From a9c2d623a66f27674ea539963a8738138ca7f6aa Mon Sep 17 00:00:00 2001 From: skotlex Date: Wed, 8 Feb 2006 16:56:53 +0000 Subject: - Cleaned up and reorganized status_change_start. Now it also receives the success % rate (0->100) - Added local function status_get_sc_tick which takes care of reducing the effect duration as need is be. - Modified status_get_sc_def to handle defense against all related statuses, now returns defense on a scale where 10000 is 100%. - Added time2 to pangvoice, it is the player effect's duration while time1 is for the mon's effect. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5227 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 4 +- src/map/battle.c | 26 +- src/map/chrif.c | 2 +- src/map/clif.c | 17 +- src/map/mob.c | 2 +- src/map/party.c | 4 +- src/map/pc.c | 26 +- src/map/script.c | 17 +- src/map/skill.c | 946 +++++++++++++++++++++++----------------------------- src/map/status.c | 795 ++++++++++++++++++++++--------------------- src/map/status.h | 2 +- 11 files changed, 891 insertions(+), 950 deletions(-) (limited to 'src/map') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index fd14b0944..31bf7b3ce 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -8336,7 +8336,7 @@ int atcommand_mute( clif_GM_silence(sd, pl_sd, 0); pl_sd->status.manner -= manner; if(pl_sd->status.manner < 0) - status_change_start(&pl_sd->bl,SC_NOCHAT,0,0,0,0,0,0); + status_change_start(&pl_sd->bl,SC_NOCHAT,100,0,0,0,0,0,0); } else { clif_displaymessage(fd, msg_table[3]); // Character not found. @@ -9431,7 +9431,7 @@ static int atcommand_mutearea_sub(struct block_list *bl,va_list ap) if (id != bl->id && !pc_isGM(pl_sd)) { pl_sd->status.manner -= time; if (pl_sd->status.manner < 0) - status_change_start(&pl_sd->bl,SC_NOCHAT,0,0,0,0,0,0); + status_change_start(&pl_sd->bl,SC_NOCHAT,100,0,0,0,0,0,0); } return 0; } diff --git a/src/map/battle.c b/src/map/battle.c index 8e32d6e7d..808f8dbb7 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -611,9 +611,10 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i if(sc->data[SC_DODGE].timer != -1 && !sc->opt1 && (flag&BF_LONG || (sc->data[SC_SPURT].timer != -1 && flag&BF_WEAPON)) && 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) - status_change_start(bl, SC_COMBO, TK_JUMPKICK, src->id, 0, 0, 2000, 0); + status_change_start(bl, SC_COMBO, 100, TK_JUMPKICK, src->id, 0, 0, 2000, 0); return 0; } @@ -2292,14 +2293,14 @@ static struct Damage battle_calc_weapon_attack( if (target->type == BL_PC) pc_breakweapon((struct map_session_data *)target); else - status_change_start(target,SC_STRIPWEAPON,1,75,0,0,breaktime,0); + status_change_start(target,SC_STRIPWEAPON,100,1,75,0,0,breaktime,0); } if(rand() % 10000 < breakrate[1] * battle_config.equip_skill_break_rate/100 || breakrate[1] >= 10000) { if (target->type == BL_PC) { struct map_session_data *tsd = (struct map_session_data *)target; pc_breakarmor(tsd); } else - status_change_start(target,SC_STRIPSHIELD,1,75,0,0,breaktime,0); + status_change_start(target,SC_STRIPSHIELD,100,1,75,0,0,breaktime,0); } } } @@ -3043,9 +3044,9 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, int duration = skill_get_time2(MO_BLADESTOP,skilllv); status_change_end(target, SC_BLADESTOP_WAIT, -1); clif_damage(src, target, tick, status_get_amotion(src), 1, 0, 1, 0, 0); //Display MISS. - status_change_start(target, SC_BLADESTOP, skilllv, 2, (int)target, (int)src, duration, 0); + status_change_start(target, SC_BLADESTOP, 100, skilllv, 2, (int)target, (int)src, duration, 0); skilllv = sd?pc_checkskill(sd, MO_BLADESTOP):1; - status_change_start(src, SC_BLADESTOP, skilllv, 1, (int)src, (int)target, duration, 0); + status_change_start(src, SC_BLADESTOP, 100, skilllv, 1, (int)src, (int)target, duration, 0); return 0; } @@ -3092,12 +3093,15 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, if (!status_isdead(target) && damage > 0) { if (sd) { int boss = status_get_mode(target)&MD_BOSS; - if ( - (sd->weapon_coma_ele[ele] > 0 && rand()%10000 < sd->weapon_coma_ele[ele]) || - (sd->weapon_coma_race[race] > 0 && rand()%10000 < sd->weapon_coma_race[race]) || - (sd->weapon_coma_race[boss?10:11] > 0 && rand()%10000 < sd->weapon_coma_race[boss?10:11]) - ) - status_change_start(target, SC_COMA, 0, 0, 0, 0, 0, 0); + int rate = 0; + if (sd->weapon_coma_ele[ele] > 0) + rate+=sd->weapon_coma_ele[ele]; + if (sd->weapon_coma_race[race] > 0) + rate += sd->weapon_coma_race[race]; + if (sd->weapon_coma_race[boss?10:11] > 0) + rate += sd->weapon_coma_race[boss?10:11]; + if (rate) + status_change_start(target, SC_COMA, rate/100, 0, 0, 0, 0, 0, 0); } } diff --git a/src/map/chrif.c b/src/map/chrif.c index 836f18acd..c1d127a44 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1227,7 +1227,7 @@ int chrif_load_scdata(int fd) ShowWarning("chrif_load_scdata: Received invalid duration (%d ms) for status change %d (character %s)\n", data.tick, sd->status.name); continue; } - status_change_start(&sd->bl, data.type, data.val1, data.val2, data.val3, data.val4, data.tick, 7); + status_change_start(&sd->bl, data.type, 100, data.val1, data.val2, data.val3, data.val4, data.tick, 15); } #endif return 0; diff --git a/src/map/clif.c b/src/map/clif.c index c40a0a037..1ba814652 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -5220,7 +5220,7 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst, WBUFB(buf,14)=fail; clif_send(buf,packet_len_table[0x11a],src,AREA); - return 0; + return fail; } /*========================================== @@ -8762,7 +8762,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color); if(battle_config.muting_players && sd->status.manner < 0 && battle_config.manner_system) - status_change_start(&sd->bl,SC_NOCHAT,0,0,0,0,0,0); + status_change_start(&sd->bl,SC_NOCHAT,100,0,0,0,0,0,0); // Lance if (script_config.event_script_type == 0) { @@ -8787,7 +8787,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if(sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele)) status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1); if(sd->special_state.infinite_endure && sd->sc_data[SC_ENDURE].timer == -1) - status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0); + status_change_start(&sd->bl,SC_ENDURE,100,10,1,0,0,0,0); // Required to eliminate glow bugs because it's executed before clif_changeoption [Lance] //New 'night' effect by dynamix [Skotlex] @@ -9097,7 +9097,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c < sd->state.snovice_flag = 3; else if (sd->state.snovice_flag == 3) { clif_skill_nodamage(&sd->bl,&sd->bl,MO_EXPLOSIONSPIRITS,-1,1); - status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS], + status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],100, 17,0,0,0,skill_get_time(MO_EXPLOSIONSPIRITS,1),0 ); //Lv17-> +50 critical (noted by Poki) [Skotlex] sd->state.snovice_flag = 0; } @@ -11002,7 +11002,7 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd) { dstsd->status.manner -= limit; if(dstsd->status.manner < 0) - status_change_start(bl,SC_NOCHAT,0,0,0,0,0,0); + status_change_start(bl,SC_NOCHAT,100,0,0,0,0,0,0); else { dstsd->status.manner = 0; @@ -11199,7 +11199,7 @@ void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd) { sd->doridori_counter = 1; if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->state.rest && (level = pc_checkskill(sd,TK_SPTIME))) - status_change_start(&sd->bl,SkillStatusChangeTable[TK_SPTIME],level,0,0,0,skill_get_time(TK_SPTIME, level),0); + status_change_start(&sd->bl,SkillStatusChangeTable[TK_SPTIME],100,level,0,0,0,skill_get_time(TK_SPTIME, level),0); return; } /*========================================== @@ -11217,8 +11217,9 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd) ShowInfo("SuperNovice explosionspirits!! %d %d %d 000\n",sd->bl.id,sd->status.class_,sd->status.base_exp); } if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_exp > 0 && nextbaseexp > 0 && (int)((double)1000*sd->status.base_exp/nextbaseexp)%100==0){ - clif_skill_nodamage(&sd->bl,&sd->bl,MO_EXPLOSIONSPIRITS,5,1); - status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],5,0,0,0,skill_get_time(MO_EXPLOSIONSPIRITS,5),0 ); + clif_skill_nodamage(&sd->bl,&sd->bl,MO_EXPLOSIONSPIRITS,5, + status_change_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],100, + 5,0,0,0,skill_get_time(MO_EXPLOSIONSPIRITS,5),0)); } } return; diff --git a/src/map/mob.c b/src/map/mob.c index c0597eff1..0ce92e813 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2327,7 +2327,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) max_hp = status_get_max_hp(&md->bl); mob_heal(md, 10*md->sc.data[SC_KAIZEL].val1*max_hp/100); clif_resurrection(&md->bl, 1); - status_change_start(&md->bl,SkillStatusChangeTable[SL_KAIZEL],10,0,0,0,skill_get_time2(SL_KAIZEL, md->sc.data[SC_KAIZEL].val1),0); + status_change_start(&md->bl,SkillStatusChangeTable[PR_KYRIE],100,10,0,0,0,skill_get_time2(SL_KAIZEL, md->sc.data[SC_KAIZEL].val1),0); status_change_end(&md->bl,SC_KAIZEL,-1); return damage; } diff --git a/src/map/party.c b/src/map/party.c index ded5626f0..d5c6b800b 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -567,7 +567,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, int skillid, in && sd->bl.m == p_sd->bl.m && pc_checkskill(p_sd,MO_TRIPLEATTACK)) { int rate = 50 +50*skilllv; //+100/150/200% success rate - status_change_start(&p_sd->bl,SC_SKILLRATE_UP,MO_TRIPLEATTACK,rate,0,0,skill_get_time(SG_FRIEND, 1),0); + status_change_start(&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK,rate,0,0,skill_get_time(SG_FRIEND, 1),0); } break; case MO_TRIPLEATTACK: //Increase Counter rate of Star Gladiators @@ -575,7 +575,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, int skillid, in && sd->bl.m == p_sd->bl.m && pc_checkskill(p_sd,TK_COUNTER)) { int rate = 50 +50*pc_checkskill(p_sd,TK_COUNTER); //+100/150/200% success rate - status_change_start(&p_sd->bl,SC_SKILLRATE_UP,TK_COUNTER,rate,0,0,skill_get_time(SG_FRIEND, 1),0); + status_change_start(&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER,rate,0,0,skill_get_time(SG_FRIEND, 1),0); } break; case AM_TWILIGHT2: //Twilight Pharmacy, requires Super Novice diff --git a/src/map/pc.c b/src/map/pc.c index 9005a7a82..e3c843055 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -306,7 +306,7 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) { sd->status.sp=sd->status.max_sp; if (sd->state.snovice_flag == 4) { sd->state.snovice_flag = 0; - status_change_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],1,0,0,0,skill_get_time(MO_STEELBODY,1),0 ); + status_change_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],100,1,0,0,0,skill_get_time(MO_STEELBODY,1),0 ); } } else { @@ -1157,14 +1157,14 @@ int pc_checkweighticon(struct map_session_data *sd) if(flag==1){ if(sd->sc.data[SC_WEIGHT50].timer==-1) - status_change_start(&sd->bl,SC_WEIGHT50,0,0,0,0,0,0); + status_change_start(&sd->bl,SC_WEIGHT50,100,0,0,0,0,0,1); }else{ if(sd->sc.data[SC_WEIGHT50].timer!=-1) status_change_end(&sd->bl,SC_WEIGHT50,-1); } if(flag==2){ if(sd->sc.data[SC_WEIGHT90].timer==-1) - status_change_start(&sd->bl,SC_WEIGHT90,0,0,0,0,0,0); + status_change_start(&sd->bl,SC_WEIGHT90,100,0,0,0,0,0,1); }else{ if(sd->sc.data[SC_WEIGHT90].timer!=-1) status_change_end(&sd->bl,SC_WEIGHT90,-1); @@ -4620,11 +4620,11 @@ int pc_checkbaselevelup(struct map_session_data *sd) //スパノビはキリエ、イムポ、マニピ、グロ、サフラLv1がかかる if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE || (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON){ - status_change_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],1,0,0,0,skill_get_time(PR_KYRIE,1),0 ); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_IMPOSITIO],1,0,0,0,skill_get_time(PR_IMPOSITIO,1),0 ); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],1,0,0,0,skill_get_time(PR_MAGNIFICAT,1),0 ); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_GLORIA],1,0,0,0,skill_get_time(PR_GLORIA,1),0 ); - status_change_start(&sd->bl,SkillStatusChangeTable[PR_SUFFRAGIUM],1,0,0,0,skill_get_time(PR_SUFFRAGIUM,1),0 ); + status_change_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],100,1,0,0,0,skill_get_time(PR_KYRIE,1),0 ); + status_change_start(&sd->bl,SkillStatusChangeTable[PR_IMPOSITIO],100,1,0,0,0,skill_get_time(PR_IMPOSITIO,1),0 ); + status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],100,1,0,0,0,skill_get_time(PR_MAGNIFICAT,1),0 ); + status_change_start(&sd->bl,SkillStatusChangeTable[PR_GLORIA],100,1,0,0,0,skill_get_time(PR_GLORIA,1),0 ); + status_change_start(&sd->bl,SkillStatusChangeTable[PR_SUFFRAGIUM],100,1,0,0,0,skill_get_time(PR_SUFFRAGIUM,1),0 ); } clif_misceffect(&sd->bl,0); @@ -5333,7 +5333,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) if(sd->status.hpstatus.max_hp>>2 && sd->sc.data[SC_AUTOBERSERK].timer != -1 && (sd->sc.data[SC_PROVOKE].timer==-1 || sd->sc.data[SC_PROVOKE].val2==0 )) // オ?トバ?サ?ク?動 - status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0); + status_change_start(&sd->bl,SC_PROVOKE,100,10,1,0,0,0,0); sd->canlog_tick = gettick(); @@ -5392,7 +5392,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) if (battle_config.pk_mode && ssd->status.manner >= 0 && battle_config.manner_system) { ssd->status.manner -= 5; if(ssd->status.manner < 0) - status_change_start(src,SC_NOCHAT,0,0,0,0,0,0); + status_change_start(src,SC_NOCHAT,100,0,0,0,0,0,0); // PK/Karma system code (not enabled yet) [celest] // originally from Kade Online, so i don't know if any of these is correct ^^; @@ -5634,9 +5634,9 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) if(battle_config.pc_invincible_time) pc_setinvincibletimer(sd, battle_config.pc_invincible_time); if (resurrect_flag) - status_change_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],10,0,0,0,skill_get_time2(SL_KAIZEL, resurrect_flag),0); + status_change_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],100,10,0,0,0,skill_get_time2(SL_KAIZEL, resurrect_flag),0); else - status_change_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],1,0,0,0,skill_get_time(MO_STEELBODY,1),0 ); + status_change_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],100,1,0,0,0,skill_get_time(MO_STEELBODY,1),0 ); return 0; } @@ -6993,7 +6993,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int pos) if(sd->special_state.infinite_endure) { if(sd->sc.data[SC_ENDURE].timer == -1) - status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0); + status_change_start(&sd->bl,SC_ENDURE,100,10,1,0,0,0,0); } else { if(sd->sc.count && sd->sc.data[SC_ENDURE].timer != -1 && sd->sc.data[SC_ENDURE].val2) diff --git a/src/map/script.c b/src/map/script.c index 0a88ddfc2..84c5c59e1 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6066,7 +6066,7 @@ int buildin_sc_start(struct script_state *st) val4 = 1; //Mark that this was a thrown sc_effect } if (bl) - status_change_start(bl,type,val1,0,0,val4,tick,0); + status_change_start(bl,type,100,val1,0,0,val4,tick,0); return 0; } @@ -6093,8 +6093,8 @@ int buildin_sc_start2(struct script_state *st) val4 = 1; } - if(bl && rand()%10000 < per) - status_change_start(bl,type,val1,0,0,val4,tick,0); + if(bl) + status_change_start(bl,type,per/100,val1,0,0,val4,tick,0); return 0; } @@ -6124,7 +6124,7 @@ int buildin_sc_start4(struct script_state *st) tick/=2; } if (bl) - status_change_start(bl,type,val1,val2,val3,val4,tick,0); + status_change_start(bl,type,100,val1,val2,val3,val4,tick,0); return 0; } @@ -6153,7 +6153,7 @@ int buildin_sc_end(struct script_state *st) int buildin_getscrate(struct script_state *st) { struct block_list *bl; - int sc_def,type,rate; + int sc_def=0,type,rate; type=conv_num(st,& (st->stack->stack_data[st->start+2])); rate=conv_num(st,& (st->stack->stack_data[st->start+3])); @@ -6162,10 +6162,11 @@ int buildin_getscrate(struct script_state *st) else bl = map_id2bl(st->rid); - sc_def = status_get_sc_def(bl,type); + if (bl) + sc_def = status_get_sc_def(bl,type); - rate = rate * sc_def / 100; - push_val(st->stack,C_INT,rate); + rate = rate*(10000-sc_def)/10000; + push_val(st->stack,C_INT,rate<0?0:rate); return 0; diff --git a/src/map/skill.c b/src/map/skill.c index 789eb1f62..b9fc9521d 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -800,8 +800,6 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int int skill,skill2; int rate; - int sc_def_mdef,sc_def_vit,sc_def_int,sc_def_luk; - nullpo_retr(0, src); nullpo_retr(0, bl); @@ -839,12 +837,6 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int if (!tsc) //skill additional effect is about adding effects to the target... //So if the target can't be inflicted with statuses, this is pointless. return 0; - //??ロの耐?ォ - sc_def_mdef = status_get_sc_def_mdef(bl); - sc_def_vit = status_get_sc_def_vit(bl); - sc_def_int = status_get_sc_def_int(bl); - sc_def_luk = status_get_sc_def_luk(bl); - switch(skillid){ case 0: // Normal attacks (no skill used) @@ -866,50 +858,43 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int } // Chance to trigger Taekwon kicks [Dralnu] if(sd->sc.count) { - if(sd->sc.data[SC_READYSTORM].timer != -1 && sd->sc.data[SC_COMBO].timer == -1 && rand()%100 < 15) { - rate = 2000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); - status_change_start(src,SC_COMBO, TK_STORMKICK,0,0,0,rate,0); - } else if(sd->sc.data[SC_READYDOWN].timer != -1 && sd->sc.data[SC_COMBO].timer == -1 && rand()%100 < 15) { - rate = 2000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); - status_change_start(src,SC_COMBO, TK_DOWNKICK,0,0,0,rate,0); - } else if(sd->sc.data[SC_READYTURN].timer != -1 && sd->sc.data[SC_COMBO].timer == -1 && rand()%100 < 15) { - rate = 2000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); - status_change_start(src,SC_COMBO, TK_TURNKICK,0,0,0,rate,0); - } else if(sd->sc.data[SC_READYCOUNTER].timer != -1 && sd->sc.data[SC_COMBO].timer == -1) //additional chance from SG_FRIEND [Komurka] + if(sd->sc.data[SC_READYSTORM].timer != -1) + status_change_start(src,SC_COMBO, TK_STORMKICK,15,0,0,0, + (2000 - 4 * status_get_agi(src) - 2 * status_get_dex(src)),0); + else if(sd->sc.data[SC_READYDOWN].timer != -1) + status_change_start(src,SC_COMBO, TK_DOWNKICK,15,0,0,0, + (2000 - 4 * status_get_agi(src) - 2 * status_get_dex(src)),0); + else if(sd->sc.data[SC_READYTURN].timer != -1 && sd->sc.data[SC_COMBO].timer == -1) + status_change_start(src,SC_COMBO, TK_TURNKICK,15,0,0,0, + (2000 - 4 * status_get_agi(src) - 2 * status_get_dex(src)),0); + else if(sd->sc.data[SC_READYCOUNTER].timer != -1 && sd->sc.data[SC_COMBO].timer == -1) //additional chance from SG_FRIEND [Komurka] { rate = 20; if (sd->sc.data[SC_SKILLRATE_UP].timer != -1 && sd->sc.data[SC_SKILLRATE_UP].val1 == TK_COUNTER) { rate += rate*sd->sc.data[SC_SKILLRATE_UP].val2/100; status_change_end(src,SC_SKILLRATE_UP,-1); } - if (rand()%100 < rate) { - rate = 2000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); - status_change_start(src,SC_COMBO, TK_COUNTER,bl->id,0,0,rate,0); - } + status_change_start(src,SC_COMBO, TK_COUNTER,rate, bl->id,0,0, + (2000 - 4 * status_get_agi(src) - 2 * status_get_dex(src)),0); } } } - if (sc && sc->count) { // Enchant Poison gives a chance to poison attacked enemies - if(sc->data[SC_ENCPOISON].timer != -1 && tsc->data[SC_POISON].timer == -1 && - rand() % 100 < sc->data[SC_ENCPOISON].val1 * sc_def_vit / 100) - status_change_start(bl,SC_POISON,sc->data[SC_ENCPOISON].val1,0,0,0,skill_get_time2(AS_ENCHANTPOISON,sc->data[SC_ENCPOISON].val1),0); + if(sc->data[SC_ENCPOISON].timer != -1) + status_change_start(bl,SC_POISON,sc->data[SC_ENCPOISON].val1, + sc->data[SC_ENCPOISON].val1,0,0,0,skill_get_time2(AS_ENCHANTPOISON,sc->data[SC_ENCPOISON].val1),0); // Enchant Deadly Poison gives a chance to deadly poison attacked enemies - if(sc->data[SC_EDP].timer != -1 && !(status_get_mode(bl)&MD_BOSS) && tsc->data[SC_DPOISON].timer == -1 && - rand() % 100 < tsc->data[SC_EDP].val2 * sc_def_vit / 100) - status_change_start(bl,SC_DPOISON,sc->data[SC_EDP].val1,0,0,0,skill_get_time2(ASC_EDP,sc->data[SC_EDP].val1),0); + if(sc->data[SC_EDP].timer != -1) + status_change_start(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),0); } if (tsc->count) { - if (tsc->data[SC_SPLASHER].timer != -1 && - tsc->data[SC_POISON].timer == -1 && - rand()%100< (2*tsc->data[SC_SPLASHER].val1+10)*sc_def_vit/100 - ) { - status_change_start(bl,SC_POISON,tsc->data[SC_SPLASHER].val1,0,0,0, + if (tsc->data[SC_SPLASHER].timer != -1) + status_change_start(bl,SC_POISON,2*tsc->data[SC_SPLASHER].val1+10, + tsc->data[SC_SPLASHER].val1,0,0,0, skill_get_time2(tsc->data[SC_SPLASHER].val2,tsc->data[SC_SPLASHER].val1),0); - } - if(tsc->data[SC_KAAHI].timer != -1) { if (dstsd && dstsd->status.sp < 5*tsc->data[SC_KAAHI].val1) ; //Not enough SP to cast @@ -925,8 +910,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int case SM_BASH: /* バッシュ?i急??U??j */ if( sd && skilllv > 5 && pc_checkskill(sd,SM_FATALBLOW)>0 ){ - if( rand()%100 < (5*(skilllv-5)+(int)sd->status.base_level/10)*sc_def_vit/100 ) //TODO: How much % per base level it actually is? - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(SM_FATALBLOW,skilllv),0); + //TODO: How much % per base level it actually is? + status_change_start(bl,SC_STAN,(5*(skilllv-5)+(int)sd->status.base_level/10), + skilllv,0,0,0,skill_get_time2(SM_FATALBLOW,skilllv),0); } break; @@ -935,67 +921,65 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int skilllv = pc_checkskill(sd, TF_POISON); case TF_POISON: /* インベナム */ case AS_SPLASHER: /* ベナムスプラッシャ? */ - if(rand()%100< (2*skilllv+10)*sc_def_vit/100 ) - status_change_start(bl,SC_POISON,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - else{ - if(sd && skillid==TF_POISON) - clif_skill_fail(sd,skillid,0,0); - } + if(!status_change_start(bl,SC_POISON,(2*skilllv+10), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0) + && sd && skillid==TF_POISON + ) + clif_skill_fail(sd,skillid,0,0); break; case AS_SONICBLOW: /* ソニックブ?? */ - if( rand()%100 < (2*skilllv+10)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STAN,(2*skilllv+10), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case AS_GRIMTOOTH: { int type = sd?SC_SLOWDOWN:SC_STOP; if (tsc->data[type].timer == -1) - status_change_start(bl,type,0,0,0,0,skill_get_time2(skillid, skilllv),0); + status_change_start(bl,type,100,skilllv,0,0,0,skill_get_time2(skillid, skilllv),0); break; } case MG_FROSTDIVER: /* フ?ストダイバ? */ case WZ_FROSTNOVA: /* フ?ストノヴァ */ { - rate = (skilllv*3+35)*sc_def_mdef/100-(status_get_int(bl)+status_get_luk(bl))/15; + rate = (skilllv*3+35)-(status_get_int(bl)+status_get_luk(bl))/15; if (rate <= 5) rate = 5; - if(tsc->data[SC_FREEZE].timer == -1 && rand()%100 < rate) - status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv)*(1-sc_def_mdef/100),0); + status_change_start(bl,SC_FREEZE,rate, + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); } break; case WZ_STORMGUST: /* スト?ムガスト */ tsc->data[SC_FREEZE].val3++; if(tsc->data[SC_FREEZE].val3 >= 3) - status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_FREEZE,100, + skilllv,0,0,0,skill_get_time2(skillid,skilllv),8); break; case WZ_METEOR: - if(rand()%100 < 3*skilllv*sc_def_vit/100) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STAN,3*skilllv,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case WZ_VERMILION: - if(rand()%100 < 4*skilllv*sc_def_int/100) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_BLIND,4*skilllv, + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case HT_FREEZINGTRAP: /* フリ?ジングトラップ */ - if(rand()%100 < (3*skilllv+35)*sc_def_mdef/100) - status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_FREEZE,(3*skilllv+35), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case HT_FLASHER: /* Flasher */ - if (!(status_get_mode(bl) & (MD_BOSS|MD_PLANT)) && - rand()%100 < (10*skilllv+30)*sc_def_int/100) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_BLIND,(10*skilllv+30), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case HT_LANDMINE: /* ランドマイン */ - if( rand()%100 < (5*skilllv+30)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STAN,(5*skilllv+30), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case HT_SHOCKWAVE: //it can't affect mobs, because they have no SP... @@ -1006,46 +990,40 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; case HT_SANDMAN: /* サンドマン */ - if( rand()%100 < (10*skilllv+40)*sc_def_int/100 ) - status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_SLEEP,(10*skilllv+40), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case TF_SPRINKLESAND: /* ?サまき */ - if( rand()%100 < 20*sc_def_int/100 ) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_BLIND,20,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case TF_THROWSTONE: /* ?ホ投げ */ - if( rand()%100 < 3*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if( rand()%100 < 3*sc_def_int/100 ) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STAN,3,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_BLIND,3,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case NPC_DARKCROSS: case CR_HOLYCROSS: /* ホ?リ?クロス */ - if( rand()%100 < 3*skilllv*sc_def_int/100 ) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_BLIND,3*skilllv, + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case CR_GRANDCROSS: /* グランドク?ス */ case NPC_GRANDDARKNESS: /*闇グランドク?ス*/ { int race = status_get_race(bl); - if( (battle_check_undead(race,status_get_elem_type(bl)) || race == 6) && rand()%100 < 100000*sc_def_int/100) //??ァ付?だが完全耐?ォには無? - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6) + status_change_start(bl,SC_BLIND,100,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); } break; case AM_ACIDTERROR: - if (rand()%100 < (skilllv*3)*sc_def_vit/100 ) { - status_change_start(bl,SC_BLEEDING,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - } + status_change_start(bl,SC_BLEEDING,(skilllv*3),skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); if (dstsd && rand()%100 < skill_get_time(skillid,skilllv) * battle_config.equip_skill_break_rate / 100) { //fixed if(pc_breakarmor(dstsd)) clif_emotion(bl,23); } - break; case AM_DEMONSTRATION: @@ -1054,8 +1032,8 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; case CR_SHIELDCHARGE: /* シ?ルドチャ?ジ */ - if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STAN,(15+skilllv*5), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case PA_PRESSURE: /* プレッシャ? */ @@ -1066,25 +1044,24 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; case RG_RAID: /* サプライズアタック */ - if( rand()%100 < (10+3*skilllv)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if( rand()%100 < (10+3*skilllv)*sc_def_int/100 ) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STAN,(10+3*skilllv), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_BLIND,(10+3*skilllv), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case BA_FROSTJOKE: - if(rand()%100 < (15+5*skilllv)*sc_def_mdef/100) - status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_FREEZE,(15+5*skilllv), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case DC_SCREAM: - if( rand()%100 < (25+5*skilllv)*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STAN,(25+5*skilllv), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case BD_LULLABY: /* 子守唄 */ - if( rand()%100 < 15*sc_def_int/100 ) - status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_SLEEP,15,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case DC_UGLYDANCE: @@ -1099,8 +1076,8 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int } break; case SL_STUN: - if (status_get_size(bl)==1 && rand()%100 < (30+10*skilllv)*sc_def_vit/100 ) //Only stuns mid-sized mobs. - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); + if (status_get_size(bl)==1) //Only stuns mid-sized mobs. + status_change_start(bl,SC_STAN,(30+10*skilllv),skilllv,0,0,0,skill_get_time(skillid,skilllv),0); break; case SG_SUN_WARM: case SG_MOON_WARM: @@ -1114,27 +1091,19 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; /* MOBの追加?果付きスキル */ - case NPC_PETRIFYATTACK: - if(rand()%100 < sc_def_mdef) - status_change_start(bl,scl[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + case NPC_CURSEATTACK: + case NPC_SLEEPATTACK: + case NPC_BLINDATTACK: + status_change_start(bl,scl[skillid-NPC_POISON],100,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case NPC_POISON: case NPC_SILENCEATTACK: case NPC_STUNATTACK: - if(rand()%100 < sc_def_vit && src->type!=BL_PET) - status_change_start(bl,scl[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); if(src->type==BL_PET) - status_change_start(bl,scl[skillid-NPC_POISON],skilllv,0,0,0,skilllv*1000,0); - break; - case NPC_CURSEATTACK: - if(rand()%100 < sc_def_luk) - status_change_start(bl,scl[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - break; - case NPC_SLEEPATTACK: - case NPC_BLINDATTACK: - if(rand()%100 < sc_def_int) - status_change_start(bl,scl[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,scl[skillid-NPC_POISON],100,skilllv,0,0,0,skilllv*1000,0); + else + status_change_start(bl,scl[skillid-NPC_POISON],100,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case NPC_MENTALBREAKER: @@ -1146,46 +1115,35 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; case CH_TIGERFIST: - if (rand()%100 < (10 + skilllv*10)*sc_def_vit/100) { - int sec = skill_get_time2 (skillid,skilllv) - status_get_agi(bl)/10; - if (dstsd) { - dstsd->canmove_tick += sec; - dstsd->canact_tick += sec; - } else if (dstmd) - dstmd->canmove_tick += sec; - } + status_change_start(bl,SC_STOP,(10+skilllv*10),0,0,0,0,skill_get_time2(skillid,skilllv),0); break; case LK_SPIRALPIERCE: - if (rand()%100 < (15 + skilllv*5)*sc_def_vit/100) - status_change_start(bl,SC_STOP,0,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STOP,(15+skilllv*5),0,0,0,0,skill_get_time2(skillid,skilllv),0); break; case ST_REJECTSWORD: /* フリ?ジングトラップ */ - if( rand()%100 < (skilllv*15) ) - status_change_start(bl,SC_AUTOCOUNTER,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_AUTOCOUNTER,(skilllv*15),skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case PF_FOGWALL: /* ホ?リ?ク?ス */ - if (src != bl) { - if (tsc->data[SC_DELUGE].timer == -1 && !(status_get_mode(bl)&MD_BOSS)) - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - } + if (src != bl && tsc->data[SC_DELUGE].timer == -1) + status_change_start(bl,SC_BLIND,100,skilllv,0,0,0,skill_get_time2(skillid,skilllv),8); break; case LK_HEADCRUSH: /* ヘッドクラッシュ */ { //??が良く分からないので適?に int race = status_get_race(bl); - if (!(battle_check_undead(race, status_get_elem_type(bl)) || race == 6) && rand()%100 < 50 * sc_def_vit/100) - status_change_start(bl, SC_BLEEDING, skilllv, 0, 0, 0, skill_get_time2(skillid,skilllv), 0); + if (!(battle_check_undead(race, status_get_elem_type(bl)) || race == 6)) + status_change_start(bl, SC_BLEEDING,50, skilllv, 0, 0, 0, skill_get_time2(skillid,skilllv), 0); } break; case LK_JOINTBEAT: /* ジョイントビ?ト */ //??が良く分からないので適?に - if( rand()%100 < (5*skilllv+5)*sc_def_vit/100 ) - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SkillStatusChangeTable[skillid],(5*skilllv+5), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case PF_SPIDERWEB: /* スパイダ?ウェッブ */ @@ -1194,34 +1152,31 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int if(map[src->m].flag.pvp) //PvPでは?S束時間半減?H sec = sec/2; battle_stopwalking(bl,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,sec,0); + status_change_start(bl,SkillStatusChangeTable[skillid],100,skilllv,0,0,0,sec,0); } break; case ASC_METEORASSAULT: /* ?テオアサルト */ //Any enemies hit by this skill will receive Stun, Darkness, or external bleeding status ailment with a 5%+5*SkillLV% chance. - if( rand()%100 < (5+skilllv*5) ) //5%+5*SkillLV% - switch(rand()%3) { - case 0: - status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,1),0); - break; - case 1: - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,2),0); - break; - default: - status_change_start(bl,SC_BLEEDING,skilllv,0,0,0,skill_get_time2(skillid,3),0); - } + switch(rand()%3) { + case 0: + status_change_start(bl,SC_BLIND,(5+skilllv*5),skilllv,0,0,0,skill_get_time2(skillid,1),0); + break; + case 1: + status_change_start(bl,SC_STAN,(5+skilllv*5),skilllv,0,0,0,skill_get_time2(skillid,2),0); + break; + default: + status_change_start(bl,SC_BLEEDING,(5+skilllv*5),skilllv,0,0,0,skill_get_time2(skillid,3),0); + } break; case HW_NAPALMVULCAN: /* ナパ?ムバルカン */ // skilllv*5%の確率で呪い - if (rand()%10000 < 5*skilllv*sc_def_luk) - status_change_start(bl,SC_CURSE,7,0,0,0,skill_get_time2(NPC_CURSEATTACK,7),0); + status_change_start(bl,SC_CURSE,5*skilllv,7,0,0,0,skill_get_time2(NPC_CURSEATTACK,7),0); break; case WS_CARTTERMINATION: // Cart termination - if (rand() % 10000 < 5 * skilllv * sc_def_vit) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + status_change_start(bl,SC_STAN,5*skilllv,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case CR_ACIDDEMONSTRATION: @@ -1235,9 +1190,8 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; case TK_DOWNKICK: - if(rand()%100 < 100*sc_def_vit/100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - break; + status_change_start(bl,SC_STAN,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); + break; case TK_JUMPKICK: //Cancel out Soul Linker status of the target. [Skotlex] @@ -1262,8 +1216,8 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int } break; case MO_BALKYOUNG: //Note: attack_type is passed as BF_WEAPON for the actual target, BF_MISC for the splash-affected mobs. - if(attack_type == BF_MISC && rand()%100 < 70*sc_def_vit/100 ) //70% base stun chance... - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + if(attack_type == BF_MISC) //70% base stun chance... + status_change_start(bl,SC_STAN,70,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; } @@ -1274,40 +1228,14 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int if(sd && skillid != MC_CARTREVOLUTION && skillid != AM_DEMONSTRATION && skillid != CR_REFLECTSHIELD && attack_type&BF_WEAPON){ /* カ?ドによる追加?果 */ int i, type; - int sc_def_card=100; - for(i=SC_COMMON_MIN;i<=SC_COMMON_MAX;i++){ type=i-SC_COMMON_MIN; - if (!sd->addeff[type] && (!sd->state.arrow_atk || !sd->arrow_addeff[type])) + rate = sd->addeff[type]+(sd->state.arrow_atk?sd->arrow_addeff[type]:0); + if (!rate) continue; //Code Speedup. - //??ロに?態異? - switch (i) { - case SC_STONE: - case SC_FREEZE: - sc_def_card=sc_def_mdef; - break; - case SC_STAN: - case SC_POISON: - case SC_DPOISON: - case SC_SILENCE: - case SC_BLEEDING: - sc_def_card=sc_def_vit; - break; - case SC_SLEEP: - case SC_CONFUSION: - case SC_BLIND: - sc_def_card=sc_def_int; - break; - case SC_CURSE: - sc_def_card=sc_def_luk; - } + rate/=100; //For some reason user effects are on a 10000 scale... - if (rand()%10000 < (sd->addeff[type]+(sd->state.arrow_atk?sd->arrow_addeff[type]:0))*sc_def_card/100 ) - { //Inflicted status effect. - if(battle_config.battle_log) - ShowInfo("PC %d skill_additional_effect: caused status effect (pos %d): %d\n",sd->bl.id,i,sd->addeff[type]); - status_change_start(bl,i,7,0,0,0,skill_get_time2(sc2l[type],7),0); - } + status_change_start(bl,i,rate,7,0,0,0,skill_get_time2(sc2l[type],7),0); } } @@ -1375,15 +1303,13 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * NPC_SILENCEATTACK,AS_SONICBLOW,NPC_BLINDATTACK, LK_HEADCRUSH }; - + int rate; struct map_session_data *sd=NULL; struct map_session_data *dstsd=NULL; struct mob_data *md=NULL; struct mob_data *dstmd=NULL; // struct pet_data *pd=NULL; Pet's can't be inflicted! - int sc_def_mdef,sc_def_vit,sc_def_int,sc_def_luk; - nullpo_retr(0, src); nullpo_retr(0, bl); @@ -1420,63 +1346,29 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * return 0; } - //自分の耐?ォ - sc_def_mdef = status_get_sc_def_mdef(src); - sc_def_vit = status_get_sc_def_vit(src); - sc_def_int = status_get_sc_def_int(src); - sc_def_luk = status_get_sc_def_luk(src); - switch(skillid){ case 0: //Normal Attack - Nothing here yet. break; case MO_EXTREMITYFIST: /* 阿?C羅覇凰? */ //阿?C羅を使うと5分間自然回復しないようになる - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 ); + status_change_start(src,SkillStatusChangeTable[skillid],100,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 ); break; } if((sd||dstsd) && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* カ?ドによる追加?果 */ int i, type; - int sc_def_card=100; for(i=SC_COMMON_MIN;i<=SC_COMMON_MAX;i++){ type=i-SC_COMMON_MIN; - - switch (i) { - case SC_STONE: - case SC_FREEZE: - sc_def_card=sc_def_mdef; - break; - case SC_STAN: - case SC_POISON: - case SC_DPOISON: - case SC_SILENCE: - case SC_BLEEDING: - sc_def_card=sc_def_vit; - break; - case SC_SLEEP: - case SC_CONFUSION: - case SC_BLIND: - sc_def_card=sc_def_int; - break; - case SC_CURSE: - sc_def_card=sc_def_luk; - } + + + rate = sd?(sd->addeff2[type]+(sd->state.arrow_atk?sd->arrow_addeff2[type]:0)):0; + if (rate) //Self infliced status from attacking. + status_change_start(src,i,rate/100,7,0,0,0,skill_get_time2(sc2[type],7),0); - if (sd && (rand()%10000 < (sd->addeff2[type]+(sd->state.arrow_atk?sd->arrow_addeff2[type]:0))*sc_def_card/100 )) - { //Self infliced status from attacking. - if(battle_config.battle_log) - ShowInfo("PC %d skill_addeff: self inflicted effect (pos %d): %d\n",src->id,i,sd->addeff2[type]); - status_change_start(src,i,7,0,0,0,skill_get_time2(sc2[type],7),0); - } - if (dstsd && - (dstsd->addeff3_type[type] == 1 || ((sd && sd->state.arrow_atk) || (status_get_range(src)>2))) && - (rand()%10000 < dstsd->addeff3[type]*sc_def_card/100) - ) { //Counter status effect. - if(battle_config.battle_log) - ShowInfo("PC %d skill_addeff: counter inflicted effect (pos %d): %d\n",src->id,i,dstsd->addeff3[type]); - status_change_start(src,i,7,0,0,0,skill_get_time2(sc2[type],7),0); - } + rate = dstsd?dstsd->addeff3[type]:0; + if (rate && (dstsd->addeff3_type[type] == 1 || ((sd && sd->state.arrow_atk) || (status_get_range(src)>2)))) + status_change_start(src,i,rate/100,7,0,0,0,skill_get_time2(sc2[type],7),0); } } @@ -1777,7 +1669,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds if (damage < status_get_hp(bl) && pc_checkskill(sd, MO_CHAINCOMBO) > 0) delay += 300 * battle_config.combo_delay_rate / 100; - status_change_start(src,SC_COMBO,MO_TRIPLEATTACK,skilllv,0,0,delay,0); + status_change_start(src,SC_COMBO,100,MO_TRIPLEATTACK,skilllv,0,0,delay,0); sd->attackabletime = sd->canmove_tick = tick + delay; clif_combo_delay(src, delay); @@ -1791,7 +1683,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds if(damage < status_get_hp(bl) && (pc_checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0)) delay += 300 * battle_config.combo_delay_rate /100; - status_change_start(src,SC_COMBO,MO_CHAINCOMBO,skilllv,0,0,delay,0); + status_change_start(src,SC_COMBO,100,MO_CHAINCOMBO,skilllv,0,0,delay,0); sd->attackabletime = sd->canmove_tick = tick + delay; clif_combo_delay(src,delay); break; @@ -1806,7 +1698,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds (pc_checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1) )) delay += 300 * battle_config.combo_delay_rate /100; - status_change_start(src,SC_COMBO,MO_COMBOFINISH,skilllv,0,0,delay,0); + status_change_start(src,SC_COMBO,100,MO_COMBOFINISH,skilllv,0,0,delay,0); sd->attackabletime = sd->canmove_tick = tick + delay; clif_combo_delay(src,delay); break; @@ -1820,7 +1712,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds (pc_checkskill(sd, CH_CHAINCRUSH) > 0) )) delay += 300 * battle_config.combo_delay_rate /100; - status_change_start(src,SC_COMBO,CH_TIGERFIST,skilllv,0,0,delay,0); + status_change_start(src,SC_COMBO,100,CH_TIGERFIST,skilllv,0,0,delay,0); sd->attackabletime = sd->canmove_tick = tick + delay; clif_combo_delay(src,delay); break; @@ -1830,7 +1722,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src); if(damage < status_get_hp(bl)) delay += 300 * battle_config.combo_delay_rate /100; - status_change_start(src,SC_COMBO,CH_CHAINCRUSH,skilllv,0,0,delay,0); + status_change_start(src,SC_COMBO,100,CH_CHAINCRUSH,skilllv,0,0,delay,0); sd->attackabletime = sd->canmove_tick = tick + delay; clif_combo_delay(src,delay); break; @@ -1840,7 +1732,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds int race = status_get_race(bl); if((race == 2 || race == 4) && damage < status_get_hp(bl) && pc_checkskill(sd, HT_POWER)) { //TODO: This code was taken from Triple Blows,is this even how it should be? [Skotlex] - status_change_start(src,SC_COMBO,HT_POWER,bl->id,0,0,2000,0); + status_change_start(src,SC_COMBO,100,HT_POWER,bl->id,0,0,2000,0); clif_combo_delay(src,2000); } break; @@ -1860,7 +1752,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds case SL_STIN: case SL_STUN: if (skilllv >= 7 && sd->sc.data[SC_COMBO].timer == -1) - status_change_start(src,SC_COMBO,SL_SMA,skilllv,0,0,skill_get_time2(skillid, skilllv),0); + status_change_start(src,SC_COMBO,100,SL_SMA,skilllv,0,0,skill_get_time2(skillid, skilllv),0); break; } //Switch End } @@ -2221,7 +2113,7 @@ int skill_guildaura_sub (struct block_list *bl,va_list ap) } return 0; } - status_change_start(&sd->bl, SC_GUILDAURA, 1, id, 0, *flag, 0, 0); + status_change_start(&sd->bl, SC_GUILDAURA,100, 1, id, 0, *flag, 0, 0); } return 0; @@ -2920,7 +2812,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s src->m,src->x-2,src->y-2,src->x+2,src->y+2,BL_CHAR, src,skillid,skilllv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id); - status_change_start (src,SC_WATK_ELEMENT,3,20,0,0,10000,0); //Initiate 10% of your damage becomes fire element. + status_change_start (src,SC_WATK_ELEMENT,100,3,20,0,0,10000,0); //Initiate 10% of your damage becomes fire element. clif_skill_nodamage (src,src,skillid,skilllv,1); } break; @@ -3027,7 +2919,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s int range = skilllv/2; //Rain doesn't affect WATERBALL (Rain has been removed at kRO) [Lupus] //int cnt = (!map[src->m].flag.rain) ? skill_count_water(src,range) - 1 : skill_get_num(skillid,skilllv) - 1; - int cnt = (src->type==BL_PC)?skill_count_water(src,range) - 1:(range*range-1); + int cnt = (src->type==BL_PC)?skill_count_water(src,range):range*range; + cnt--; if (cnt > 0) skill_addtimerskill(src,tick+150,bl->id,0,0, skillid,skilllv,cnt,flag); @@ -3125,7 +3018,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s case SL_STUN: case SL_SMA: if (sd && bl->type != BL_MOB) { - status_change_start(src,SC_STAN,skilllv,0,0,0,3000,0); + status_change_start(src,SC_STAN,100,skilllv,0,0,0,3000,8); clif_skill_fail(sd,skillid,0,0); break; } @@ -3279,7 +3172,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in struct mob_data *md = NULL; struct mob_data *dstmd = NULL; int i; - int sc_def_vit, sc_def_mdef; // int sc_dex, sc_luk; if(skillid < 0) @@ -3302,9 +3194,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in nullpo_retr (1, md = (struct mob_data *)src); } - sc_def_vit = status_get_sc_def_vit (bl); - sc_def_mdef = status_get_sc_def_mdef (bl); - if (bl->type == BL_PC){ nullpo_retr (1, dstsd = (struct map_session_data *)bl); } else if (bl->type == BL_MOB){ @@ -3411,7 +3300,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_updatestatus(sd,SP_BASEEXP); clif_updatestatus(sd,SP_JOBEXP); } - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,0,0); //SC_COMA :P + status_change_start(src,SkillStatusChangeTable[skillid],100,skilllv,0,0,0,0,0); //SC_COMA :P break; } else if (dstsd && pc_isdead(dstsd) && flag&1) { //Revive skill_area_temp[0]++; //Count it in, then fall-through to the Resurrection code. @@ -3472,22 +3361,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(src,bl,skillid,skilllv,0); break; } - if (rand() % 100 < (40 + skilllv * 2 + (status_get_lv(src) + status_get_int(src))/5 +(sc_def_mdef-100))) { //0 defense is sc_def_mdef == 100! [Skotlex] - i = skill_get_time(skillid,skilllv); - if (bl->type == BL_PC) i/=2; //Halved duration for Players - status_change_start (bl, SkillStatusChangeTable[skillid], skilllv, 0, 0, 0, i, 0); - clif_skill_nodamage (src, bl, skillid, skilllv, 1); - } + clif_skill_nodamage (src, bl, skillid, skilllv, + status_change_start (bl, SkillStatusChangeTable[skillid], + (40 + skilllv * 2 + (status_get_lv(src) + status_get_int(src))/5), + skilllv, 0, 0, 0, skill_get_time(skillid,skilllv),0)); break; case AL_CRUCIS: if (flag & 1) { int race = status_get_race (bl), ele = status_get_elem_type (bl); if (battle_check_target (src, bl, BCT_ENEMY) && (race == 6 || battle_check_undead (race, ele))) { - int slv = status_get_lv (src),tlv = status_get_lv (bl); - int rate = 23 + skilllv*4 + slv - tlv; - if (rand()%100 < rate) - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,0,0); + status_change_start(bl,SkillStatusChangeTable[skillid], + 23+skilllv*4 +status_get_lv(src) -status_get_lv(bl), + skilllv,0,0,0,0,0); } } else { map_foreachinarea(skill_area_sub, @@ -3506,11 +3392,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if (tsc && tsc->count && tsc->data[SC_SILENCE].timer != -1) { status_change_end(bl,SC_SILENCE, -1); clif_skill_nodamage (src, bl, skillid, skilllv, 1); - } else if (rand() % 100 < sc_def_vit) { - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - clif_skill_nodamage (src, bl, skillid, skilllv, 1); - } else - clif_skill_nodamage (src, bl, skillid, skilllv, 0); + } else + clif_skill_nodamage (src, bl, skillid, skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid], + 100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case SA_ABRACADABRA: @@ -3560,8 +3445,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(src,bl,skillid,skilllv,0); break; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 )); break; case SA_FULLRECOVERY: clif_skill_nodamage(src,bl,skillid,skilllv,1); @@ -3609,8 +3495,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in battle_damage(NULL,bl,status_get_max_hp(bl),1); break; case SA_REVERSEORCISH: - status_change_start(bl, SkillStatusChangeTable[skillid], skilllv,0,0,0,skill_get_time(skillid, skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl, SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid, skilllv),0)); break; case SA_FORTUNE: clif_skill_nodamage(src,bl,skillid,skilllv,1); @@ -3638,8 +3525,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if (status_isimmune(bl)) clif_skill_nodamage(src,bl,skillid,skilllv,0); else { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); } break; @@ -3654,8 +3542,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in return 1; } } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid], + 100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); } break; @@ -3667,8 +3556,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if(sc && tsc){ if (sc->data[sc1].timer == -1 && tsc->data[sc2].timer == -1) { - status_change_start (src,sc1,skilllv,0,bl->id,0,skill_get_time(skillid,skilllv),0); - status_change_start (bl,sc2,skilllv,0,src->id,0,skill_get_time(skillid,skilllv),0); + status_change_start (src,sc1,100,skilllv,0,bl->id,0,skill_get_time(skillid,skilllv),0); + status_change_start (bl,sc2,100,skilllv,0,src->id,0,skill_get_time(skillid,skilllv),0); clif_marionette(src, bl); } else if (sc->data[sc1].timer != -1 && tsc->data[sc2].timer != -1 && @@ -3691,8 +3580,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if (status_isimmune(bl)) clif_skill_nodamage(src,bl,skillid,skilllv,0); else { - status_change_start (bl,SkillStatusChangeTable[skillid],skilllv,src->id,0,0,skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start (bl,SkillStatusChangeTable[skillid],100, + skilllv,src->id,0,0,skill_get_time(skillid,skilllv),0)); } break; case SA_FLAMELAUNCHER: // added failure chance and chance to break weapon if turned on [Valaris] @@ -3728,19 +3618,17 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } pc_delitem(sd, i, skill_db[skillid].amount[0], 0); } - - if(skilllv < 4 && rand()%100 > (60+skilllv*10) ) { // 100% success rate at lv4 & 5, but lasts longer at lv5 + // 100% success rate at lv4 & 5, but lasts longer at lv5 + i = skilllv <4?(60+skilllv*10):100; + i = status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0); + if(!i) { if (sd) clif_skill_fail(sd,skillid,0,0); - clif_skill_nodamage(src,bl,skillid,skilllv,0); if(dstsd && battle_config.equip_self_break_rate) { if(sd && sd != dstsd) clif_displaymessage(sd->fd,"You broke target's weapon"); pc_breakweapon(dstsd); } - break; - } else { - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } + clif_skill_nodamage(src,bl,skillid,skilllv,i); break; case PR_ASPERSIO: /* アスペルシオ */ @@ -3748,8 +3636,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(src,bl,skillid,skilllv,0); break; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case TK_SEVENWIND: @@ -3778,8 +3667,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in sci=SC_ASPERSIO; break; } - status_change_start(bl,sci,skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,sci,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); } break; @@ -3788,8 +3677,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(bl,bl,skillid,skilllv,0); break; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(bl,bl,skillid,skilllv,1); + clif_skill_nodamage(bl,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case LK_BERSERK: /* バ?サ?ク */ @@ -3831,15 +3721,17 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case SG_SUN_COMFORT: case SG_MOON_COMFORT: case SG_STAR_COMFORT: - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case SG_SUN_WARM: case SG_MOON_WARM: case SG_STAR_WARM: - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,skillid,skill_get_range(skillid,skilllv),skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,skillid,skill_get_range(skillid,skilllv),skill_get_time(skillid,skilllv),0)); break; case CG_MOONLIT: /* 月明りの泉に落ちる花びら */ @@ -3853,7 +3745,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case HP_ASSUMPTIO: if (flag&1) - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); + status_change_start(bl,SkillStatusChangeTable[skillid],100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); else { map_foreachinarea(skill_area_sub, @@ -3865,8 +3757,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in break; case SM_ENDURE: /* インデュア */ - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); if (sd) pc_blockskill_start (sd, skillid, 10000); break; @@ -3885,8 +3778,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in break; } } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case LK_TENSIONRELAX: /* テンションリラックス */ @@ -3894,8 +3788,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in pc_setsit(sd); clif_sitting(sd); } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case MC_CHANGECART: @@ -3926,8 +3821,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case AC_CONCENTRATION: /* ?W中力向? */ { int range = 1; - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); map_foreachinarea( status_change_timer_sub, src->m, src->x-range, src->y-range, src->x+range,src->y+range,BL_CHAR, src,status_get_sc(src),SkillStatusChangeTable[skillid],tick); @@ -3940,18 +3836,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in map_freeblock_unlock(); return 1; } - - if (rand()%100 > 50 + 3*skilllv + status_get_lv(src) - status_get_lv(bl)) //TODO: How much does base level affects? Dummy value of 1% per level difference used. [Skotlex] + //TODO: How much does base level affects? Dummy value of 1% per level difference used. [Skotlex] + clif_skill_nodamage(src,bl,skillid,skilllv, + (i=status_change_start(bl,SkillStatusChangeTable[skillid], + 50 +3*skilllv +status_get_lv(src) -status_get_lv(bl), + skilllv,0,0,0,skill_get_time(skillid,skilllv),0))); + if (!i) { - clif_skill_nodamage(src,bl,skillid,skilllv,0); if (sd) clif_skill_fail(sd,skillid,0,0); map_freeblock_unlock(); return 0; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - if(dstmd && dstmd->skilltimer!=-1 && dstmd->state.skillcastcancel) // 詠?・妨害 skill_castcancel(bl,0); if(dstsd && dstsd->skilltimer!=-1 && (!dstsd->special_state.no_castcancel || map_flag_gvg(bl->m)) @@ -3996,8 +3892,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in return 1; } sd->devotion[i] = bl->id; - status_change_start(bl,SkillStatusChangeTable[skillid],src->id,i,skill_get_range2(src,skillid,skilllv),skill_get_time2(skillid, skilllv),1000,0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + src->id,i,skill_get_range2(src,skillid,skilllv),skill_get_time2(skillid, skilllv),1000,0)); clif_devotion(sd); } else @@ -4035,8 +3932,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in break; case MO_BLADESTOP: // 白?n取り - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(src,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case MO_ABSORBSPIRITS: // ?奪 @@ -4092,9 +3990,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(src,bl,skillid,skilllv,0); break; } - if(rand() % 100 < (20 + 10 * skilllv) * sc_def_vit / 100 ) - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SC_STAN,(20 + 10 * skilllv), + skilllv,0,0,0,skill_get_time2(skillid,skilllv),0)); break; case RG_RAID: /* サプライズアタック */ clif_skill_nodamage(src,bl,skillid,skilllv,1); @@ -4174,8 +4072,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(bl,bl,skillid,skilllv,0); break; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(bl,bl,skillid,skilllv,1); + clif_skill_nodamage(bl,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); } else if (sd) { /* パ?ティ全?への?? */ party_foreachsamemap (skill_area_sub, @@ -4191,8 +4090,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case BS_OVERTHRUST: /* オ?バ?トラスト */ if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) { /* 個別の?? */ - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,(src == bl)? 1:0,0,0,skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(bl,bl,skillid,skilllv,1); + clif_skill_nodamage(bl,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,(src == bl)? 1:0,0,0,skill_get_time(skillid,skilllv),0)); } else if (sd) { /* パ?ティ全?への?? */ party_foreachsamemap(skill_area_sub, @@ -4217,10 +4117,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in { int sci = SkillStatusChangeTable[skillid]; if (tsc && tsc->data[sci].timer != -1) - status_change_end(bl, sci, -1); + i = status_change_end(bl, sci, -1); else - status_change_start(bl,sci,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + i = status_change_start(bl,sci,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); + clif_skill_nodamage(src,bl,skillid,skilllv,i); } break; case SL_KAITE: @@ -4234,22 +4134,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in dstsd->char_id == sd->status.partner_id || dstsd->char_id == sd->status.child )) { - status_change_start(src,SC_STAN,skilllv,0,0,0,3000,0); + status_change_start(src,SC_STAN,100,skilllv,0,0,0,3000,8); clif_skill_fail(sd,skillid,0,0); break; } } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid, skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid, skilllv),0)); break; case SM_AUTOBERSERK: // Celest { int sc = SkillStatusChangeTable[skillid]; if (tsc && tsc->data[sc].timer != -1) - status_change_end(bl, sc, -1); + i = status_change_end(bl, sc, -1); else - status_change_start(bl,sc,skilllv,0,0,0,0,0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + i = status_change_start(bl,sc,100,skilllv,0,0,0,0,0); + clif_skill_nodamage(src,bl,skillid,skilllv,i); } break; case TF_HIDING: /* ハイディング */ @@ -4257,20 +4158,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in { int sc = SkillStatusChangeTable[skillid]; if (tsc && tsc->data[sc].timer != -1) - status_change_end(bl, sc, -1); + i = status_change_end(bl, sc, -1); else - status_change_start(bl,sc,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,-1,1); // Don't display the skill name as it is a hiding skill + i = status_change_start(bl,sc,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); + clif_skill_nodamage(src,bl,skillid,-1,i); // Don't display the skill name as it is a hiding skill } break; case TK_RUN: { int sci = SkillStatusChangeTable[skillid]; if (tsc && tsc->data[sci].timer != -1) - status_change_end(bl, sci, -1); + i = status_change_end(bl, sci, -1); else - status_change_start(bl,sci,skilllv,status_get_dir(bl),0,0,0,0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + i = status_change_start(bl,sci,100,skilllv,status_get_dir(bl),0,0,0,0); + clif_skill_nodamage(src,bl,skillid,skilllv,i); } break; case AS_CLOAKING: /* ク??キング */ @@ -4278,18 +4179,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in int sci=SkillStatusChangeTable[skillid]; if(tsc && tsc->data[sci].timer!=-1 ) /* 解?怩キる */ - status_change_end(bl, sci, -1); + i = status_change_end(bl, sci, -1); else - /* 付加する */ - { //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 && skilllv < 3 && skill_check_cloaking(bl)) - if (sd && pc_checkskill(sd, AS_CLOAKING)< 3 && skill_check_cloaking(bl)) - clif_skill_fail(sd,skillid,0,0); - else - status_change_start(bl,sci,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - } - clif_skill_nodamage(src,bl,skillid,-1,1); + i = status_change_start(bl,sci,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0); + clif_skill_nodamage(src,bl,skillid,-1,i); + if (!i && sd) + clif_skill_fail(sd,skillid,0,0); } break; @@ -4324,25 +4219,27 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in skill_clear_unitgroup(src); sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0); if(skillid == CG_HERMODE) - status_change_start(src,SC_DANCING,skillid,0,0,sg->group_id,skill_get_time(skillid,skilllv),0); + i = status_change_start(src,SC_DANCING,100, + skillid,0,0,sg->group_id,skill_get_time(skillid,skilllv),0); else - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,BCT_SELF,sg->group_id, - skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + i = status_change_start(src,SkillStatusChangeTable[skillid],100, + skilllv,0,BCT_SELF,sg->group_id, + skill_get_time(skillid,skilllv),0); + clif_skill_nodamage(src,bl,skillid,skilllv,i); } break; case PA_GOSPEL: /* ゴスペル */ if (!tsc) break; if (tsc->data[SC_GOSPEL].timer != -1 && tsc->data[SC_GOSPEL].val4 == BCT_SELF) { - status_change_end(bl,SC_GOSPEL,-1); + i = status_change_end(bl,SC_GOSPEL,-1); } else { struct skill_unit_group *sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0); if (tsc->data[SC_GOSPEL].timer != -1) status_change_end(bl,SC_GOSPEL,-1); //Was under someone else's Gospel. [Skotlex] - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,(int)sg,BCT_SELF,skill_get_time(skillid,skilllv),0); + i = status_change_start(bl,SkillStatusChangeTable[skillid],100,skilllv,0,(int)sg,BCT_SELF,skill_get_time(skillid,skilllv),0); } - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv,i); break; case BD_ADAPTATION: /* アドリブ */ @@ -4367,44 +4264,29 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case BA_PANGVOICE://パンボイス - if(status_get_mode(bl)&MD_BOSS){ - clif_skill_nodamage(src,bl,skillid,skilllv,0); - if(sd) - clif_skill_fail(sd,skillid,0,0); - break; - } - if(rand()%100 < 50){ - status_change_start(bl,SC_CONFUSION,7,0,0,0,10000+7000,0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - }else{ - clif_skill_nodamage(src,bl,skillid,skilllv,0); - if(sd) - clif_skill_fail(sd,skillid,0,0); - } + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SC_CONFUSION,50, + 7,0,0,0,skill_get_time(skillid,skilllv),0)); break; case DC_WINKCHARM://魅惑のウィンク - if(dstsd){ - if(rand()%100 < 30) { - status_change_start(bl,SC_CONFUSION,7,0,0,0,10000+7000,0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - }else{ - clif_skill_nodamage(src,bl,skillid,skilllv,0); - if(sd) - clif_skill_fail(sd,skillid,0,0); - } - }else if(dstmd) - { - int race = status_get_race(bl); - if(!(status_get_mode(bl)&MD_BOSS) && status_get_lv(src)>status_get_lv(bl) && (race == 6 || race == 7 || race == 8) && rand()%100 < 70) { - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,10000,0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + if(dstsd){ + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SC_CONFUSION,30, + 7,0,0,0,skill_get_time2(skillid,skilllv),0)); + }else if(dstmd) + { + int race = status_get_race(bl); + if(status_get_lv(src)>status_get_lv(bl) && (race == 6 || race == 7 || race == 8)) { + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],70, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); } else{ - clif_skill_nodamage(src,bl,skillid,skilllv,0); - if(sd) - clif_skill_fail(sd,skillid,0,0); - } + clif_skill_nodamage(src,bl,skillid,skilllv,0); + if(sd) + clif_skill_fail(sd,skillid,0,0); } + } break; case TF_STEAL: // スティ?ル @@ -4429,41 +4311,33 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case MG_STONECURSE: /* スト?ンカ?ス */ { - // Level 6-10 doesn't consume a red gem if it fails [celest] - int i, gem_flag = 1, fail_flag = 0; if (status_get_mode(bl)&MD_BOSS) { if (sd) clif_skill_fail(sd,skillid,0,0); break; } if(status_isimmune(bl) || !tsc) break; + if (dstmd) + mob_target(dstmd,src,skill_get_range2(src,skillid,skilllv)); + if (tsc->data[SC_STONE].timer != -1) { status_change_end(bl,SC_STONE,-1); - if (sd) { - fail_flag = 1; - clif_skill_fail(sd,skillid,0,0); - } + if (sd) clif_skill_fail(sd,skillid,0,0); + break; } - else if( rand()%100 < (skilllv*4+20)*status_get_sc_def(bl, SC_STONE)/100 - && !battle_check_undead(status_get_race(bl),status_get_elem_type(bl))) - { - status_change_start(bl,SC_STONE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); - } else if(sd) { - if (skilllv > 5) gem_flag = 0; + if (status_change_start(bl,SC_STONE, + (skilllv*4+20),skilllv,0,0,0,skill_get_time2(skillid,skilllv),0)) + clif_skill_nodamage(src,bl,skillid,skilllv,1); + else if(sd) { clif_skill_fail(sd,skillid,0,0); - fail_flag = 1; + // Level 6-10 doesn't consume a red gem if it fails [celest] + if (skilllv > 5) break; } - if (dstmd) - mob_target(dstmd,src,skill_get_range2(src,skillid,skilllv)); - if (sd && gem_flag) { - if ((i=pc_search_inventory(sd, skill_db[skillid].itemid[0])) < 0 ) { - // if (!fail_flag) clif_skill_fail(sd,skillid,0,0); This is actually a bug! Altough the gem is checked in skill_check_condition... - break; - } + if (sd) { if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_WIZARD) break; //Do not delete the gemstone. - pc_delitem(sd, i, skill_db[skillid].amount[0], 0); + if ((i=pc_search_inventory(sd, skill_db[skillid].itemid[0])) >= 0 ) + pc_delitem(sd, i, skill_db[skillid].amount[0], 0); } } break; @@ -4482,7 +4356,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in status_change_end(bl, SC_BLIND , -1 ); status_change_end(bl, SC_CONFUSION, -1 ); if( battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) ){//アンデッドなら暗闇?果 - status_change_start(bl, SC_CONFUSION,1,0,0,0,6000,0); + status_change_start(bl, SC_CONFUSION,100,1,0,0,0,6000,0); } clif_skill_nodamage(src,bl,skillid,skilllv,1); break; @@ -4503,10 +4377,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in status_change_end(bl, SC_STONE , -1 ); status_change_end(bl, SC_SLEEP , -1 ); status_change_end(bl, SC_STAN , -1 ); + //Is this equation really right? It looks so... special. if( battle_check_undead(status_get_race(bl),status_get_elem_type(bl)) ){//アンデッドなら暗闇?果 - if(rand()%100 < (100-(status_get_int(bl)/2+status_get_vit(bl)/3+status_get_luk(bl)/10))) { - status_change_start(bl, SC_BLIND,1,0,0,0, - 1000 * 30 * (100-(status_get_int(bl)+status_get_vit(bl))/2)/100,0); + status_change_start(bl, SC_BLIND, + (100-(status_get_int(bl)/2+status_get_vit(bl)/3+status_get_luk(bl)/10)), + 1,0,0,0, + 1000 * 30 * (100-(status_get_int(bl)+status_get_vit(bl))/2)/100,10); } } clif_skill_nodamage(src,bl,skillid,skilllv,1); @@ -4672,7 +4548,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in for (i=0;i<4;i++) { if (sclist[i] != 0) // Start the SC only if an equipment was stripped from this location - status_change_start(bl,sclist[i],skilllv,0,0,0,skill_get_time(skillid,skilllv)+strip_fix/2,0); + status_change_start(bl,sclist[i],100,skilllv,0,0,0,skill_get_time(skillid,skilllv)+strip_fix/2,0); } break; @@ -4761,8 +4637,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in int scid = SC_STRIPWEAPON + (skillid - AM_CP_WEAPON); if(tsc && tsc->data[scid].timer != -1) status_change_end(bl, scid, -1 ); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); } break; case AM_TWILIGHT1: @@ -4801,8 +4678,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in { int i; clif_skill_nodamage(src,bl,skillid,skilllv,1); - if (rand()%100 >= (50+10*skilllv)*sc_def_mdef/100 // Fixed & changed to use a proportionnal reduction (no info, but seems far more logical) [DracoRPG] - || tsc == NULL || (tsc->data[SC_SPIRIT].timer != -1 && tsc->data[SC_SPIRIT].val2 == SL_ROGUE)) //Rogue's spirit defends againt dispel. + i = status_get_sc_def_mdef(bl); + if (i >= 10000 || + tsc == NULL || (tsc->data[SC_SPIRIT].timer != -1 && 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()%10000 >= (10000-i)*(50+10*skilllv)/100) { if (sd) clif_skill_fail(sd,skillid,0,0); @@ -4952,7 +4832,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case SA_MAGICROD: if (status_isimmune(bl)) break; - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); + status_change_start(bl,SkillStatusChangeTable[skillid],100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); break; case SA_AUTOSPELL: /* オ?トスペル */ clif_skill_nodamage(src,bl,skillid,skilllv,1); @@ -4986,7 +4866,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in maxlv = 3; } if(spellid > 0) - status_change_start(src,SC_AUTOSPELL,skilllv,spellid,maxlv,0, + status_change_start(src,SC_AUTOSPELL,100,skilllv,spellid,maxlv,0, skill_get_time(SA_AUTOSPELL,skilllv),0); } break; @@ -5041,16 +4921,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(src,bl,skillid,skilllv,0); break; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case NPC_KEEPING: case NPC_BARRIER: { int skill_time = skill_get_time(skillid,skilllv); - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_time,0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_time,0)); if (md) mob_changestate(md,MS_DELAY,skill_time); else if (sd) @@ -5066,14 +4948,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case NPC_DARKBLESSING: { - int sc_def = 100 - status_get_mdef(bl); - if(status_isimmune(bl) || status_get_elem_type(bl) == 7 || status_get_race(bl) == 6) { + if(status_isimmune(bl)) { clif_skill_nodamage(src,bl,skillid,skilllv,0); break; } - if(rand()%100 < sc_def*(50+skilllv*5)/100) - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid], + (50+skilllv*5),skilllv,0,0,0,skill_get_time2(skillid,skilllv),0)); } break; @@ -5085,9 +4966,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } pc_heal(dstsd,0,-100); } - if(rand()%100 < (skilllv*5)*sc_def_vit/100) - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid], + (skilllv*5),skilllv,0,0,0,skill_get_time2(skillid,skilllv),0)); break; case NPC_SUICIDE: /* 自決 */ @@ -5118,8 +4999,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in int i = SC_ASPDPOTION0 + skilllv - 1; if (i > SC_ASPDPOTION3) i = SC_ASPDPOTION3; - status_change_start(bl,i,skilllv,0,0,0,skilllv * 60000,0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,i,100,skilllv,0,0,0,skilllv * 60000,0)); } break; @@ -5227,15 +5108,17 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case NPC_POWERUP: // +25% attack per skill level? It's a guess... [Skotlex] - status_change_start(bl,SC_INCATKRATE,25*skilllv,0,0,0,skilllv * 60000,0); + status_change_start(bl,SC_INCATKRATE,100,25*skilllv,0,0,0,skilllv * 60000,0); // another random guess xP - clif_skill_nodamage(src,bl,skillid,skilllv,1); - status_change_start(bl,SC_INCALLSTATUS,skilllv * 5,0,0,0,skilllv * 60000,0); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SC_INCALLSTATUS,100, + skilllv * 5,0,0,0,skilllv * 60000,0)); break; case NPC_AGIUP: - status_change_start(bl,SC_INCAGI,skilllv * 10,0,0,0,skilllv * 60000,0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SC_INCAGI,100, + skilllv * 10,0,0,0,skilllv * 60000,0)); break; case NPC_SIEGEMODE: @@ -5289,9 +5172,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in map_freeblock_unlock(); return 0; } - status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if (f_sd) status_change_start(&f_sd->bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - if (m_sd) status_change_start(&m_sd->bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); + status_change_start(bl,SC_STAN,100,skilllv,0,0,0,skill_get_time2(skillid,skilllv),8); + if (f_sd) status_change_start(&f_sd->bl,SkillStatusChangeTable[skillid],100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); + if (m_sd) status_change_start(&m_sd->bl,SkillStatusChangeTable[skillid],100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); } break; @@ -5438,8 +5321,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in map_freeblock_unlock(); return 1; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,src->id,skill_get_time(skillid,skilllv),1000,0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,skillid,src->id,skill_get_time(skillid,skilllv),1000,0)); break; case PF_MINDBREAKER: /* プ?ボック */ @@ -5450,17 +5334,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in map_freeblock_unlock(); return 1; } - - if (rand()%100 > 55 + skilllv*5) - { //Has a 55% + skilllv*5% success chance. - clif_skill_nodamage(src,bl,skillid,skilllv,0); - if (sd) - clif_skill_fail(sd,skillid,0,0); + + //Has a 55% + skilllv*5% success chance. + if (!clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],55 +5*skilllv, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0))) + { + if (sd) clif_skill_fail(sd,skillid,0,0); map_freeblock_unlock(); return 0; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); if(dstmd && dstmd->skilltimer!=-1 && dstmd->state.skillcastcancel) // 詠?・妨害 skill_castcancel(bl,0); @@ -5545,7 +5428,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in for (i=0; i<4; i++) { if(tsc->data[SC_STRIPWEAPON + i].timer != -1) status_change_end(bl, SC_STRIPWEAPON + i, -1 ); - status_change_start(bl,SC_CP_WEAPON + i,skilllv,0,0,0,skilltime,0 ); + status_change_start(bl,SC_CP_WEAPON + i,100,skilllv,0,0,0,skilltime,0 ); } clif_skill_nodamage(src,bl,skillid,skilllv,1); } @@ -5557,13 +5440,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case PF_DOUBLECASTING: - if (rand() % 100 > 30 + skilllv * 10) { + if (!clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid], + 30+ 10*skilllv,skilllv,0,0,0,skill_get_time(skillid,skilllv),0))) if (sd) clif_skill_fail(sd,skillid,0,0); - map_freeblock_unlock(); - return 0; - } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); - clif_skill_nodamage(src,bl,skillid,skilllv,1); break; case CG_LONGINGFREEDOM: @@ -5571,8 +5451,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if (tsc && tsc->data[SC_LONGING].timer == -1 && tsc->data[SC_DANCING].timer != -1 && tsc->data[SC_DANCING].val4 && tsc->data[SC_DANCING].val1 != CG_MOONLIT) //Can't use Longing for Freedom while under Moonlight Petals. [Skotlex] { - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); } } break; @@ -5594,7 +5475,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if (dstsd) pc_heal(dstsd,0,-dstsd->status.sp); break; case 1: // matk halved - status_change_start(bl,SC_INCMATKRATE,-50,0,0,0,30000,0); + status_change_start(bl,SC_INCMATKRATE,100,-50,0,0,0,30000,0); break; case 2: // all buffs removed status_change_clear_buffs(bl); @@ -5608,7 +5489,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } break; case 4: // atk halved - status_change_start(bl,SC_INCATKRATE,-50,0,0,0,30000,0); + status_change_start(bl,SC_INCATKRATE,100,-50,0,0,0,30000,0); break; case 5: // 2000HP heal, random teleported battle_heal(src, src, 2000, 0, 0); @@ -5624,37 +5505,37 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case 7: // stop freeze or stoned { int sc[] = { SC_STOP, SC_FREEZE, SC_STONE }; - status_change_start(bl,sc[rand()%3],skilllv,0,0,0,30000,0); + status_change_start(bl,sc[rand()%3],100,skilllv,0,0,0,30000,0); } break; case 8: // curse coma and poison - status_change_start(bl,SC_COMA,skilllv,0,0,0,30000,0); - status_change_start(bl,SC_CURSE,skilllv,0,0,0,30000,0); - status_change_start(bl,SC_POISON,skilllv,0,0,0,30000,0); + status_change_start(bl,SC_COMA,100,skilllv,0,0,0,30000,0); + status_change_start(bl,SC_CURSE,100,skilllv,0,0,0,30000,0); + status_change_start(bl,SC_POISON,100,skilllv,0,0,0,30000,0); break; case 9: // chaos - status_change_start(bl,SC_CONFUSION,skilllv,0,0,0,30000,0); + status_change_start(bl,SC_CONFUSION,100,skilllv,0,0,0,30000,0); break; case 10: // 6666 damage, atk matk halved, cursed battle_damage(src, bl, 6666, 0); clif_damage(src,bl,tick,0,0,6666,0,0,0); - status_change_start(bl,SC_INCATKRATE,-50,0,0,0,30000,0); - status_change_start(bl,SC_INCMATKRATE,-50,0,0,0,30000,0); - status_change_start(bl,SC_CURSE,skilllv,0,0,0,30000,0); + status_change_start(bl,SC_INCATKRATE,100,-50,0,0,0,30000,0); + status_change_start(bl,SC_INCMATKRATE,100,-50,0,0,0,30000,0); + status_change_start(bl,SC_CURSE,skilllv,100,0,0,0,30000,0); break; case 11: // 4444 damage battle_damage(src, bl, 4444, 0); clif_damage(src,bl,tick,0,0,4444,0,0,0); break; case 12: // stun - status_change_start(bl,SC_STAN,skilllv,0,0,0,5000,0); + status_change_start(bl,SC_STAN,100,skilllv,0,0,0,5000,0); break; case 13: // atk,matk,hit,flee,def reduced - status_change_start(bl,SC_INCATKRATE,-20,0,0,0,30000,0); - status_change_start(bl,SC_INCMATKRATE,-20,0,0,0,30000,0); - status_change_start(bl,SC_INCHITRATE,-20,0,0,0,30000,0); - status_change_start(bl,SC_INCFLEERATE,-20,0,0,0,30000,0); - status_change_start(bl,SC_INCDEFRATE,-20,0,0,0,30000,0); + status_change_start(bl,SC_INCATKRATE,100,-20,0,0,0,30000,0); + status_change_start(bl,SC_INCMATKRATE,100,-20,0,0,0,30000,0); + status_change_start(bl,SC_INCHITRATE,100,-20,0,0,0,30000,0); + status_change_start(bl,SC_INCFLEERATE,100,-20,0,0,0,30000,0); + status_change_start(bl,SC_INCDEFRATE,100,-20,0,0,0,30000,0); break; default: break; @@ -5683,23 +5564,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_fail(sd,skillid,0,0); break; } - status_change_start(bl,SC_SPIRIT,skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0); - status_change_start(src,SC_COMBO,SL_SMA,skilllv,0,0,skill_get_time2(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SC_SPIRIT,100, + skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0)); + status_change_start(src,SC_COMBO,100,SL_SMA,skilllv,0,0,skill_get_time2(skillid,skilllv),0); break; case SL_HIGH: if (sd && !(dstsd && (dstsd->class_&JOBL_UPPER) && !(dstsd->class_&JOBL_2) && dstsd->status.base_level < 70)) { clif_skill_fail(sd,skillid,0,0); break; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0 ); - status_change_start(src,SC_COMBO,SL_SMA,skilllv,0,0,skill_get_time2(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0)); + status_change_start(src,SC_COMBO,100,SL_SMA,skilllv,0,0,skill_get_time2(skillid,skilllv),0); break; case SL_SKA: // [marquis007] if (sd && bl->type != BL_MOB) { - status_change_start(src,SC_STAN,skilllv,0,0,0,3000,0); + status_change_start(src,SC_STAN,100,skilllv,0,0,0,3000,8); clif_skill_fail(sd,skillid,0,0); break; } @@ -5707,29 +5590,32 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_fail(sd,skillid,0,0); else { - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); } break; case SL_SWOO: if (sd && bl->type != BL_MOB) { - status_change_start(src,SC_STAN,skilllv,0,0,0,3000,0); + status_change_start(src,SC_STAN,100,skilllv,0,0,0,3000,8); clif_skill_fail(sd,skillid,0,0); break; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,status_get_mode(bl)&MD_BOSS?skill_get_time(skillid,skilllv)/5:skill_get_time(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); break; case SL_SKE: if (sd && bl->type != BL_MOB) { - status_change_start(src,SC_STAN,skilllv,0,0,0,3000,0); + status_change_start(src,SC_STAN,100,skilllv,0,0,0,3000,8); clif_skill_fail(sd,skillid,0,0); break; } - status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0 ); - status_change_start(src,SC_COMBO,SL_SMA,skilllv,0,0,skill_get_time2(skillid,skilllv),0); - clif_skill_nodamage(src,bl,skillid,skilllv,1); + clif_skill_nodamage(src,bl,skillid,skilllv, + status_change_start(bl,SkillStatusChangeTable[skillid],100, + skilllv,skillid,0,0,skill_get_time(skillid,skilllv),0)); + status_change_start(src,SC_COMBO,100,SL_SMA,skilllv,0,0,skill_get_time2(skillid,skilllv),0); break; // New guild skills [Celest] @@ -5744,7 +5630,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } if(flag&1) { if (dstsd && dstsd->status.guild_id == sd->status.guild_id) { - status_change_start(&dstsd->bl,SC_BATTLEORDERS,skilllv,0,0,0,0,0 ); + status_change_start(&dstsd->bl,SC_BATTLEORDERS,100,skilllv,0,0,0,0,0 ); } } else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) && @@ -5769,7 +5655,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } if(flag&1) { if (dstsd && dstsd->status.guild_id == sd->status.guild_id) { - status_change_start(&dstsd->bl,SC_REGENERATION,skilllv,0,0,0,0,0 ); + status_change_start(&dstsd->bl,SC_REGENERATION,100,skilllv,0,0,0,0,0 ); } } else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) && @@ -6427,8 +6313,8 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil struct skill_unit_group *sg; clif_skill_poseffect(src,skillid,skilllv,x,y,tick); sg = skill_unitsetting(src,skillid,skilllv,x,y,0); - status_change_start(src,SkillStatusChangeTable[skillid],skilllv,0,BCT_SELF,(int)sg, - skill_get_time(skillid,skilllv),0); + status_change_start(src,SkillStatusChangeTable[skillid],100, + skilllv,0,BCT_SELF,(int)sg,skill_get_time(skillid,skilllv),0); } break; @@ -6925,12 +6811,12 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int 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) - status_change_start(bl,type,sg->skill_lv,sg->group_id,(int)sg,0,sg->limit,0); + status_change_start(bl,type,100,sg->skill_lv,sg->group_id,(int)sg,0,sg->limit,0); break; case UNT_PNEUMA: if (sc && sc->data[type].timer == -1) - status_change_start(bl,type,sg->skill_lv,sg->group_id,0,0,sg->limit,0); + status_change_start(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit,0); break; case UNT_WARP_WAITING: @@ -6953,14 +6839,14 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int if(status_isimmune(bl)) break; if(sc && sc->data[type].timer==-1) - status_change_start(bl,type,sg->skill_lv,sg->group_id,0,0,sg->limit,0); + status_change_start(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit,0); break; case UNT_VOLCANO: case UNT_DELUGE: case UNT_VIOLENTGALE: if(sc && sc->data[type].timer==-1) - status_change_start(bl,type,sg->skill_lv,sg->group_id,0,0, + status_change_start(bl,type,100,sg->skill_lv,sg->group_id,0,0, skill_get_time2(sg->skill_id,sg->skill_lv),0); break; @@ -6975,7 +6861,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int if (sg->src_id==bl->id && (!sc || sc->data[SC_SPIRIT].timer == -1 || sc->data[SC_SPIRIT].val2 != SL_BARDDANCER)) return sg->skill_id; if (sc && sc->data[type].timer==-1) - status_change_start(bl,type,sg->skill_lv,sg->val1,sg->val2,0,sg->limit,0); + status_change_start(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit,0); break; case UNT_WHISTLE: @@ -6990,7 +6876,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int if (sg->src_id==bl->id && (!sc || sc->data[SC_SPIRIT].timer == -1 || sc->data[SC_SPIRIT].val2 != SL_BARDDANCER)) return 0; if (sc && sc->data[type].timer==-1) - status_change_start(bl,type,sg->skill_lv,sg->val1,sg->val2,0,sg->limit,0); + status_change_start(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit,0); break; case UNT_BASILICA: @@ -7001,15 +6887,15 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int case UNT_FOGWALL: if (sc && sc->data[type].timer==-1) { - status_change_start (bl, type, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit, 0); + status_change_start (bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit, 0); if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0) skill_additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, tick); } break; case UNT_GRAVITATION: - if (sc && sc->data[type].timer==-1 && !status_get_mode(bl)&MD_BOSS) - status_change_start(bl,type,sg->skill_lv,5*sg->skill_lv,BCT_ENEMY,sg->group_id,sg->limit,0); + if (sc && sc->data[type].timer==-1) + status_change_start(bl,type,100,sg->skill_lv,5*sg->skill_lv,BCT_ENEMY,sg->group_id,sg->limit,0); break; case UNT_ICEWALL: //Destroy the cell. [Skotlex] @@ -7021,7 +6907,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int if (sg->src_id != bl->id && sc && sc->data[type].timer==-1 && battle_check_target(ss,bl,BCT_PARTY)>0) //Start Gospel Effect to prevent item usage affects party only. [Skotlex] - status_change_start(bl,type,sg->skill_lv,0,0,BCT_ALL,sg->limit,0); + status_change_start(bl,type,100,sg->skill_lv,0,0,BCT_ALL,sg->limit,0); break; } @@ -7160,20 +7046,16 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign case UNT_ANKLESNARE: if(sg->val2==0 && tsc && tsc->data[SC_ANKLE].timer==-1){ - int sec = skill_get_time2(sg->skill_id,sg->skill_lv) - status_get_agi(bl)*100; - if(status_get_mode(bl)&MD_BOSS) // Lasts 5 times less on bosses - sec = sec/5; - if (sec < 3000+30*sg->skill_lv) // Minimum trap time of 3+0.03*skilllv seconds [celest] - sec = 3000+30*sg->skill_lv; + int sec = skill_get_time2(sg->skill_id,sg->skill_lv); battle_stopwalking(bl,1); - status_change_start(bl,SC_ANKLE,sg->skill_lv,0,0,0,sec,0); + status_change_start(bl,SC_ANKLE,100,sg->skill_lv,0,0,0,sec,0); map_moveblock(bl, src->bl.x, src->bl.y, tick); clif_fixpos(bl); //clif_01ac(&src->bl); //Removed? Check the openkore description of this packet: [Skotlex] // 01AC: long ID // Indicates that an object is trapped, but ID is not a // valid monster or player ID. - sg->limit=DIFF_TICK(tick,sg->tick) + sec; + sg->limit=DIFF_TICK(tick,sg->tick)+sec; sg->val2=bl->id; sg->interval = -1; src->range = 0; @@ -7182,7 +7064,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign case UNT_VENOMDUST: if(tsc && tsc->data[type].timer==-1 ) - status_change_start(bl,type,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),0); + status_change_start(bl,type,100,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),8); break; case UNT_LANDMINE: @@ -7276,38 +7158,38 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign status_change_clear_debuffs (bl); break; case 2: // Level 10 Blessing - status_change_start(bl,SC_BLESSING,10,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_BLESSING,100,10,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 3: // Level 10 Increase AGI - status_change_start(bl,SC_INCREASEAGI,10,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCREASEAGI,100,10,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 4: // Enchant weapon with Holy element - status_change_start(bl,SC_ASPERSIO,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_ASPERSIO,100,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 5: // Enchant armor with Holy element - status_change_start(bl,SC_BENEDICTIO,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_BENEDICTIO,100,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 6: // MaxHP +100% - status_change_start(bl,SC_INCMHPRATE,100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCMHPRATE,100,100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 7: // MaxSP +100% - status_change_start(bl,SC_INCMSPRATE,100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCMSPRATE,100,100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 8: // All stats +20 - status_change_start(bl,SC_INCALLSTATUS,20,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCALLSTATUS,100,20,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 9: // DEF +25% - status_change_start(bl,SC_INCDEFRATE,25,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCDEFRATE,100,25,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 10: // ATK +100% - status_change_start(bl,SC_INCATKRATE,100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCATKRATE,100,100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 11: // HIT/Flee +50 - status_change_start(bl,SC_INCHIT,50,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); - status_change_start(bl,SC_INCFLEE,50,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCHIT,100,50,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCFLEE,100,50,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 12: // Immunity to all status - status_change_start(bl,SC_SCRESIST,100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_SCRESIST,100,100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; } } @@ -7323,28 +7205,28 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign break; } case 1: // Curse - status_change_start(bl,SC_CURSE,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_CURSE,100,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 2: // Blind - status_change_start(bl,SC_BLIND,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_BLIND,100,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 3: // Poison - status_change_start(bl,SC_POISON,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_POISON,100,1,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 4: // Level 10 Provoke - status_change_start(bl,SC_PROVOKE,10,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_PROVOKE,100,10,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 5: // DEF -100% - status_change_start(bl,SC_INCDEFRATE,-100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCDEFRATE,100,-100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 6: // ATK -100% - status_change_start(bl,SC_INCATKRATE,-100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCATKRATE,100,-100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 7: // Flee -100% - status_change_start(bl,SC_INCFLEERATE,-100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_INCFLEERATE,100,-100,0,0,0,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; case 8: // Speed/ASPD -25% - status_change_start(bl,SC_GOSPEL,1,0,0,BCT_ENEMY,skill_get_time2(sg->skill_id, sg->skill_lv),0); + status_change_start(bl,SC_GOSPEL,100,1,0,0,BCT_ENEMY,skill_get_time2(sg->skill_id, sg->skill_lv),0); break; } } @@ -7674,12 +7556,12 @@ static void skill_moonlit(struct block_list* src, struct block_list* partner, in ,partner->x+range,partner->y+range ,BL_CHAR,src,partner,blowcount); - status_change_start(src,SC_DANCING,CG_MOONLIT,0,0,partner?partner->id:BCT_SELF,time+1000,0); - status_change_start(src,SkillStatusChangeTable[CG_MOONLIT],skilllv,0,0,0,time,0); + status_change_start(src,SC_DANCING,100,CG_MOONLIT,0,0,partner?partner->id:BCT_SELF,time+1000,0); + status_change_start(src,SkillStatusChangeTable[CG_MOONLIT],100,skilllv,0,0,0,time,0); if (partner) { - status_change_start(partner,SC_DANCING,CG_MOONLIT,0,0,src->id,time+1000,0); - status_change_start(partner,SkillStatusChangeTable[CG_MOONLIT],skilllv,0,0,0,time,0); + status_change_start(partner,SC_DANCING,100,CG_MOONLIT,0,0,src->id,time+1000,0); + status_change_start(partner,SkillStatusChangeTable[CG_MOONLIT],100,skilllv,0,0,0,time,0); } } @@ -7793,7 +7675,7 @@ static int skill_check_pc_partner(struct map_session_data *sd, int skill_id, int if (c > 0 && (tsd = map_id2sd(p_sd[0])) != NULL) { sd->sc.data[SC_DANCING].val4= tsd->bl.id; - status_change_start(&tsd->bl,SC_DANCING,skill_id,sd->sc.data[SC_DANCING].val2,0,sd->bl.id,skill_get_time(skill_id,*skill_lv)+1000,0); + status_change_start(&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING].val2,0,sd->bl.id,skill_get_time(skill_id,*skill_lv)+1000,0); clif_skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1); tsd->skillid_dance = tsd->skillid = skill_id; tsd->skilllv_dance = tsd->skilllv = *skill_lv; @@ -9475,7 +9357,7 @@ int skill_autospell(struct map_session_data *sd,int skillid) if(maxlv > (lv=pc_checkskill(sd,skillid))) maxlv = lv; - status_change_start(&sd->bl,SC_AUTOSPELL,skilllv,skillid,maxlv,0, // val1:スキルID val2:使用?ナ大Lv + status_change_start(&sd->bl,SC_AUTOSPELL,100,skilllv,skillid,maxlv,0, // val1:スキルID val2:使用?ナ大Lv skill_get_time(SA_AUTOSPELL,skilllv),0);// にしてみたけどbscriptが?曹ォ易い????H return 0; } @@ -10275,7 +10157,7 @@ struct skill_unit_group *skill_initunitgroup(struct block_list *src, sd->skillid_dance=skillid; sd->skilllv_dance=skilllv; } - status_change_start(src,SC_DANCING,skillid,(int)group,0,(i&UF_ENSEMBLE?BCT_SELF:0),skill_get_time(skillid,skilllv)+1000,0); + status_change_start(src,SC_DANCING,100,skillid,(int)group,0,(i&UF_ENSEMBLE?BCT_SELF:0),skill_get_time(skillid,skilllv)+1000,0); //?奏スキルは相方をダンス?態にする if (sd && i&UF_ENSEMBLE && battle_config.player_skill_partner_check) { diff --git a/src/map/status.c b/src/map/status.c index 4ae4b81f7..72a5e036a 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1919,7 +1919,7 @@ int status_calc_pc(struct map_session_data* sd,int first) /* I don't think there's a need for this here. It should be handled in pc_damage and pc_heal. [Skotlex] if(sd->status.hpstatus.max_hp>>2 && sd->sc.data[SC_AUTOBERSERK].timer!=-1 && (sd->sc.data[SC_PROVOKE].timer==-1 || sd->sc.data[SC_PROVOKE].val2==0) && !pc_isdead(sd)) - status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0); + status_change_start(&sd->bl,SC_PROVOKE,100,10,1,0,0,0,0); */ calculating = 0; return 0; @@ -3520,8 +3520,6 @@ int status_isdead(struct block_list *bl) int status_isimmune(struct block_list *bl) { struct map_session_data *sd = (struct map_session_data *)bl; - - nullpo_retr(0, bl); if (bl->type == BL_PC) { if (sd->special_state.no_magic_damage) return 1; @@ -3541,90 +3539,164 @@ struct status_change *status_get_sc(struct block_list *bl) return NULL; } +//Returns defense against the specified status change. +//Return range is 0 (no resist) to 10000 (inmunity) int status_get_sc_def(struct block_list *bl, int type) { int sc_def; struct status_change* sc; + struct map_session_data *sd; nullpo_retr(0, bl); switch (type) { case SP_MDEF1: // mdef - sc_def = 100 - (3 + status_get_mdef(bl) + status_get_luk(bl)/3); + case SC_STONE: + case SC_FREEZE: + case SC_DECREASEAGI: + sc_def = 3 + status_get_mdef(bl) + status_get_luk(bl)/3; break; case SP_MDEF2: // int - sc_def = 100 - (3 + status_get_int(bl) + status_get_luk(bl)/3); + case SC_SLEEP: + case SC_CONFUSION: + sc_def = 3 + status_get_int(bl) + status_get_luk(bl)/3; break; case SP_DEF1: // def - sc_def = 100 - (3 + status_get_def(bl) + status_get_luk(bl)/3); + sc_def = 3 + status_get_def(bl) + status_get_luk(bl)/3; break; case SP_DEF2: // vit - sc_def = 100 - (3 + status_get_vit(bl) + status_get_luk(bl)/3); - break; - case SP_LUK: // luck - sc_def = 100 - (3 + status_get_luk(bl)); - break; - - case SC_STONE: - case SC_FREEZE: - sc_def = 100 - (3 + status_get_mdef(bl) + status_get_luk(bl)/3); - break; case SC_STAN: case SC_POISON: case SC_SILENCE: - sc_def = 100 - (3 + status_get_vit(bl) + status_get_luk(bl)/3); - break; - case SC_SLEEP: - case SC_CONFUSION: - sc_def = 100 - (3 + status_get_int(bl) + status_get_luk(bl)/3); + case SC_STOP: + sc_def = 3 + status_get_vit(bl) + status_get_luk(bl)/3; + break; + case SP_LUK: // luck + sc_def = 3 + status_get_luk(bl); break; case SC_BLIND: - sc_def = 100 - (3 + status_get_int(bl) + status_get_vit(bl)/3); + sc_def = 3 + status_get_int(bl) + status_get_vit(bl)/3; break; case SC_CURSE: - sc_def = 100 - (3 + status_get_luk(bl) + status_get_vit(bl)/3); - break; - - default: - sc_def = 100; + sc_def = 3 + status_get_luk(bl) + status_get_vit(bl)/3; break; + case SC_COMA: + sc_def = 3 + status_get_mdef(bl); + default: + return 0; //Effect that cannot be reduced? Likely a buff. } 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 + sc_def += sc->data[SC_SCRESIST].val1; //Status resist else if (sc->data[SC_SIEGFRIED].timer != -1) - sc_def -= sc->data[SC_SIEGFRIED].val2; //Status resistance. + sc_def += sc->data[SC_SIEGFRIED].val2; //Status resistance. } + sc_def*=100; //Send it on the interval 0->10000 if(bl->type == BL_MOB) { struct mob_data *md = (struct mob_data *)bl; if (md->class_ == MOBID_EMPERIUM) return 0; - if (sc_def < 50) - sc_def = 50; + if (sc_def > 5000) + sc_def = 5000; } - return (sc_def < 0) ? 0 : sc_def; + sd = bl->type==BL_PC?(struct map_session_data*)bl:NULL; + + if(sd && SC_COMMON_MIN<=type && type<=SC_COMMON_MAX && + sd->reseff[type-SC_COMMON_MIN] > 0) + sc_def += sd->reseff[type-SC_COMMON_MIN]; + + return sc_def; } +//Reduces tick delay based on type and character defenses. +int status_get_sc_tick(struct block_list *bl, int type, int tick) +{ + struct map_session_data *sd; + sd = bl->type == BL_PC?(struct map_session_data *)bl:NULL; + switch (type) { + case SC_DECREASEAGI: /* 速度減少 */ + if (sd) // Celest + tick>>=1; + break; + case SC_ADRENALINE: /* アドレナリンラッシュ */ + case SC_ADRENALINE2: + case SC_WEAPONPERFECTION: /* ウェポンパ?フェクション */ + case SC_OVERTHRUST: /* オ?バ?スラスト */ + if(sd && pc_checkskill(sd,BS_HILTBINDING)>0) + tick += tick / 10; + break; + case SC_STONE: /* 石化 */ + tick = tick-status_get_mdef(bl)*200; + break; + case SC_FREEZE: /* 凍結 */ + tick -= tick*status_get_mdef(bl)/100; + break; + case SC_STAN: /* スタン(val2にミリ秒セット) */ + tick -= tick*status_get_sc_def_vit(bl)/10000; + break; + case SC_DPOISON: /* 猛毒 */ + case SC_POISON: /* 毒 */ + tick -= tick*(status_get_vit(bl) + status_get_luk(bl)/5)/100; + break; + case SC_SILENCE: /* 沈?(レックスデビ?ナ) */ + case SC_CONFUSION: + case SC_CURSE: + tick -= tick * status_get_vit(bl)/100; + break; + case SC_BLIND: /* 暗? */ + if(tick < 1000) + tick = 30000; + tick -= tick*(status_get_lv(bl)/10 + status_get_int(bl)/15)/100; + if (tick < 5000) //Minimum 5 secs? + tick = 5000; + break; + case SC_BLEEDING: + tick -= tick*(status_get_lv(bl)/5 +status_get_vit(bl))/100; + if(tick < 10000) //Minimum bleed time is 10 secs or this sc does nothing! [Skotlex] + tick = 10000; + break; + case SC_SWOO: + if (status_get_mode(bl)&MD_BOSS) + tick /= 5; //Reduce skill's duration. But for how long? + break; + case SC_ANKLE: + tick -= status_get_agi(bl)*100; + if(status_get_mode(bl)&MD_BOSS) // Lasts 5 times less on bosses + tick /= 5; + // Minimum trap time of 3+0.03*skilllv seconds [celest] + // Changed to 3 secs and moved from skill.c [Skotlex] + if (tick < 3000) + tick = 3000; + break; + case SC_STOP: + // Unsure of this... but I get a feeling that agi reduces this + // (it was on Tiger Fist Code, but at -1 ms per 10 agi.... + tick -= 100*status_get_agi(bl); + break; + } + return tick; +} /*========================================== * Starts a status change. * type = type, val1~4 depend on the type. + * rate = base success rate. 100 = 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 *------------------------------------------ */ -int status_change_start(struct block_list *bl,int type,int val1,int val2,int val3,int val4,int tick,int flag) +int status_change_start(struct block_list *bl,int 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; - int opt_flag = 0, calc_flag = 0,updateflag = 0, save_flag = 0, race, mode, elem, undead_flag; - int scdef = 0; + int opt_flag , calc_flag = 0,updateflag = 0, save_flag = 0, race, mode, elem, undead_flag; nullpo_retr(0, bl); sc=status_get_sc(bl); @@ -3641,15 +3713,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val if (((struct mob_data*)bl)->class_ == MOBID_EMPERIUM && type != SC_SAFETYWALL) return 0; //Emperium can't be afflicted by status changes. break; - /* For more flexibility. Anything that has a sc data, let it through. [Skotlex] - case BL_PET: //Because pets can't have status changes. - case BL_SKILL: //These may happen by attacking traps or the like. [Skotlex] - return 0; - default: - if(battle_config.error_log) - ShowError("status_change_start: invalid source type (%d)!\n", bl->type); - return 0; - */ } if(type < 0 || type >= SC_MAX) { @@ -3658,120 +3721,162 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val return 0; } + //Check rate + if (!(flag&(4|1))) { + if (flag&8) { + race = status_get_sc_def(bl, type); + if (race) + rate -= rate*race/100; + } else + rate*=100; //Pass to 10000 = 100% + if (!(rand()%10000 < rate)) + return 0; + } + race=status_get_race(bl); mode=status_get_mode(bl); elem=status_get_elem_type(bl); undead_flag=battle_check_undead(race,elem); - if(type == SC_AETERNA && (sc->data[SC_STONE].timer != -1 || sc->data[SC_FREEZE].timer != -1) ) - return 0; - if(type == SC_OVERTHRUST && sc->data[SC_MAXOVERTHRUST].timer != -1) - return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex] - switch(type){ + //Check for inmunities / sc fails + switch (type) { case SC_STONE: case SC_FREEZE: - scdef=3+status_get_mdef(bl)+status_get_luk(bl)/3; - break; - case SC_STAN: - case SC_SILENCE: - case SC_POISON: - case SC_DPOISON: - scdef=3+status_get_vit(bl)+status_get_luk(bl)/3; - break; + //I've been informed that undead chars are inmune to stone curse too. [Skotlex] + if (undead_flag && !(flag&1)) + return 0; case SC_SLEEP: - case SC_BLIND: - scdef=3+status_get_int(bl)+status_get_luk(bl)/3; - break; + case SC_STAN: + if (sc->opt1) + return 0; //Cannot override other opt1 status changes. [Skotlex] + break; case SC_CURSE: - scdef=3+status_get_luk(bl); - break; - default: - scdef=0; + //Dark Elementals are inmune to curse. + if (elem == 7 && !(flag&1)) + return 0; + break; + case SC_COMA: + //Dark elementals and Demons are inmune to coma. + if((elem == 7 || race == 6) && !(flag&1)) + return 0; + break; + case SC_AETERNA: + if (sc->data[SC_STONE].timer != -1 || sc->data[SC_FREEZE].timer != -1) + return 0; + break; + case SC_OVERTHRUST: + if (sc->data[SC_MAXOVERTHRUST].timer != -1) + return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex] + break; + case SC_ADRENALINE: + if (sd && !(skill_get_weapontype(BS_ADRENALINE)&(1<status.weapon))) + return 0; + if (sc->data[SC_QUAGMIRE].timer!=-1 || + sc->data[SC_DONTFORGETME].timer!=-1 || + sc->data[SC_DECREASEAGI].timer!=-1 + ) + return 0; + break; + case SC_ADRENALINE2: + if (sd && !(skill_get_weapontype(BS_ADRENALINE2)&(1<status.weapon))) + return 0; + if (sc->data[SC_QUAGMIRE].timer!=-1 || + sc->data[SC_DONTFORGETME].timer!=-1 || + sc->data[SC_DECREASEAGI].timer!=-1 + ) + return 0; + break; + case SC_ONEHAND: + case SC_TWOHANDQUICKEN: + if(sc->data[SC_DECREASEAGI].timer!=-1) + return 0; + case SC_CONCENTRATE: + case SC_INCREASEAGI: + case SC_SPEARSQUICKEN: + case SC_TRUESIGHT: + case SC_WINDWALK: + case SC_CARTBOOST: + case SC_ASSNCROS: + if (sc->data[SC_QUAGMIRE].timer!=-1 || sc->data[SC_DONTFORGETME].timer!=-1) + 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 && skilllv < 3 && skill_check_cloaking(bl)) + if (sd && pc_checkskill(sd, AS_CLOAKING)< 3 && skill_check_cloaking(bl)) + return 0; + break; } - if(scdef>=100) - return 0; - - if(sd){ - if(type == SC_ADRENALINE && !(skill_get_weapontype(BS_ADRENALINE)&(1<status.weapon))) - return 0; - if(type == SC_ADRENALINE2 && !(skill_get_weapontype(BS_ADRENALINE2)&(1<status.weapon))) - return 0; - if(SC_COMMON_MIN<=type && type<=SC_COMMON_MAX && !(flag&1)){ - if(sd->reseff[type-SC_COMMON_MIN] > 0 && rand()%10000reseff[type-SC_COMMON_MIN]){ - if(battle_config.battle_log) - ShowInfo("PC %d skill_sc_start: status change %d blocked by reseff card (AID: %d).\n",type,bl->id); + //Check for BOSS resistnces + if(mode & MD_BOSS && !(flag&1)) { + if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX) + return 0; + switch (type) { + case SC_BLESSING: + if (!undead_flag || race != 6) + break; + case SC_QUAGMIRE: + case SC_DECREASEAGI: + case SC_SIGNUMCRUCIS: + case SC_PROVOKE: + case SC_ROKISWEIL: + case SC_COMA: + case SC_GRAVITATION: return 0; - } } } - if (sc->opt1) + //Check for overlapping fails + if(sc->data[type].timer != -1){ switch (type) { - case SC_STONE: - case SC_FREEZE: - case SC_SLEEP: + case SC_ADRENALINE: + case SC_ADRENALINE2: + case SC_WEAPONPERFECTION: + case SC_OVERTHRUST: + if (sc->data[type].val2 && !val2) + return 0; + break; + case SC_GOSPEL: + //Must not override a casting gospel char. + if (sc->data[type].val4 == BCT_SELF) + return 0; case SC_STAN: - return 0; //Cannot override other opt1 status changes. [Skotlex] - } - - if((type==SC_FREEZE || type==SC_STONE) && undead_flag && !(flag&1)) - //I've been informed that undead chars are inmune to stone curse too. [Skotlex] - return 0; - //Dark Elementals are inmune to curse. - if(type==SC_CURSE && elem == 7 && !(flag&1)) - return 0; - - if (type==SC_BLESSING && (bl->type==BL_PC || (!undead_flag && race!=6))) { - if (sc->data[SC_CURSE].timer!=-1) - status_change_end(bl,SC_CURSE,-1); - if (sc->data[SC_STONE].timer!=-1 && sc->data[SC_STONE].val2==0) - status_change_end(bl,SC_STONE,-1); - } - - if((type == SC_ADRENALINE || type==SC_ADRENALINE2 || type == SC_WEAPONPERFECTION || type == SC_OVERTHRUST) && - sc->data[type].timer != -1 && sc->data[type].val2 && !val2) - return 0; - - if(mode & MD_BOSS && !(flag&1) && ( (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX) - || type==SC_QUAGMIRE || type==SC_DECREASEAGI || type==SC_SIGNUMCRUCIS - || type==SC_PROVOKE || type==SC_ROKISWEIL || type==SC_COMA - || (type == SC_BLESSING && (undead_flag || race == 6)))){ - /* ボスには?かない(ただしカ?ドによる?果は適用される) */ - return 0; - } - - if(sc->data[type].timer != -1){ /* すでに同じ異常になっている場合タイマ解除 */ - if(sc->data[type].val1 > val1 && type != SC_COMBO && type != SC_DANCING && type != SC_DEVOTION && - type != SC_ASPDPOTION0 && type != SC_ASPDPOTION1 && type != SC_ASPDPOTION2 && type != SC_ASPDPOTION3 - && type != SC_ATKPOTION && type != SC_MATKPOTION // added atk and matk potions [Valaris] - ) - return 0; - - if ((type >=SC_STAN && type <= SC_BLIND) || type == SC_DPOISON) - return 0;/* ?ぎ足しができない?態異常である時は?態異常を行わない */ - - if (type == SC_GOSPEL && sc->data[type].val4 == BCT_SELF) //Must not override a casting gospel char. - return 0; - + case SC_SLEEP: + case SC_POISON: + case SC_CURSE: + case SC_SILENCE: + case SC_CONFUSION: + case SC_BLIND: + case SC_BLEEDING: + case SC_DPOISON: + case SC_COMBO: //You aren't supposed to change the combo (and it gets turned off when you trigger it) + return 0; + case SC_DANCING: + case SC_DEVOTION: + case SC_ASPDPOTION0: + case SC_ASPDPOTION1: + case SC_ASPDPOTION2: + case SC_ASPDPOTION3: + case SC_ATKPOTION: + case SC_MATKPOTION: + break; + default: + if(sc->data[type].val1 > val1) + return 0; + } (sc->count)--; delete_timer(sc->data[type].timer, status_change_timer); sc->data[type].timer = -1; } - if(type==SC_FREEZE || type==SC_STAN || type==SC_SLEEP || type==SC_STOP || type == SC_CONFUSION || - type==SC_CLOSECONFINE || type==SC_CLOSECONFINE2 || type ==SC_TRICKDEAD) - battle_stopwalking(bl,1); - - // クアグマイア/私を忘れないで中は無効なスキル - if ((sc->data[SC_QUAGMIRE].timer!=-1 || sc->data[SC_DONTFORGETME].timer!=-1) && - (type==SC_CONCENTRATE || type==SC_INCREASEAGI || - type==SC_TWOHANDQUICKEN || type==SC_SPEARSQUICKEN || - type==SC_ADRENALINE || type==SC_ADRENALINE2 || - type==SC_TRUESIGHT || type==SC_WINDWALK || - type==SC_CARTBOOST || type==SC_ASSNCROS || - type==SC_ONEHAND)) - return 0; + //SC duration reduction. + if(!(flag&(2|4)) && tick) { + tick = status_get_sc_tick(bl, type, tick); + if (tick < 0) + return 0; + } switch(type){ /* 異常の種類ごとの?理 */ case SC_PROVOKE: /* プロボック */ @@ -3787,9 +3892,9 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val { if (!(flag&4)) tick = 60*1000; - if (bl->type == BL_PC && sd->status.hpstatus.max_hp>>2 && + if (sd && sd->status.hpstatus.max_hp>>2 && (sc->data[SC_PROVOKE].timer==-1 || sc->data[SC_PROVOKE].val2==0)) - status_change_start(bl,SC_PROVOKE,10,1,0,0,0,0); + status_change_start(bl,SC_PROVOKE,10,10000,1,0,0,0,0); } break; @@ -3799,8 +3904,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val status_change_end(bl,SC_DECREASEAGI,-1); break; case SC_DECREASEAGI: /* 速度減少 */ - if (bl->type == BL_PC && !(tick&2)) // Celest - tick>>=1; calc_flag = 1; if(sc->data[SC_INCREASEAGI].timer!=-1 ) status_change_end(bl,SC_INCREASEAGI,-1); @@ -3833,32 +3936,8 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val status_change_end(bl,SC_ASPDPOTION2,-1); if(sc->data[SC_ASPDPOTION3].timer!=-1) status_change_end(bl,SC_ASPDPOTION3,-1); - case SC_TWOHANDQUICKEN: /* 2HQ */ - if(sc->data[SC_DECREASEAGI].timer!=-1) - return 0; - sc->opt3 |= 1; - calc_flag = 1; - break; - case SC_ADRENALINE2: - case SC_ADRENALINE: /* アドレナリンラッシュ */ - if(sc->data[SC_DECREASEAGI].timer!=-1) - return 0; - if(bl->type == BL_PC && !(flag&2)) - if(pc_checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; calc_flag = 1; break; - case SC_WEAPONPERFECTION: /* ウェポンパ?フェクション */ - if(bl->type == BL_PC && !(flag&2)) - if(pc_checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; - break; - case SC_OVERTHRUST: /* オ?バ?スラスト */ - if(bl->type == BL_PC && !(flag&2)) - if(pc_checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; - sc->opt3 |= 2; - break; case SC_MAXOVERTHRUST: //Cancels Normal Overthrust. [Skotlex] if (sc->data[SC_OVERTHRUST].timer != -1) status_change_end(bl, SC_OVERTHRUST, -1); @@ -3871,11 +3950,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val val2 = tick; } break; - case SC_ENCPOISON: /* エンチャントポイズン */ - calc_flag = 1; - val2=(((val1 - 1) / 2) + 3)*100; /* 毒付?確率 */ - skill_enchant_elemental_end(bl,SC_ENCPOISON); - break; case SC_EDP: // [Celest] val2 = val1 + 2; /* 猛毒付?確率(%) */ calc_flag = 1; @@ -3884,9 +3958,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val if (!(flag&4)) val2=val1/2 + val1%2; // [Celest] break; - case SC_ENERGYCOAT: /* エナジ?コ?ト */ - sc->opt3 |= 4; - break; case SC_MAGICROD: val2 = val1*20; break; @@ -3903,10 +3974,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val case SC_MINDBREAKER: calc_flag = 1; if(tick <= 0) tick = 1000; /* (オ?トバ?サ?ク) */ - case SC_TRICKDEAD: /* 死んだふり */ - if (bl->type == BL_PC) { - pc_stopattack(sd); - } break; case SC_QUAGMIRE: /* クァグマイア */ calc_flag = 1; @@ -3939,26 +4006,17 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val if (!(flag&4)) val2 = 5; break; + case SC_ENCPOISON: /* エンチャントポイズン */ + calc_flag = 1; + val2=(((val1 - 1) / 2) + 3)*100; /* 毒付?確率 */ case SC_ASPERSIO: /* アスペルシオ */ - skill_enchant_elemental_end(bl,SC_ASPERSIO); - break; case SC_FIREWEAPON: /* フレ?ムランチャ? */ - skill_enchant_elemental_end(bl,SC_FIREWEAPON); - break; case SC_WATERWEAPON: /* フロストウェポン */ - skill_enchant_elemental_end(bl,SC_WATERWEAPON); - break; case SC_WINDWEAPON: /* ライトニングロ?ダ? */ - skill_enchant_elemental_end(bl,SC_WINDWEAPON); - break; case SC_EARTHWEAPON: /* サイズミックウェポン */ - skill_enchant_elemental_end(bl,SC_EARTHWEAPON); - break; case SC_SHADOWWEAPON: - skill_enchant_elemental_end(bl,SC_SHADOWWEAPON); - break; case SC_GHOSTWEAPON: - skill_enchant_elemental_end(bl,SC_GHOSTWEAPON); + skill_enchant_elemental_end(bl,type); break; case SC_PROVIDENCE: /* プロヴィデンス */ calc_flag = 1; @@ -3995,35 +4053,12 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val case SC_SPEARSQUICKEN: /* スピアクイッケン */ calc_flag = 1; val2 = 20+val1; - sc->opt3 |= 1; break; case SC_BLADESTOP: /* 白刃取り */ if(val2==2) clif_bladestop((struct block_list *)val3,(struct block_list *)val4,1); - sc->opt3 |= 32; break; - case SC_LULLABY: /* 子守唄 */ - case SC_RICHMANKIM: - case SC_ROKISWEIL: /* ロキの叫び */ - case SC_INTOABYSS: /* 深淵の中に */ - case SC_POEMBRAGI: /* ブラギの詩 */ - case SC_UGLYDANCE: /* 自分勝手なダンス */ - break; - case SC_ETERNALCHAOS: /* エタ?ナルカオス */ - case SC_DRUMBATTLE: /* ?太鼓の響き */ - case SC_NIBELUNGEN: /* ニ?ベルングの指輪 */ - case SC_SIEGFRIED: /* 不死身のジ?クフリ?ド */ - case SC_WHISTLE: /* 口笛 */ - case SC_ASSNCROS: /* 夕陽のアサシンクロス */ - case SC_APPLEIDUN: /* イドゥンの林檎 */ - case SC_HUMMING: /* ハミング */ - case SC_ATKPOTION: // Valaris - case SC_MATKPOTION: - case SC_FORTUNE: /* 幸運のキス */ - case SC_SERVICE4U: /* サ?ビスフォ?ユ? */ - calc_flag = 1; - break; case SC_DONTFORGETME: /* 私を忘れないで */ calc_flag = 1; if(sc->data[SC_INCREASEAGI].timer!=-1 ) /* 速度上昇解除 */ @@ -4063,12 +4098,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val case SC_EXPLOSIONSPIRITS: // 爆裂波動 calc_flag = 1; val2 = 75 + 25*val1; - sc->opt3 |= 8; - break; - case SC_STEELBODY: // 金剛 - case SC_SKA: - calc_flag = 1; - sc->opt3 |= 16; break; case SC_AUTOCOUNTER: val3 = val4 = 0; @@ -4085,27 +4114,24 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val case SC_XMAS: // Xmas Suit [Valaris] case SC_WEDDING: //結婚用(結婚衣裳になって?くのが?いとか) - { - struct map_session_data *sd; - if (bl->type == BL_PC && (sd= (struct map_session_data *)bl)) - { //Change look. - if(type==SC_WEDDING) - sd->view_class = JOB_WEDDING; - else if(type==SC_XMAS) - sd->view_class = JOB_XMAS; - clif_changelook(&sd->bl,LOOK_BASE,sd->view_class); + if (sd) + { //Change look. + if(type==SC_WEDDING) + sd->view_class = JOB_WEDDING; + else if(type==SC_XMAS) + sd->view_class = JOB_XMAS; + clif_changelook(&sd->bl,LOOK_BASE,sd->view_class); #if PACKETVER < 4 - clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); + clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); + clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); #else - clif_changelook(&sd->bl,LOOK_WEAPON,0); + clif_changelook(&sd->bl,LOOK_WEAPON,0); #endif - if(battle_config.save_clothcolor && sd->status.clothes_color > 0 && - ((type==SC_WEDDING && !battle_config.wedding_ignorepalette) || - (type==SC_XMAS && !battle_config.xmas_ignorepalette))) - clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color); - } - } + if(battle_config.save_clothcolor && sd->status.clothes_color > 0 && + ((type==SC_WEDDING && !battle_config.wedding_ignorepalette) || + (type==SC_XMAS && !battle_config.xmas_ignorepalette))) + clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color); + } break; case SC_NOCHAT: //チャット禁止?態 { @@ -4121,33 +4147,16 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val /* option1 */ case SC_STONE: /* 石化 */ - if(!(flag&2)) { - int sc_def = status_get_mdef(bl)*200; - tick = tick - sc_def; - } - if (!(flag&4)) - val3 = tick/1000; - if(val3 < 1) val3 = 1; - if (!(flag&4)) - tick = 5000; + if (flag&4) + break; val2 = 1; + val3 = tick/1000; + if(val3 < 1) val3 = 1; + tick = 5000; break; case SC_SLEEP: /* 睡眠 */ - if(!(flag&4)) { + if(!(flag&4)) tick = 30000;//睡眠はステ?タス耐性に?わらず30秒 - } - break; - case SC_FREEZE: /* 凍結 */ - if(!(flag&2)) { - int sc_def = 100 - status_get_mdef(bl); - tick = tick * sc_def / 100; - } - break; - case SC_STAN: /* スタン(val2にミリ秒セット) */ - if(!(flag&2)) { - int sc_def = status_get_sc_def_vit(bl); - tick = tick * sc_def / 100; - } break; /* option2 */ @@ -4180,10 +4189,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val calc_flag = 1; if (flag&4) break; - if(!(flag&2)) { - int sc_def = 100 - (status_get_vit(bl) + status_get_luk(bl)/5); - tick = tick * sc_def / 100; - } val3 = tick/1000; if(val3 < 1) val3 = 1; tick = 1000; @@ -4202,48 +4207,14 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val } break; } - if(!(flag&2)) { - int sc_def = 100 - status_get_vit(bl); - tick = tick * sc_def / 100; - } break; case SC_CONFUSION: - if(!(flag&2)) { - int sc_def = 100 - status_get_vit(bl); - tick = tick * sc_def / 100; - } clif_emotion(bl,1); break; - case SC_BLIND: /* 暗? */ - calc_flag = 1; - if(!(flag&4) && tick < 1000) - tick = 30000; - if(!(flag&2)) { - int sc_def = 100 - (status_get_lv(bl)/10 + status_get_int(bl)/15); - tick = tick*sc_def/100; - if (tick < 5000) //Minimum 5 secs? - tick = 5000; - } - break; - case SC_CURSE: - calc_flag = 1; - if(!(flag&2)) { - int sc_def = 100 - status_get_vit(bl); - tick = tick * sc_def / 100; - } - break; - case SC_BLEEDING: - if(!(flag&2)) { - int sc_def = 100 - (status_get_lv(bl)/5 +status_get_vit(bl)); - tick = tick * sc_def / 100; - } - if(!(flag&4) && tick < 10000) //Minimum bleed time is 10 secs or this sc does nothing! [Skotlex] - tick = 10000; val4 = tick; tick = 10000; break; - /* option */ case SC_HIDING: /* ハイディング */ calc_flag = 1; @@ -4298,7 +4269,7 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val for (i = 0; i < 5; i++) { //Pass the status to the other affected chars. [Skotlex] if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i]))) - status_change_start(&tsd->bl,SC_AUTOGUARD,val1,val2,0,0,tick,1); + status_change_start(&tsd->bl,SC_AUTOGUARD,10000,val1,val2,0,0,tick,1); } } break; @@ -4314,16 +4285,11 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val 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(&tsd->bl,SC_DEFENDER,val1,val2,0,0,tick,1); + status_change_start(&tsd->bl,SC_DEFENDER,10000,val1,val2,0,0,tick,1); } } break; - case SC_CONCENTRATION: /* コンセントレ?ション */ - sc->opt3 |= 1; - calc_flag = 1; - break; - case SC_TENSIONRELAX: /* テンションリラックス */ if (flag&4) break; @@ -4344,7 +4310,7 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val case SC_JOINTBEAT: // Random break [DracoRPG] calc_flag = 1; val2 = rand()%6; - if (val2 == 5) status_change_start(bl,SC_BLEEDING,val1,0,0,0,skill_get_time2(type,val1),0); + if (val2 == 5) status_change_start(bl,SC_BLEEDING,10000,val1,0,0,0,skill_get_time2(type,val1),0); break; case SC_BERSERK: /* バ?サ?ク */ @@ -4355,14 +4321,12 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val clif_updatestatus(sd,SP_SP); sd->canregen_tick = gettick() + 300000; } - sc->opt3 |= 128; if (!(flag&4)) tick = 10000; calc_flag = 1; break; case SC_ASSUMPTIO: /* アスムプティオ */ - sc->opt3 |= 2048; if(sc->data[SC_KYRIE].timer!=-1) status_change_end(bl,SC_KYRIE,-1); break; @@ -4372,8 +4336,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val val2 = tick/1000; tick = 1000; } - sc->opt3 |= 4096; - opt_flag = 1; break; case SC_GOSPEL: @@ -4397,7 +4359,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val return 0; tick = 1000; calc_flag = 1; - sc->opt3 |= 1024; break; case SC_REJECTSWORD: /* リジェクトソ?ド */ @@ -4442,10 +4403,12 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val //Ideally, we should calculate the remaining time and use that, but we'll trust that //once the Crusader's status changes, it will reflect on the others. if (src->sc.data[SC_AUTOGUARD].timer != -1) - status_change_start(bl,SC_AUTOGUARD,src->sc.data[SC_AUTOGUARD].val1,0,0,0, + status_change_start(bl,SC_AUTOGUARD,10000, + src->sc.data[SC_AUTOGUARD].val1,0,0,0, skill_get_time(CR_AUTOGUARD,src->sc.data[SC_AUTOGUARD].val1),0); if (src->sc.data[SC_DEFENDER].timer != -1) - status_change_start(bl,SC_DEFENDER,src->sc.data[SC_DEFENDER].val1,0,0,0, + status_change_start(bl,SC_DEFENDER,10000, + src->sc.data[SC_DEFENDER].val1,0,0,0, skill_get_time(CR_DEFENDER,src->sc.data[SC_DEFENDER].val1),0); } break; @@ -4470,7 +4433,7 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val struct status_change *sc2 = src?status_get_sc(src):NULL; if (src && sc2 && sc2->count) { if (sc2->data[SC_CLOSECONFINE].timer == -1) //Start lock on caster. - status_change_start(src,SC_CLOSECONFINE,1,0,0,0,tick+1000,0); + status_change_start(src,SC_CLOSECONFINE,10000,1,0,0,0,tick+1000,0); else { //Increase count of locked enemies and refresh time. sc2->data[SC_CLOSECONFINE].val1++; delete_timer(sc2->data[SC_CLOSECONFINE].timer, status_change_timer); @@ -4519,13 +4482,6 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val break; } break; - case SC_SWOO: // [marquis007] - if (!(flag&4) && status_get_mode(bl)&MD_BOSS) - tick /= 4; //Reduce skill's duration. But for how long? -// sc->opt3 |= 8192; //We haven't figured out this value yet... - opt_flag = 1; - calc_flag = 1; - break; case SC_TKDORI: val2 = 11-val1; //Chance to consume: 11-skilllv% break; @@ -4534,11 +4490,30 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val val4 = gettick(); //Store time at which you started running. calc_flag = 1; break; - case SC_INCATKRATE: /* ATK%上昇 */ - if (bl->type == BL_MOB) - sc->opt3 |= 8; //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex] + case SC_BLESSING: + if (bl->type==BL_PC || (!undead_flag && race!=6)) { + if (sc->data[SC_CURSE].timer!=-1) + status_change_end(bl,SC_CURSE,-1); + if (sc->data[SC_STONE].timer!=-1 && sc->data[SC_STONE].val2==0) + status_change_end(bl,SC_STONE,-1); + } + case SC_CONCENTRATION: /* コンセントレ?ション */case SC_ETERNALCHAOS: /* エタ?ナルカオス */ + case SC_DRUMBATTLE: /* ?太鼓の響き */ + case SC_NIBELUNGEN: /* ニ?ベルングの指輪 */ + case SC_SIEGFRIED: /* 不死身のジ?クフリ?ド */ + case SC_WHISTLE: /* 口笛 */ + case SC_ASSNCROS: /* 夕陽のアサシンクロス */ + case SC_APPLEIDUN: /* イドゥンの林檎 */ + case SC_HUMMING: /* ハミング */ + case SC_ATKPOTION: // Valaris + case SC_MATKPOTION: + case SC_FORTUNE: /* 幸運のキス */ + case SC_SERVICE4U: /* サ?ビスフォ?ユ? */ + case SC_ADRENALINE2: + case SC_ADRENALINE: /* アドレナリンラッシュ */ + case SC_BLIND: /* 暗? */ + case SC_CURSE: case SC_CONCENTRATE: /* 集中力向上 */ - case SC_BLESSING: /* ブレッシング */ case SC_ANGELUS: /* アンゼルス */ case SC_IMPOSITIO: /* インポシティオマヌス */ case SC_GLORIA: /* グロリア */ @@ -4558,6 +4533,7 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val case SC_INCFLEERATE: /* FLEE%上昇 */ case SC_INCMHPRATE: /* MHP%上昇 */ case SC_INCMSPRATE: /* MSP%上昇 */ + case SC_INCATKRATE: /* ATK%上昇 */ case SC_INCMATKRATE: case SC_INCDEFRATE: case SC_INCSTR: @@ -4584,10 +4560,26 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val case SC_STAR_COMFORT: case SC_FUSION: case SC_SKE: + case SC_SWOO: // [marquis007] + case SC_STEELBODY: // 金剛 + case SC_SKA: + case SC_TWOHANDQUICKEN: /* 2HQ */ calc_flag = 1; break; + case SC_LULLABY: /* 子守唄 */ + case SC_RICHMANKIM: + case SC_ROKISWEIL: /* ロキの叫び */ + case SC_INTOABYSS: /* 深淵の中に */ + case SC_POEMBRAGI: /* ブラギの詩 */ + case SC_UGLYDANCE: /* 自分勝手なダンス */ + case SC_WEAPONPERFECTION: /* ウェポンパ?フェクション */ + case SC_TRICKDEAD: /* 死んだふり */ + case SC_FREEZE: /* 凍結 */ + case SC_STAN: /* スタン(val2にミリ秒セット) */ + case SC_ENERGYCOAT: /* エナジ?コ?ト */ case SC_SAFETYWALL: + case SC_OVERTHRUST: /* オ?バ?スラスト */ case SC_SLOWPOISON: //Slow potion can be activated even if not poisoned. case SC_SUFFRAGIUM: /* サフラギム */ case SC_BENEDICTIO: /* 聖? */ @@ -4631,6 +4623,31 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val return 0; } + //Those that make you stop attacking/walking.... + switch (type) { + case SC_FREEZE: + case SC_STAN: + case SC_SLEEP: + case SC_TRICKDEAD: + battle_stopattack(bl); + skill_stop_dancing(bl); /* 演奏/ダンスの中? */ + // Cancel cast when get status [LuzZza] + if (!sd || sd->skillid != PA_PRESSURE) //Only Pressure cannot be cancelled. + skill_castcancel(bl, 0); + case SC_STOP: + case SC_CONFUSION: + case SC_CLOSECONFINE: + case SC_CLOSECONFINE2: + battle_stopwalking(bl,1); + break; + case SC_HIDING: + case SC_CLOAKING: + case SC_CHASEWALK: + battle_stopattack(bl); /* 攻?停止 */ + break; + } + + if (bl->type == BL_PC && (battle_config.display_hallucination || type != SC_HALLUCINATION)) { if (flag&4) @@ -4638,80 +4655,118 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val clif_status_change(bl,StatusIconChangeTable[type],1); } - /* optionの?更 */ + // Set option as needed. + opt_flag = 1; switch(type){ + //OPT1 case SC_STONE: case SC_FREEZE: case SC_STAN: case SC_SLEEP: - - // Cancel cast when get status [LuzZza] - if (bl->type == BL_PC) { - struct map_session_data *sd = (struct map_session_data *)bl; //Only Pressure is uninterruptable. - if (sd->skilltimer != -1 && sd->skillid != PA_PRESSURE) skill_castcancel(bl, 0); - } else - if (bl->type == BL_MOB) { - if (((struct mob_data *)bl)->skilltimer != -1) skill_castcancel(bl, 0); - } - - battle_stopattack(bl); /* 攻?停止 */ - skill_stop_dancing(bl); /* 演奏/ダンスの中? */ if(type == SC_STONE) sc->opt1 = OPT1_STONEWAIT; else sc->opt1 = OPT1_STONE + (type - SC_STONE); - opt_flag = 1; break; + //OPT2 case SC_POISON: case SC_CURSE: case SC_SILENCE: case SC_BLIND: sc->opt2 |= 1<<(type-SC_POISON); - opt_flag = 1; break; case SC_DPOISON: // 暫定で毒のエフェクトを使用 sc->opt2 |= OPT2_DPOISON; - opt_flag = 1; break; case SC_SIGNUMCRUCIS: sc->opt2 |= OPT2_SIGNUMCRUCIS; - opt_flag = 1; break; + //OPT3 + case SC_TWOHANDQUICKEN: /* 2HQ */ + case SC_SPEARSQUICKEN: /* スピアクイッケン */ + case SC_CONCENTRATION: /* コンセントレ?ション */ + sc->opt3 |= 1; + opt_flag = 0; + break; + case SC_MAXOVERTHRUST: + case SC_OVERTHRUST: /* オ?バ?スラスト */ + sc->opt3 |= 2; + opt_flag = 0; + break; + case SC_ENERGYCOAT: /* エナジ?コ?ト */ + sc->opt3 |= 4; + opt_flag = 0; + break; + case SC_INCATKRATE: /* ATK%上昇 */ + //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex] + if (bl->type != BL_MOB) { + opt_flag = 0; + break; + } + case SC_EXPLOSIONSPIRITS: // 爆裂波動 + sc->opt3 |= 8; + opt_flag = 0; + break; + case SC_STEELBODY: // 金剛 + case SC_SKA: + sc->opt3 |= 16; + opt_flag = 0; + break; + case SC_BLADESTOP: /* 白刃取り */ + sc->opt3 |= 32; + opt_flag = 0; + break; + case SC_BERSERK: /* バ?サ?ク */ + sc->opt3 |= 128; + opt_flag = 0; + break; + case SC_MARIONETTE: /* マリオネットコントロ?ル */ + case SC_MARIONETTE2: + sc->opt3 |= 1024; + opt_flag = 0; + break; + case SC_ASSUMPTIO: /* アスムプティオ */ + sc->opt3 |= 2048; + opt_flag = 0; + break; + case SC_WARM: //SG skills [Komurka] + sc->opt3 |= 4096; + opt_flag = 0; + break; +// case SC_SWOO: // [marquis007] +// sc->opt3 |= 8192; //We haven't figured out this value yet... +// break; + + //OPTION case SC_HIDING: + sc->option |= OPTION_HIDE; + break; case SC_CLOAKING: - battle_stopattack(bl); /* 攻?停止 */ - sc->option |= ((type==SC_HIDING)?OPTION_HIDE:OPTION_CLOAK); - opt_flag =1 ; + sc->option |= OPTION_CLOAK; break; case SC_CHASEWALK: - battle_stopattack(bl); /* 攻?停止 */ sc->option |= OPTION_CHASEWALK|OPTION_CLOAK; - opt_flag =1 ; break; case SC_SIGHT: sc->option |= OPTION_SIGHT; - opt_flag = 1; break; case SC_RUWACH: sc->option |= OPTION_RUWACH; - opt_flag = 1; break; case SC_WEDDING: sc->option |= OPTION_WEDDING; - opt_flag = 1; break; case SC_ORCISH: sc->option |= OPTION_ORCISH; - opt_flag = 1; break; case SC_SIGHTTRASHER: sc->option |= OPTION_SIGHTTRASHER; - opt_flag = 1; break; case SC_FUSION: sc->option |= OPTION_FLYING; - opt_flag = 1; break; + default: + opt_flag = 0; } if(opt_flag) /* optionの?更 */ @@ -4727,22 +4782,19 @@ int status_change_start(struct block_list *bl,int type,int val1,int val2,int val sc->data[type].timer = add_timer( gettick() + tick, status_change_timer, bl->id, type); - if(bl->type==BL_PC && calc_flag) - status_calc_pc(sd,0); /* ステ?タス再計算 */ - - if(bl->type==BL_PC && save_flag) - chrif_save(sd,0); // save the player status - - if(bl->type==BL_PC && updateflag) - clif_updatestatus(sd,updateflag); /* ステ?タスをクライアントに送る */ - - if (bl->type==BL_PC && sd->pd) - pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing - - if(type==SC_RUN && bl->type==BL_PC) - pc_run(sd,val1,val2); - - return 0; + if(sd) { + if (calc_flag) + status_calc_pc(sd,0); /* ステ?タス再計算 */ + if(save_flag) + chrif_save(sd,0); // save the player status + if(updateflag) + clif_updatestatus(sd,updateflag); /* ステ?タスをクライアントに送る */ + if (sd->pd) + pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing + if (type==SC_RUN) + pc_run(sd,val1,val2); + } + return 1; } /*========================================== * ステータス異常全解除 @@ -4941,7 +4993,7 @@ int status_change_end( struct block_list* bl , int type,int tid ) DIFF_TICK(gettick(), sc->data[type].val4) <= 1000 && (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0)) ) - status_change_start(bl,SC_SPURT,sc->data[type].val1,0,0,0,skill_get_time2(TK_RUN, sc->data[type].val1),0); + status_change_start(bl,SC_SPURT,10000,sc->data[type].val1,0,0,0,skill_get_time2(TK_RUN, sc->data[type].val1),0); calc_flag = 1; break; case SC_AUTOBERSERK: @@ -5230,7 +5282,7 @@ int status_change_end( struct block_list* bl , int type,int tid ) status_calc_pc((struct map_session_data *)bl,0); /* ステ?タス再計算 */ } - return 0; + return 1; } @@ -5292,7 +5344,8 @@ int status_change_timer(int tid, unsigned int tick, int id, int data) sd->status.sp -= sp; // update sp cost [Celest] clif_updatestatus(sd,SP_SP); if ((++sc->data[SC_CHASEWALK].val4) == 1) { - status_change_start(bl, SC_INCSTR, 1<<(sc->data[SC_CHASEWALK].val1-1), 0, 0, 0, + status_change_start(bl, SC_INCSTR,10000, + 1<<(sc->data[SC_CHASEWALK].val1-1), 0, 0, 0, (sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration *skill_get_time2(ST_CHASEWALK,sc->data[SC_CHASEWALK].val1), 0); } diff --git a/src/map/status.h b/src/map/status.h index bd04f527c..e4774a4f8 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -479,7 +479,7 @@ int status_get_sc_def(struct block_list *bl, int type); #define status_get_sc_def_luk(bl) (status_get_sc_def(bl, SP_LUK)) // 状態異常関連 skill.c より移動 -int status_change_start(struct block_list *bl,int type,int val1,int val2,int val3,int val4,int tick,int flag); +int status_change_start(struct block_list *bl,int type,int rate,int val1,int val2,int val3,int val4,int tick,int flag); int status_change_end( struct block_list* bl , int type,int tid ); int status_change_timer(int tid, unsigned int tick, int id, int data); int status_change_timer_sub(struct block_list *bl, va_list ap ); -- cgit v1.2.3-70-g09d2