- 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://svn.code.sf.net/p/rathena/svn/trunk@7947 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-07-28 15:11:17 +00:00
parent 1d754d8cd8
commit 7cdbea9cf2
7 changed files with 122 additions and 187 deletions

View File

@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/07/28 2006/07/28
* Cleaned up the NJ update code: [Skotlex]
- 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
* Some cleaning of battle_drain, Evil Druid card should work now. [Skotlex] * Some cleaning of battle_drain, Evil Druid card should work now. [Skotlex]
* Made status_damage allow damaging of objects not on a map, this should * Made status_damage allow damaging of objects not on a map, this should
fix pet-catching making the mob never respawn again. [Skotlex] fix pet-catching making the mob never respawn again. [Skotlex]

View File

@ -557,7 +557,7 @@
533,0,0,0,0,0,0,10,0,no,0,0,0,none,0 //NJ_NINPOU#NJ_NINPOU# 533,0,0,0,0,0,0,10,0,no,0,0,0,none,0 //NJ_NINPOU#NJ_NINPOU#
534,9,8,1,3,0,0,10,1:2:3:4:5:6:7:8:9:10,yes,0,0,0,magic,0 //NJ_KOUENKA#NJ_KOUENKA# 534,9,8,1,3,0,0,10,1:2:3:4:5:6:7:8:9:10,yes,0,0,0,magic,0 //NJ_KOUENKA#NJ_KOUENKA#
535,0,8,4,3,0,0,10,1,yes,0,0,0,magic,0 //NJ_KAENSIN#NJ_KAENSIN# 535,0,8,4,3,0,0,10,1,yes,0,0,0,magic,0 //NJ_KAENSIN#NJ_KAENSIN#
536,9,8,1,3,2,1,5,-3,yes,0,0,0,magic,0 //NJ_BAKUENRYU#NJ_BAKUENRYU# 536,9,8,1,3,2,1,5,3,yes,0,0,0,magic,0 //NJ_BAKUENRYU#NJ_BAKUENRYU#
537,9,8,1,1,0,0,10,3:4:5:6:7:8:9:10:11:12,yes,0,0,0,magic,0 //NJ_HYOUSENSOU#NJ_HYOUSENSOU# 537,9,8,1,1,0,0,10,3:4:5:6:7:8:9:10:11:12,yes,0,0,0,magic,0 //NJ_HYOUSENSOU#NJ_HYOUSENSOU#
538,9,6,2,0,1,0,10,1,yes,0,0,0,magic,0 //NJ_SUITON#NJ_SUITON# 538,9,6,2,0,1,0,10,1,yes,0,0,0,magic,0 //NJ_SUITON#NJ_SUITON#
539,0,6,4,1,1,0,5,1,yes,0,0,0,magic,0 //NJ_HYOUSYOURAKU#NJ_HYOUSYOURAKU# 539,0,6,4,1,1,0,5,1,yes,0,0,0,magic,0 //NJ_HYOUSYOURAKU#NJ_HYOUSYOURAKU#

View File

@ -416,7 +416,7 @@
523,0,0,2,0,0,0,99,6,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_SYURIKEN 523,0,0,2,0,0,0,99,6,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_SYURIKEN
524,0,0,30:25:20:15:10,0,0,0,99,7,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_KUNAI 524,0,0,30:25:20:15:10,0,0,0,99,7,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_KUNAI
525,0,0,20:25:30:35:40,0,0,0,22,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_HUUMA 525,0,0,20:25:30:35:40,0,0,0,22,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_HUUMA
526,0,0,50,0,0,500:1000:1500:2000:2500:3000:3500:4000:4500:5000,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_ZENYNAGE 526,0,0,50,0,0,1000:2000:3000:4000:5000:6000:7000:8000:9000:10000,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_ZENYNAGE
527,0,0,40,0,0,0,0,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_TATAMIGAESHI 527,0,0,40,0,0,0,0,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_TATAMIGAESHI
528,0,0,10:12:14:16:18:20:22:24:26:28,0,0,0,0,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_KASUMIKIRI 528,0,0,10:12:14:16:18:20:22:24:26:28,0,0,0,0,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_KASUMIKIRI
529,0,0,40,0,0,0,0,0,0,hiding,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_SHADOWJUMP 529,0,0,40,0,0,0,0,0,0,hiding,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NJ_SHADOWJUMP

View File

