summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-02-08 16:56:53 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-02-08 16:56:53 +0000
commita9c2d623a66f27674ea539963a8738138ca7f6aa (patch)
tree50739b9bd7045cc5618702a486b8eda834f1b2e5
parent1847024eda6075c5637cef48bc14eb3e4958bd34 (diff)
downloadhercules-a9c2d623a66f27674ea539963a8738138ca7f6aa.tar.gz
hercules-a9c2d623a66f27674ea539963a8738138ca7f6aa.tar.bz2
hercules-a9c2d623a66f27674ea539963a8738138ca7f6aa.tar.xz
hercules-a9c2d623a66f27674ea539963a8738138ca7f6aa.zip
- 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
-rw-r--r--Changelog-Trunk.txt3
-rw-r--r--db/skill_cast_db.txt6
-rw-r--r--src/map/atcommand.c4
-rw-r--r--src/map/battle.c26
-rw-r--r--src/map/chrif.c2
-rw-r--r--src/map/clif.c17
-rw-r--r--src/map/mob.c2
-rw-r--r--src/map/party.c4
-rw-r--r--src/map/pc.c26
-rw-r--r--src/map/script.c17
-rw-r--r--src/map/skill.c946
-rw-r--r--src/map/status.c795
-rw-r--r--src/map/status.h2
13 files changed, 897 insertions, 953 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 1ced875a2..6431a1046 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -5,6 +5,9 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. EV
GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
2006/02/08
+ * Rewrote/organized status_change_start, it now receives the base rate for
+ the effect. It handles reducing this rate/duration through natural
+ resistances and whatever else should reduce it. [Skotlex]
* Fixes to exp2.txt on the novice job exp. Thanks to rollopop. [Skotlex]
- Also modified exp2.txt to use the normal max levels by default.
2006/02/07
diff --git a/db/skill_cast_db.txt b/db/skill_cast_db.txt
index fd5f9107d..ce39f6bbd 100644
--- a/db/skill_cast_db.txt
+++ b/db/skill_cast_db.txt
@@ -819,9 +819,9 @@
//-- HT_PHANTASMIC
1009,0,0,0,0
//-- BA_PANGVOICE
-1010,1000,2000,10000,0
-//-- DC_WINKCHARM
-1011,1000,2000,10000,0
+1010,1000,2000,17000,0
+//-- DC_WINKCHARM (time1: Charm, time2: Confusion)
+1011,1000,2000,10000,17000
//-- BS_GREED
1013,0,1000,0,0
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.hp<sd->status.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.hp<sd->status.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<<sd->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<<sd->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<<sd->status.weapon)))
- return 0;
- if(type == SC_ADRENALINE2 && !(skill_get_weapontype(BS_ADRENALINE2)&(1<<sd->status.weapon)))
- return 0;
- if(SC_COMMON_MIN<=type && type<=SC_COMMON_MAX && !(flag&1)){
- if(sd->reseff[type-SC_COMMON_MIN] > 0 && rand()%10000<sd->reseff[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.hp<sd->status.max_hp>>2 &&
+ if (sd && sd->status.hp<sd->status.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 );