diff options
author | skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2006-07-28 15:11:17 +0000 |
---|---|---|
committer | skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2006-07-28 15:11:17 +0000 |
commit | a5a5d08082d272690f89389db6029edf94fe551d (patch) | |
tree | 2dd9e2d74cd230904f53b4164570df2d6542ca48 /src/map | |
parent | 71140a6d9bb8b15fdee82745b559db0ca6a0052d (diff) | |
download | hercules-a5a5d08082d272690f89389db6029edf94fe551d.tar.gz hercules-a5a5d08082d272690f89389db6029edf94fe551d.tar.bz2 hercules-a5a5d08082d272690f89389db6029edf94fe551d.tar.xz hercules-a5a5d08082d272690f89389db6029edf94fe551d.zip |
- Cleaned up the NJ update code.
- Restored code which was removed (stuff like SC_SKA)
- Fixed possible crashes on some NJ skills if used by non-players.
- Fixed most NJ magic spells doing more damage than they should.
- Fixed ZenyNage being able to do more damage than zeny you have.
- Cleaned up skill setting code for Suiton and Kaensin
- Ordered SC_* definitions in status.c
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7947 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 71 | ||||
-rw-r--r-- | src/map/pc.c | 2 | ||||
-rw-r--r-- | src/map/skill.c | 127 | ||||
-rw-r--r-- | src/map/status.c | 99 |
4 files changed, 114 insertions, 185 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index 23531c62b..d07123428 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1123,6 +1123,11 @@ static struct Damage battle_calc_weapon_attack( switch (skill_num) { //Calc base damage according to skill + case NJ_ISSEN: + wd.damage = 80*sstatus->str +skill_lv*sstatus->hp*8/100; + wd.damage2 = 0; + status_set_hp(src, 1, 0); + break; case PA_SACRIFICE: skill = sstatus->max_hp* 9/100; status_zap(src, skill, 0);//Damage to self is always 9% @@ -1183,20 +1188,29 @@ static struct Damage battle_calc_weapon_attack( wd.damage2 = hd->master->homunculus.intimacy ; hd->master->homunculus.intimacy = 200; clif_send_homdata(hd->master,0x100,hd->master->homunculus.intimacy/100); + break; } - break; default: { i = (flag.cri?1:0)|(flag.arrow?2:0)|(skill_num == HW_MAGICCRASHER?4:0)|(skill_num == MO_EXTREMITYFIST?8:0); - if ( flag.arrow && sd->status.weapon != W_BOW && sd->status.weapon != W_REVOLVER && sd->status.weapon != W_SHOTGUN - && sd->status.weapon != W_GATLING && sd->status.weapon != W_GRENADE ) i |= 16; // for ex. shuriken must not be influenced by DEX + if (flag.arrow && sd) + switch(sd->status.weapon) { + case W_BOW: + case W_REVOLVER: + case W_SHOTGUN: + case W_GATLING: + case W_GRENADE: + break; + default: + i |= 16; // for ex. shuriken must not be influenced by DEX + } wd.damage = battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i); if (sstatus->lhw) wd.damage2 = battle_calc_base_damage(sstatus, sstatus->lhw, sc, tstatus->size, sd, i); // Added split damage for Huuma - if (skill_num == NJ_HUUMA) // Divide ATK in case of multiple targets skill - { + if (skill_num == NJ_HUUMA) + { // Divide ATK in case of multiple targets skill if(wflag>0) wd.damage/= wflag; else if(battle_config.error_log) @@ -1378,7 +1392,7 @@ static struct Damage battle_calc_weapon_attack( //You'd need something like 6K SP to reach this max, so should be fine for most purposes. if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased. skillratio = (unsigned short)ratio; - status_zap(src, 0, sstatus->sp); + status_set_sp(src, 0, 0); flag.idef= flag.idef2= 1; } break; @@ -1549,6 +1563,9 @@ static struct Damage battle_calc_weapon_attack( ATK_ADD(sstatus->matk_min); } break; + case NJ_SYURIKEN: + ATK_ADD(4*skill_lv); + break; } } //Div fix. @@ -1710,26 +1727,6 @@ static struct Damage battle_calc_weapon_attack( if (flag.rh && wd.damage < 1) wd.damage = 1; if (flag.lh && wd.damage2 < 1) wd.damage2 = 1; - // Added Tobidougu bonus on throwing weapon ninja skills if not wearing a Fuuma shuriken (bonus already added in battle_addmastery) - switch(skill_num) - { - case NJ_SYURIKEN: - if((skill = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0 && sd->status.weapon != W_HUUMA) { wd.damage+=skill*3+skill_lv*4; } - else {wd.damage+=skill_lv*4; } - break; - case NJ_KUNAI: - if((skill = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0 && sd->status.weapon != W_HUUMA) { wd.damage+=skill*3; } - break; - default: - break; - } - - if ( skill_num == NJ_ISSEN ) - { - wd.damage=sstatus->str*80+skill_lv*sstatus->hp*8/100; - status_zap(src, sstatus->hp-1, 0); - } - if (sd && flag.weapon && skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != CR_GRANDCROSS) { //Add mastery damage @@ -1748,6 +1745,11 @@ static struct Damage battle_calc_weapon_attack( skillratio = (sd->status.base_level + sstatus->dex+ sstatus->luk)/(skill<4?12-3*skill:1); ATK_ADDRATE(skillratio); } + // Added Tobidougu bonus on throwing weapon ninja skills if not wearing a Fuuma shuriken (bonus already added in battle_addmastery) + if ((skill_num == NJ_SYURIKEN || skill_num == NJ_KUNAI) && + sd->status.weapon != W_HUUMA && + (skill = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0) + ATK_ADD(3*skill); } } //Here ends flag.hit section, the rest of the function applies to both hitting and missing attacks else if(wd.div_ < 0) //Since the attack missed... @@ -2316,20 +2318,21 @@ struct Damage battle_calc_magic_attack( skillratio -= 10; break; case NJ_BAKUENRYU: - skillratio += 50 + 150*skill_lv; + skillratio += 50*(skill_lv-1); break; case NJ_HYOUSENSOU: skillratio -= 30; - if ( sc->data[SC_SUITON].timer != -1 ) skillratio += skillratio*sc->data[SC_SUITON].val1*2/100; - break; + if (sc && sc->data[SC_SUITON].timer != -1) + skillratio += sc->data[SC_SUITON].val4; + break; case NJ_HYOUSYOURAKU: - skillratio += 100 + 50*skill_lv; + skillratio += 50*skill_lv; break; case NJ_RAIGEKISAI: skillratio += 60 + 40*skill_lv; break; case NJ_KAMAITACHI: - skillratio += 100 + 100*skill_lv; + skillratio += 100*skill_lv; break; } @@ -2510,7 +2513,7 @@ struct Damage battle_calc_misc_attack( switch(skill_num){ case PA_PRESSURE: case GS_FLING: - case NJ_ZENYNAGE: // Throw zeny not affected by cards, elements, race.. + case NJ_ZENYNAGE: flag.elefix = flag.cardfix = 0; case HT_BLITZBEAT: case TF_THROWSTONE: @@ -2595,10 +2598,10 @@ struct Damage battle_calc_misc_attack( if (tsd) md.damage>>=1; break; case NJ_ZENYNAGE: - md.damage = skill_get_zeny(skill_num ,skill_lv); + md.damage = skill_get_zeny(skill_num ,skill_lv)/2; if (!md.damage) md.damage = 2; md.damage = md.damage + rand()%md.damage; - if(is_boss(target)) // deleted || map_flag_vs(target->m) , seemed to reduce damage in PVP mode + if(is_boss(target)) md.damage=md.damage*60/100; break; case GS_FLING: diff --git a/src/map/pc.c b/src/map/pc.c index 5e20aaa4a..5af6a080e 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -3231,7 +3231,7 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in { //Misc map-changing settings party_send_dot_remove(sd); //minimap dot fix [Kevin] guild_send_dot_remove(sd); - skill_clear_group(&sd->bl, 1|(battle_config.traps_setting&2)); + skill_clear_group(&sd->bl, 1|4|(battle_config.traps_setting&2)); if (sd->sc.count) { //Cancel some map related stuff. if (sd->sc.data[SC_WARM].timer != -1) diff --git a/src/map/skill.c b/src/map/skill.c index 683a38e7e..1c09354d2 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2732,11 +2732,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int clif_slide(src,bl->x,bl->y); break; - case SN_SHARPSHOOTING: /* シャープシューティング */ - // Does it stop if touch an obstacle? it shouldn't shoot trough walls - map_foreachinpath (skill_attack_area,src->m,src->x,src->y,bl->x,bl->y, - skill_get_splash(skillid, skilllv),BL_CHAR, - BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); // varargs + case SN_SHARPSHOOTING: + case NJ_KAMAITACHI: + //It won't shoot through walls since on castend there has to be a direct + //line of sight between caster and target. + map_foreachinpath (skill_attack_area,src->m,src->x,src->y,bl->x,bl->y, + skill_get_splash(skillid, skilllv),BL_CHAR, + BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); break; case MO_INVESTIGATE: /* 発勁 */ @@ -2824,6 +2826,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case MC_CARTREVOLUTION: case NPC_SPLASHATTACK: case AC_SHOWER: //Targetted skill implementation. + case NJ_BAKUENRYU: if(flag&1){ if(bl->id!=skill_area_temp[1]){ skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick, @@ -2955,7 +2958,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); break; - /* 魔法系スキル */ case MG_SOULSTRIKE: /* ソウルストライク */ case NPC_DARKSTRIKE: /*闇ソウルストライク*/ case MG_COLDBOLT: /* コールドボルト */ @@ -2971,6 +2973,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case MG_FROSTDIVER: /* フロストダイバー */ case WZ_SIGHTBLASTER: case WZ_SIGHTRASHER: /* サイトラッシャー */ + case NJ_KOUENKA: + case NJ_HYOUSENSOU: + case NJ_HUUJIN: skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); break; @@ -3088,7 +3093,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int skill_attack(BF_MISC, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); } else { skill_area_temp[0] = 0; - skill_area_temp[1] = bl->id; if (flag & 0xf00000) //Warning, 0x100000 is currently BCT_NEUTRAL, so don't mix it when asking for the enemy. [Skotlex] map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR, @@ -3177,39 +3181,19 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int break; case NJ_HUUMA: if (flag & 1) { - if (bl->id != skill_area_temp[1]) - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); + skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); } else { skill_area_temp[0] = 0; - skill_area_temp[1] = bl->id; map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY, skill_area_sub_count); - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); } break; - case NJ_BAKUENRYU: - if (flag & 1) { - skill_attack(BF_MAGIC, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); - } else { - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_area_temp[0] = 0; - skill_area_temp[1] = bl->id; - if (flag & 0xf00000) - map_foreachinrange(skill_area_sub, bl, - skill_get_splash(skillid, skilllv), BL_CHAR, - src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count); - map_foreachinrange(skill_area_sub, bl, - skill_get_splash(skillid, skilllv), BL_CHAR, - src, skillid, skilllv, tick, BCT_ENEMY|1, - skill_castend_damage_id); - } - break; case NJ_KASUMIKIRI: skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); sc_start(src,SC_HIDING,100,skilllv,skill_get_time(skillid,skilllv)); @@ -3218,23 +3202,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int status_change_end(src, SC_HIDING, -1); skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); break; - case NJ_KOUENKA: - case NJ_HYOUSENSOU: - case NJ_HUUJIN: - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); - break; - case NJ_KAMAITACHI: - // Does it stop if touch an obstacle? it shouldn't shoot trough walls - map_foreachinpath (skill_attack_area,src->m,src->x,src->y,bl->x,bl->y, - skill_get_splash(skillid, skilllv),BL_CHAR, - BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); // varargs - break; - //Not implemented yet [Vicious] - //case NJ_KASUMIKIRI: - //case NJ_KIRIKAGE: case NJ_ISSEN: skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - if (sc && sc->data[SC_NEN].timer != -1) status_change_end(src,SC_NEN,-1); break; @@ -6123,7 +6092,6 @@ int skill_castend_pos2 (struct block_list *src, int x, int y, int skillid, int s case DC_SERVICEFORYOU: case GS_DESPERADO: case NJ_SUITON: - case NJ_BAKUENRYU: case NJ_KAENSIN: case NJ_HYOUSYOURAKU: case NJ_RAIGEKISAI: @@ -6596,35 +6564,7 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid, target = BCT_ALL; break; case NJ_SUITON: - val1 = skilllv*2; - - { - // don't call skill_clear_group(src,1), it deletes also kaensin... and I think it doesn't have to - // so this is a copy paste of skill_clear_group() function, which only deletes suiton (shoud maybe create a new function) - struct unit_data *ud = unit_bl2ud(src); - struct skill_unit_group *group[MAX_SKILLUNITGROUP]; - int i, count=0, tflag=1; - - nullpo_retr(0, src); - if (!ud) break; - - for (i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i];i++) - { - switch (ud->skillunit[i]->skill_id) { - case NJ_SUITON: - if (tflag&1) - group[count++]= ud->skillunit[i]; - break; - default: - if (tflag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP) - group[count++]= ud->skillunit[i]; - break; - } - - } - for (i=0;i<count;i++) - skill_delunitgroup(src, group[i]); - } + skill_clear_group(src,1); break; case HT_SHOCKWAVE: /* ショックウェーブトラップ */ val1=skilllv*15+10; @@ -6765,35 +6705,8 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid, if (sd) val1 = sd->status.child; break; case NJ_KAENSIN: - { - // don't call skill_clear_group(src,1), it deletes also suiton... and I think it doesn't have to - // so this is a copy paste of skill_clear_group() function, which only deletes kaesin (shoud maybe create a new function) - struct unit_data *ud = unit_bl2ud(src); - struct skill_unit_group *group[MAX_SKILLUNITGROUP]; - int i, count=0, tflag=1; - - val2 = (skilllv+1)/2 + 4; - - nullpo_retr(0, src); - if (!ud) break; - - for (i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i];i++) - { - switch (ud->skillunit[i]->skill_id) { - case NJ_KAENSIN: - if (tflag&1) - group[count++]= ud->skillunit[i]; - break; - default: - if (tflag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP) - group[count++]= ud->skillunit[i]; - break; - } - - } - for (i=0;i<count;i++) - skill_delunitgroup(src, group[i]); - } + skill_clear_group(src, 4); //Delete previous Kaensins + val2 = (skilllv+1)/2 + 4; break; case GS_GROUNDDRIFT: @@ -7498,7 +7411,6 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int switch (skill_id) { case WZ_QUAGMIRE: - case NJ_SUITON: if (bl->type==BL_MOB) break; if (sc && sc->data[type].timer != -1) @@ -7529,6 +7441,7 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int case SA_VIOLENTGALE: case CG_HERMODE: case HW_GRAVITATION: + case NJ_SUITON: if (sc && sc->data[type].timer != -1) status_change_end(bl, type, -1); break; @@ -8385,7 +8298,8 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t case NJ_ISSEN: if (!sc || sc->data[SC_NEN].timer==-1) { clif_skill_fail(sd,skill,0,0); - return 0; } + return 0; + } break; case NJ_ZENYNAGE: @@ -9281,10 +9195,13 @@ int skill_clear_group (struct block_list *bl, int flag) case SA_VIOLENTGALE: case SA_LANDPROTECTOR: case NJ_SUITON: - case NJ_KAENSIN: if (flag&1) group[count++]= ud->skillunit[i]; break; + case NJ_KAENSIN: + if (flag&4) + group[count++]= ud->skillunit[i]; + break; default: if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP) group[count++]= ud->skillunit[i]; diff --git a/src/map/status.c b/src/map/status.c index a0483f0a9..91141855a 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -348,6 +348,15 @@ void initChangeTables(void) { add_sc(CG_HERMODE, SC_HERMODE); set_sc(SL_HIGH, SC_SPIRIT, SI_SPIRIT, SCB_PC); set_sc(KN_ONEHAND, SC_ONEHAND, SI_ONEHAND, SCB_ASPD); + set_sc(GS_FLING, SC_FLING, SI_BLANK, SCB_DEF|SCB_DEF2); + set_sc(GS_MADNESSCANCEL, SC_MADNESSCANCEL, SI_MADNESSCANCEL, SCB_BATK|SCB_ASPD); + set_sc(GS_ADJUSTMENT, SC_ADJUSTMENT, SI_ADJUSTMENT, SCB_HIT|SCB_FLEE); + set_sc(GS_INCREASING, SC_INCREASING, SI_ACCURACY, SCB_AGI|SCB_DEX|SCB_HIT); + set_sc(GS_GATLINGFEVER, SC_GATLINGFEVER, SI_GATLINGFEVER, SCB_FLEE|SCB_SPEED|SCB_ASPD); + set_sc(NJ_TATAMIGAESHI, SC_TATAMIGAESHI, SI_BLANK, SCB_NONE); + set_sc(NJ_SUITON, SC_SUITON, SI_BLANK, SCB_AGI|SCB_SPEED); + add_sc(NJ_HYOUSYOURAKU, SC_FREEZE); + set_sc(NJ_NEN, SC_NEN, SI_NEN, SCB_STR|SCB_INT); set_sc(CR_SHRINK, SC_SHRINK, SI_SHRINK, SCB_NONE); set_sc(RG_CLOSECONFINE, SC_CLOSECONFINE2, SI_CLOSECONFINE2, SCB_NONE); set_sc(RG_CLOSECONFINE, SC_CLOSECONFINE, SI_CLOSECONFINE, SCB_FLEE); @@ -358,26 +367,13 @@ void initChangeTables(void) { add_sc(SA_ELEMENTFIRE, SC_ELEMENTALCHANGE); add_sc(SA_ELEMENTGROUND, SC_ELEMENTALCHANGE); add_sc(SA_ELEMENTWIND, SC_ELEMENTALCHANGE); - add_sc(NJ_HYOUSYOURAKU, SC_FREEZE); - set_sc(NJ_NEN, SC_NEN, SI_NEN, SCB_STR|SCB_INT); - //Until they're at right position - gs_set_sc- [Vicious] / some of these don't seem to have a status icon adequate [blackhole89] - set_sc(GS_MADNESSCANCEL, SC_MADNESSCANCEL, SI_MADNESSCANCEL, SCB_BATK|SCB_ASPD); - set_sc(GS_ADJUSTMENT, SC_ADJUSTMENT, SI_ADJUSTMENT, SCB_HIT|SCB_FLEE); - set_sc(GS_INCREASING, SC_INCREASING, SI_ACCURACY, SCB_AGI|SCB_DEX|SCB_HIT); - set_sc(GS_GATLINGFEVER, SC_GATLINGFEVER, SI_GATLINGFEVER, SCB_FLEE|SCB_SPEED|SCB_ASPD); - set_sc(GS_FLING, SC_FLING, SI_BLANK, SCB_DEF|SCB_DEF2); - set_sc(NJ_TATAMIGAESHI, SC_TATAMIGAESHI, SI_BLANK, SCB_NONE); - - //Uncomment and update when you plan on implementing. -// set_sc(NJ_UTSUSEMI, SC_UTSUSEMI, SI_MAEMI); - set_sc(NJ_SUITON, SC_SUITON, SI_BLANK, SCB_AGI|SCB_SPEED); set_sc(HLIF_AVOID, SC_AVOID, SI_BLANK, SCB_SPEED); set_sc(HLIF_CHANGE, SC_CHANGE, SI_BLANK, SCB_INT); - set_sc(HAMI_BLOODLUST, SC_BLOODLUST, SI_BLANK, SCB_BATK|SCB_WATK); set_sc(HFLI_FLEET, SC_FLEET, SI_BLANK, SCB_ASPD|SCB_BATK|SCB_WATK); set_sc(HFLI_SPEED, SC_SPEED, SI_BLANK, SCB_FLEE); //[orn] set_sc(HAMI_DEFENCE, SC_DEFENCE, SI_BLANK, SCB_DEF); //[orn] + set_sc(HAMI_BLOODLUST, SC_BLOODLUST, SI_BLANK, SCB_BATK|SCB_WATK); set_sc(GD_LEADERSHIP, SC_GUILDAURA, SI_GUILDAURA, SCB_STR|SCB_AGI|SCB_VIT|SCB_DEX); set_sc(GD_BATTLEORDER, SC_BATTLEORDERS, SI_BATTLEORDERS, SCB_STR|SCB_INT|SCB_DEX); @@ -2971,7 +2967,7 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang agi -= 2 + sc->data[SC_DECREASEAGI].val1; if(sc->data[SC_QUAGMIRE].timer!=-1) agi -= sc->data[SC_QUAGMIRE].val2; - if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val4) + if(sc->data[SC_SUITON].timer!=-1) agi -= sc->data[SC_SUITON].val2; if(sc->data[SC_MARIONETTE].timer!=-1) agi -= (sc->data[SC_MARIONETTE].val3>>8)&0xFF; @@ -3313,7 +3309,7 @@ static signed char status_calc_def(struct block_list *bl, struct status_change * if(sc->data[SC_KEEPING].timer!=-1) return 100; if(sc->data[SC_SKA].timer != -1) - return rand()%100; //Reports indicate SKA actually randomizes defense. + return sc->data[SC_SKA].val3; if (sc->data[SC_DEFENCE].timer != -1) //[orn] def += sc->data[SC_DEFENCE].val2 ; if(sc->data[SC_STEELBODY].timer!=-1) @@ -3455,8 +3451,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha speed = speed * 100/75; if(sc->data[SC_QUAGMIRE].timer!=-1) speed = speed * 100/50; - if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val4) - speed = speed * 100/50; + if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val3) + speed = speed * 100/sc->data[SC_SUITON].val3; if(sc->data[SC_DONTFORGETME].timer!=-1) speed = speed * 100/sc->data[SC_DONTFORGETME].val3; if(sc->data[SC_DEFENDER].timer!=-1) @@ -4766,29 +4762,29 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val val2 = 0; break; case SC_SUITON: - if (status_get_class(bl) != JOB_NINJA) { - if ( bl->type == BL_PC && !map[sd->bl.m].flag.pvp && !map_flag_gvg(sd->bl.m) ) val4=0; - else val4=1; - - switch ((val1+1)/3) { - case 3: - val2 = 8; - break; - case 2: - val2 = 5; - break; - case 1: - val2 = 3; - break; - case 0: - val2 = 0; - break; - default: - val2 = 3*((val1+1)/3); - break; - - } - } else val2 = 0; + val2 = 0; //Agi penalty + val3 = 0; //Walk speed penalty + val4 = 2*val1; //NJ_HYOUSENSOU damage bonus. + if (status_get_class(bl) != JOB_NINJA && !map_flag_vs(bl->m)) { + val3 = 50; + switch ((val1+1)/3) { + case 3: + val2 = 8; + break; + case 2: + val2 = 5; + break; + case 1: + val2 = 3; + break; + case 0: + val2 = 0; + break; + default: + val2 = 3*((val1+1)/3); + break; + } + }; break; case SC_ONEHAND: case SC_TWOHANDQUICKEN: @@ -5388,6 +5384,11 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val val2 = 20*val1; //matk increase. val3 = 12*val1; //mdef2 reduction. break; + case SC_SKA: + val2 = tick/1000; + val3 = rand()%100; //Def changes randomly every second... + tick = 1000; + break; case SC_JAILED: tick = val1>0?1000:250; break; @@ -6080,10 +6081,8 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, int data) hp = status->max_hp - status->hp; if (hp > sc->data[data].val2) hp = sc->data[data].val2; - if (hp) { - status_heal(bl, hp, 0, 0); - clif_skill_nodamage(NULL,bl,AL_HEAL,hp,1); - } + if (hp) + status_heal(bl, hp, 0, 2); sc->data[data].val4=-1; return 1; } @@ -6153,6 +6152,16 @@ int status_change_timer(int tid, unsigned int tick, int id, int data) return 0; break; + case SC_SKA: + if((--sc->data[type].val2)>0){ + sc->data[type].val3 = rand()%100; //Random defense. + sc->data[type].timer=add_timer( + 1000+tick, status_change_timer, + bl->id, data); + return 0; + } + break; + case SC_HIDING: if((--sc->data[type].val2)>0){ |