@ -1123,6 +1123,11 @@ static struct Damage battle_calc_weapon_attack(
switch (skill_num) switch (skill_num)
{ //Calc base damage according to skill { //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: case PA_SACRIFICE:
skill = sstatus->max_hp* 9/100; skill = sstatus->max_hp* 9/100;
status_zap(src, skill, 0);//Damage to self is always 9% 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 ; wd.damage2 = hd->master->homunculus.intimacy ;
hd->master->homunculus.intimacy = 200; hd->master->homunculus.intimacy = 200;
clif_send_homdata(hd->master,0x100,hd->master->homunculus.intimacy/100); clif_send_homdata(hd->master,0x100,hd->master->homunculus.intimacy/100);
break;
} }
break;
default: default:
{ {
i = (flag.cri?1:0)|(flag.arrow?2:0)|(skill_num == HW_MAGICCRASHER?4:0)|(skill_num == MO_EXTREMITYFIST?8:0); 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 if (flag.arrow && sd)
&& sd->status.weapon != W_GATLING && sd->status.weapon != W_GRENADE ) i |= 16; // for ex. shuriken must not be influenced by DEX 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); wd.damage = battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i);
if (sstatus->lhw) if (sstatus->lhw)
wd.damage2 = battle_calc_base_damage(sstatus, sstatus->lhw, sc, tstatus->size, sd, i); wd.damage2 = battle_calc_base_damage(sstatus, sstatus->lhw, sc, tstatus->size, sd, i);
// Added split damage for Huuma // 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) if(wflag>0)
wd.damage/= wflag; wd.damage/= wflag;
else if(battle_config.error_log) 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. //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. if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased.
skillratio = (unsigned short)ratio; skillratio = (unsigned short)ratio;
status_zap(src, 0, sstatus->sp); status_set_sp(src, 0, 0);
flag.idef= flag.idef2= 1; flag.idef= flag.idef2= 1;
} }
break; break;
@ -1549,6 +1563,9 @@ static struct Damage battle_calc_weapon_attack(
ATK_ADD(sstatus->matk_min); ATK_ADD(sstatus->matk_min);
} }
break; break;
case NJ_SYURIKEN:
ATK_ADD(4*skill_lv);
break;
} }
} }
//Div fix. //Div fix.
@ -1710,26 +1727,6 @@ static struct Damage battle_calc_weapon_attack(
if (flag.rh && wd.damage < 1) wd.damage = 1; if (flag.rh && wd.damage < 1) wd.damage = 1;
if (flag.lh && wd.damage2 < 1) wd.damage2 = 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 if (sd && flag.weapon && skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST
&& skill_num != CR_GRANDCROSS) && skill_num != CR_GRANDCROSS)
{ //Add mastery damage { //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); skillratio = (sd->status.base_level + sstatus->dex+ sstatus->luk)/(skill<4?12-3*skill:1);
ATK_ADDRATE(skillratio); 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 } //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... else if(wd.div_ < 0) //Since the attack missed...
@ -2316,20 +2318,21 @@ struct Damage battle_calc_magic_attack(
skillratio -= 10; skillratio -= 10;
break; break;
case NJ_BAKUENRYU: case NJ_BAKUENRYU:
skillratio += 50 + 150*skill_lv; skillratio += 50*(skill_lv-1);
break; break;
case NJ_HYOUSENSOU: case NJ_HYOUSENSOU:
skillratio -= 30; skillratio -= 30;
if ( sc->data[SC_SUITON].timer != -1 ) skillratio += skillratio*sc->data[SC_SUITON].val1*2/100; if (sc && sc->data[SC_SUITON].timer != -1)
break; skillratio += sc->data[SC_SUITON].val4;
break;
case NJ_HYOUSYOURAKU: case NJ_HYOUSYOURAKU:
skillratio += 100 + 50*skill_lv; skillratio += 50*skill_lv;
break; break;
case NJ_RAIGEKISAI: case NJ_RAIGEKISAI:
skillratio += 60 + 40*skill_lv; skillratio += 60 + 40*skill_lv;
break; break;
case NJ_KAMAITACHI: case NJ_KAMAITACHI:
skillratio += 100 + 100*skill_lv; skillratio += 100*skill_lv;
break; break;
} }
@ -2510,7 +2513,7 @@ struct Damage battle_calc_misc_attack(
switch(skill_num){ switch(skill_num){
case PA_PRESSURE: case PA_PRESSURE:
case GS_FLING: case GS_FLING:
case NJ_ZENYNAGE: // Throw zeny not affected by cards, elements, race.. case NJ_ZENYNAGE:
flag.elefix = flag.cardfix = 0; flag.elefix = flag.cardfix = 0;
case HT_BLITZBEAT: case HT_BLITZBEAT:
case TF_THROWSTONE: case TF_THROWSTONE:
@ -2595,10 +2598,10 @@ struct Damage battle_calc_misc_attack(
if (tsd) md.damage>>=1; if (tsd) md.damage>>=1;
break; break;
case NJ_ZENYNAGE: 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; if (!md.damage) md.damage = 2;
md.damage = md.damage + rand()%md.damage; 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; md.damage=md.damage*60/100;
break; break;
case GS_FLING: case GS_FLING:

View File

@ -3231,7 +3231,7 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
{ //Misc map-changing settings { //Misc map-changing settings
party_send_dot_remove(sd); //minimap dot fix [Kevin] party_send_dot_remove(sd); //minimap dot fix [Kevin]
guild_send_dot_remove(sd); 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) if (sd->sc.count)
{ //Cancel some map related stuff. { //Cancel some map related stuff.
if (sd->sc.data[SC_WARM].timer != -1) if (sd->sc.data[SC_WARM].timer != -1)

View File

@ -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); clif_slide(src,bl->x,bl->y);
break; break;
case SN_SHARPSHOOTING: /* シャープシューティング */ case SN_SHARPSHOOTING:
// Does it stop if touch an obstacle? it shouldn't shoot trough walls case NJ_KAMAITACHI:
map_foreachinpath (skill_attack_area,src->m,src->x,src->y,bl->x,bl->y, //It won't shoot through walls since on castend there has to be a direct
skill_get_splash(skillid, skilllv),BL_CHAR, //line of sight between caster and target.
BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); // varargs 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; break;
case MO_INVESTIGATE: /* 発勁 */ 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 MC_CARTREVOLUTION:
case NPC_SPLASHATTACK: case NPC_SPLASHATTACK:
case AC_SHOWER: //Targetted skill implementation. case AC_SHOWER: //Targetted skill implementation.
case NJ_BAKUENRYU:
if(flag&1){ if(flag&1){
if(bl->id!=skill_area_temp[1]){ if(bl->id!=skill_area_temp[1]){
skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick, 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); skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
break; break;
/* 魔法系スキル */
case MG_SOULSTRIKE: /* ソウルストライク */ case MG_SOULSTRIKE: /* ソウルストライク */
case NPC_DARKSTRIKE: /*闇ソウルストライク*/ case NPC_DARKSTRIKE: /*闇ソウルストライク*/
case MG_COLDBOLT: /* コールドボルト */ 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 MG_FROSTDIVER: /* フロストダイバー */
case WZ_SIGHTBLASTER: case WZ_SIGHTBLASTER:
case WZ_SIGHTRASHER: /* サイトラッシャー */ case WZ_SIGHTRASHER: /* サイトラッシャー */
case NJ_KOUENKA:
case NJ_HYOUSENSOU:
case NJ_HUUJIN:
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
break; 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]); skill_attack(BF_MISC, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]);
} else { } else {
skill_area_temp[0] = 0; 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] 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, map_foreachinrange(skill_area_sub, bl,
skill_get_splash(skillid, skilllv), BL_CHAR, 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; break;
case NJ_HUUMA: case NJ_HUUMA:
if (flag & 1) { 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 { } else {
skill_area_temp[0] = 0; skill_area_temp[0] = 0;
skill_area_temp[1] = bl->id;
map_foreachinrange(skill_area_sub, bl, map_foreachinrange(skill_area_sub, bl,
skill_get_splash(skillid, skilllv), BL_CHAR, skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, flag|BCT_ENEMY, src, skillid, skilllv, tick, flag|BCT_ENEMY,
skill_area_sub_count); skill_area_sub_count);
skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]);
map_foreachinrange(skill_area_sub, bl, map_foreachinrange(skill_area_sub, bl,
skill_get_splash(skillid, skilllv), BL_CHAR, skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, flag|BCT_ENEMY|1, src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
skill_castend_damage_id); skill_castend_damage_id);
} }
break; 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: case NJ_KASUMIKIRI:
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
sc_start(src,SC_HIDING,100,skilllv,skill_get_time(skillid,skilllv)); 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); status_change_end(src, SC_HIDING, -1);
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
break; 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: case NJ_ISSEN:
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
if (sc && sc->data[SC_NEN].timer != -1) if (sc && sc->data[SC_NEN].timer != -1)
status_change_end(src,SC_NEN,-1); status_change_end(src,SC_NEN,-1);
break; 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 DC_SERVICEFORYOU:
case GS_DESPERADO: case GS_DESPERADO:
case NJ_SUITON: case NJ_SUITON:
case NJ_BAKUENRYU:
case NJ_KAENSIN: case NJ_KAENSIN:
case NJ_HYOUSYOURAKU: case NJ_HYOUSYOURAKU:
case NJ_RAIGEKISAI: case NJ_RAIGEKISAI:
@ -6596,35 +6564,7 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid,
target = BCT_ALL; target = BCT_ALL;
break; break;
case NJ_SUITON: case NJ_SUITON:
val1 = skilllv*2; skill_clear_group(src,1);
{
// 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]);
}
break; break;
case HT_SHOCKWAVE: /* ショックウェーブトラップ */ case HT_SHOCKWAVE: /* ショックウェーブトラップ */
val1=skilllv*15+10; 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; if (sd) val1 = sd->status.child;
break; break;
case NJ_KAENSIN: case NJ_KAENSIN:
{ skill_clear_group(src, 4); //Delete previous Kaensins
// don't call skill_clear_group(src,1), it deletes also suiton... and I think it doesn't have to val2 = (skilllv+1)/2 + 4;
// 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]);
}
break; break;
case GS_GROUNDDRIFT: case GS_GROUNDDRIFT:
@ -7498,7 +7411,6 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
switch (skill_id) switch (skill_id)
{ {
case WZ_QUAGMIRE: case WZ_QUAGMIRE:
case NJ_SUITON:
if (bl->type==BL_MOB) if (bl->type==BL_MOB)
break; break;
if (sc && sc->data[type].timer != -1) 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 SA_VIOLENTGALE:
case CG_HERMODE: case CG_HERMODE:
case HW_GRAVITATION: case HW_GRAVITATION:
case NJ_SUITON:
if (sc && sc->data[type].timer != -1) if (sc && sc->data[type].timer != -1)
status_change_end(bl, type, -1); status_change_end(bl, type, -1);
break; break;
@ -8385,7 +8298,8 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t
case NJ_ISSEN: case NJ_ISSEN:
if (!sc || sc->data[SC_NEN].timer==-1) { if (!sc || sc->data[SC_NEN].timer==-1) {
clif_skill_fail(sd,skill,0,0); clif_skill_fail(sd,skill,0,0);
return 0; } return 0;
}
break; break;
case NJ_ZENYNAGE: case NJ_ZENYNAGE:
@ -9281,10 +9195,13 @@ int skill_clear_group (struct block_list *bl, int flag)
case SA_VIOLENTGALE: case SA_VIOLENTGALE:
case SA_LANDPROTECTOR: case SA_LANDPROTECTOR:
case NJ_SUITON: case NJ_SUITON:
case NJ_KAENSIN:
if (flag&1) if (flag&1)
group[count++]= ud->skillunit[i]; group[count++]= ud->skillunit[i];
break; break;
case NJ_KAENSIN:
if (flag&4)
group[count++]= ud->skillunit[i];
break;
default: default:
if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP) if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP)
group[count++]= ud->skillunit[i]; group[count++]= ud->skillunit[i];

View File

@ -348,6 +348,15 @@ void initChangeTables(void) {
add_sc(CG_HERMODE, SC_HERMODE); add_sc(CG_HERMODE, SC_HERMODE);
set_sc(SL_HIGH, SC_SPIRIT, SI_SPIRIT, SCB_PC); set_sc(SL_HIGH, SC_SPIRIT, SI_SPIRIT, SCB_PC);
set_sc(KN_ONEHAND, SC_ONEHAND, SI_ONEHAND, SCB_ASPD); 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(CR_SHRINK, SC_SHRINK, SI_SHRINK, SCB_NONE);
set_sc(RG_CLOSECONFINE, SC_CLOSECONFINE2, SI_CLOSECONFINE2, SCB_NONE); set_sc(RG_CLOSECONFINE, SC_CLOSECONFINE2, SI_CLOSECONFINE2, SCB_NONE);
set_sc(RG_CLOSECONFINE, SC_CLOSECONFINE, SI_CLOSECONFINE, SCB_FLEE); 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_ELEMENTFIRE, SC_ELEMENTALCHANGE);
add_sc(SA_ELEMENTGROUND, SC_ELEMENTALCHANGE); add_sc(SA_ELEMENTGROUND, SC_ELEMENTALCHANGE);
add_sc(SA_ELEMENTWIND, 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_AVOID, SC_AVOID, SI_BLANK, SCB_SPEED);
set_sc(HLIF_CHANGE, SC_CHANGE, SI_BLANK, SCB_INT); 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_FLEET, SC_FLEET, SI_BLANK, SCB_ASPD|SCB_BATK|SCB_WATK);
set_sc(HFLI_SPEED, SC_SPEED, SI_BLANK, SCB_FLEE); //[orn] 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_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_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); 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; agi -= 2 + sc->data[SC_DECREASEAGI].val1;
if(sc->data[SC_QUAGMIRE].timer!=-1) if(sc->data[SC_QUAGMIRE].timer!=-1)
agi -= sc->data[SC_QUAGMIRE].val2; 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; agi -= sc->data[SC_SUITON].val2;
if(sc->data[SC_MARIONETTE].timer!=-1) if(sc->data[SC_MARIONETTE].timer!=-1)
agi -= (sc->data[SC_MARIONETTE].val3>>8)&0xFF; 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) if(sc->data[SC_KEEPING].timer!=-1)
return 100; return 100;
if(sc->data[SC_SKA].timer != -1) 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] if (sc->data[SC_DEFENCE].timer != -1) //[orn]
def += sc->data[SC_DEFENCE].val2 ; def += sc->data[SC_DEFENCE].val2 ;
if(sc->data[SC_STEELBODY].timer!=-1) 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; speed = speed * 100/75;
if(sc->data[SC_QUAGMIRE].timer!=-1) if(sc->data[SC_QUAGMIRE].timer!=-1)
speed = speed * 100/50; speed = speed * 100/50;
if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val4) if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val3)
speed = speed * 100/50; speed = speed * 100/sc->data[SC_SUITON].val3;
if(sc->data[SC_DONTFORGETME].timer!=-1) if(sc->data[SC_DONTFORGETME].timer!=-1)
speed = speed * 100/sc->data[SC_DONTFORGETME].val3; speed = speed * 100/sc->data[SC_DONTFORGETME].val3;
if(sc->data[SC_DEFENDER].timer!=-1) 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; val2 = 0;
break; break;
case SC_SUITON: case SC_SUITON:
if (status_get_class(bl) != JOB_NINJA) { val2 = 0; //Agi penalty
if ( bl->type == BL_PC && !map[sd->bl.m].flag.pvp && !map_flag_gvg(sd->bl.m) ) val4=0; val3 = 0; //Walk speed penalty
else val4=1; val4 = 2*val1; //NJ_HYOUSENSOU damage bonus.
if (status_get_class(bl) != JOB_NINJA && !map_flag_vs(bl->m)) {
switch ((val1+1)/3) { val3 = 50;
case 3: switch ((val1+1)/3) {
val2 = 8; case 3:
break; val2 = 8;
case 2: break;
val2 = 5; case 2:
break; val2 = 5;
case 1: break;
val2 = 3; case 1:
break; val2 = 3;
case 0: break;
val2 = 0; case 0:
break; val2 = 0;
default: break;
val2 = 3*((val1+1)/3); default:
break; val2 = 3*((val1+1)/3);
break;
} }
} else val2 = 0; };
break; break;
case SC_ONEHAND: case SC_ONEHAND:
case SC_TWOHANDQUICKEN: 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. val2 = 20*val1; //matk increase.
val3 = 12*val1; //mdef2 reduction. val3 = 12*val1; //mdef2 reduction.
break; break;
case SC_SKA:
val2 = tick/1000;
val3 = rand()%100; //Def changes randomly every second...
tick = 1000;
break;
case SC_JAILED: case SC_JAILED:
tick = val1>0?1000:250; tick = val1>0?1000:250;
break; break;
@ -6080,10 +6081,8 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, int data)
hp = status->max_hp - status->hp; hp = status->max_hp - status->hp;
if (hp > sc->data[data].val2) if (hp > sc->data[data].val2)
hp = sc->data[data].val2; hp = sc->data[data].val2;
if (hp) { if (hp)
status_heal(bl, hp, 0, 0); status_heal(bl, hp, 0, 2);
clif_skill_nodamage(NULL,bl,AL_HEAL,hp,1);
}
sc->data[data].val4=-1; sc->data[data].val4=-1;
return 1; return 1;
} }
@ -6153,6 +6152,16 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
return 0; return 0;
break; 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: case SC_HIDING:
if((--sc->data[type].val2)>0){ if((--sc->data[type].val2)>0){