diff options
Diffstat (limited to 'src/map/skill.c')
-rw-r--r-- | src/map/skill.c | 188 |
1 files changed, 67 insertions, 121 deletions
diff --git a/src/map/skill.c b/src/map/skill.c index 2cd3ff4e6..3de357f22 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1827,11 +1827,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if (attack_type&BF_MAGIC) { if(sc && sc->data[SC_KAITE].timer != -1 && (dmg.damage || dmg.damage2) - && !(sstatus->mode&MD_BOSS) && (sd || status_get_lv(dsrc) <= 80) - ) { //Works on players or mobs with level under 80. - clif_skill_nodamage(bl,bl,SL_KAITE,sc->data[SC_KAITE].val1,1); + && !(sstatus->mode&MD_BOSS) && (src->type == BL_PC || status_get_lv(src) <= 80) ) + { //Works on players or mobs with level under 80. + clif_specialeffect(bl, 438, AREA); if (--sc->data[SC_KAITE].val2 <= 0) status_change_end(bl, SC_KAITE, -1); + clif_skill_nodamage(bl,src,skillid,skilllv,1); bl = src; //Just make the skill attack yourself @.@ sc = status_get_sc(bl); tsd = (bl->type == BL_PC)?(TBL_PC*)bl:NULL; @@ -2010,7 +2011,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if (ud && ud->skilltarget == bl->id) dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, type); else - dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5); //TODO: Check whether it's better to send -1 in skilllv or also send 0 as skillid, maybe even change this to a clif_damage packet? + dmg.dmotion = clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,8,dmg.damage2); // can't know why 8, but it works for all skills... break; } case PA_GOSPEL: //Should look like Holy Cross [Skotlex] @@ -2081,7 +2082,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds //Only knockback if it's still alive, otherwise a "ghost" is left behind. [Skotlex] if (dmg.blewcount > 0 && !status_isdead(bl)) - skill_blown(dsrc,bl,dmg.blewcount); + { + if ( skillid != NJ_TATAMIGAESHI ) skill_blown(dsrc,bl,dmg.blewcount); + else skill_blown(src,bl,dmg.blewcount); + } //Delayed damage must be dealt after the knockback (it needs to know actual position of target) if (dmg.amotion) @@ -2824,40 +2828,39 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int break; //Splash attack skills. + case AS_SPLASHER: + if ( (flag&1) && bl->id != skill_area_temp[1] ) + { + skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, 1); + break; + } case AS_GRIMTOOTH: case MC_CARTREVOLUTION: case NPC_SPLASHATTACK: - case AC_SHOWER: //Targetted skill implementation. + case AC_SHOWER: + case MG_NAPALMBEAT: + case MG_FIREBALL: + case HW_NAPALMVULCAN: + case HT_BLITZBEAT: + case NJ_HUUMA: 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, - 0x0500); - } - } else { - 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|1, - skill_castend_damage_id); - //Skill-attack at the end in case it has knockback. [Skotlex] - skill_attack(skill_get_type(skillid),src,src,bl,skillid,skilllv,tick,0); - } - break; - - case AS_SPLASHER: if (flag & 1) { //Invoked from map_foreachinarea, skill_area_temp[0] holds number of targets to divide damage by. - if (bl->id != skill_area_temp[0]) - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, 1); + skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); } else { - skill_area_temp[0] = bl->id; + if ( skillid == NJ_BAKUENRYU ) clif_skill_nodamage(src,bl,skillid,skilllv,1); + skill_area_temp[0] = 0; + skill_area_temp[1] = bl->id; + if ( (skill_get_nk(skillid)&NK_SPLASHSPLIT) || (skillid==HT_BLITZBEAT && 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, + src, skillid, skilllv, tick, flag|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, + src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, 0); } break; + case SM_MAGNUM: if(flag&1) skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); @@ -3020,56 +3023,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_NAPALMBEAT: - case MG_FIREBALL: - if (flag & 1) { - if (bl->id == skill_area_temp[1]) - break; - if(skillid == MG_FIREBALL) //Store distance. - skill_area_temp[0] = distance_blxy(bl, skill_area_temp[2], skill_area_temp[3]); - skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick, skill_area_temp[0]| 0x0500); - } else { - skill_area_temp[0]=0; - skill_area_temp[1]=bl->id; - switch (skillid) { - case MG_NAPALMBEAT: - map_foreachinrange(skill_area_sub, bl, - skill_get_splash(skillid, skilllv),BL_CHAR, - src,skillid,skilllv,tick,flag|BCT_ENEMY, - skill_area_sub_count); - break; - case MG_FIREBALL: - skill_area_temp[2]=bl->x; - skill_area_temp[3]=bl->y; - break; - } - skill_attack(BF_MAGIC,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 HW_NAPALMVULCAN: // Fixed By SteelViruZ - if (flag & 1) { - if (bl->id != skill_area_temp[1]) - skill_attack(BF_MAGIC, 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_MAGIC, 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 SL_STIN: case SL_STUN: case SL_SMA: @@ -3080,22 +3033,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 HT_BLITZBEAT: - if (flag & 1) { //Invoked from map_foreachinarea, skill_area_temp[0] holds number of targets to divide damage by. - skill_attack(BF_MISC, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); - } else { - skill_area_temp[0] = 0; - 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, - 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 NPC_DARKBREATH: clif_emotion(src,7); @@ -3162,33 +3099,18 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int skill_castend_damage_id); } break; - case NJ_HUUMA: - if (flag & 1) { - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); - } else { - skill_area_temp[0] = 0; - map_foreachinrange(skill_area_sub, bl, - skill_get_splash(skillid, skilllv), BL_CHAR, - src, skillid, skilllv, tick, flag|BCT_ENEMY, - skill_area_sub_count); - 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_KASUMIKIRI: skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); sc_start(src,SC_HIDING,100,skilllv,skill_get_time(skillid,skilllv)); break; case NJ_KIRIKAGE: - status_change_end(src, SC_HIDING, -1); - skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - if (unit_movepos(src, bl->x, bl->y, 0, 0)) - { //FIXME: Why are you sending a packet to LIE about where the character is? - //If you want to place yourself adjacent to the target, do the proper coding..? - int dir = unit_getdir(src); - clif_slide(src,src->x - dirx[dir],src->y - diry[dir]); + { + int dir = map_calc_dir(src,bl->x,bl->y); + status_change_end(src, SC_HIDING, -1); + skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); + if (unit_movepos(src, bl->x - dirx[dir], bl->y - diry[dir], 0, 0)) // fixed... sorry for this o_O + clif_slide(src,bl->x - dirx[dir],bl->y - diry[dir]); } break; case NJ_ISSEN: @@ -4065,6 +3987,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in skill_castend_damage_id); break; + case NJ_HYOUSYOURAKU: + case NJ_RAIGEKISAI: + clif_skill_nodamage(src,bl,skillid,skilllv,1); case WZ_FROSTNOVA: map_foreachinrange(skill_attack_area, src, skill_get_splash(skillid, skilllv), BL_CHAR, @@ -6706,7 +6631,7 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid, if (sd) val1 = sd->status.child; break; case NJ_KAENSIN: - skill_clear_group(src, 4); //Delete previous Kaensins + skill_clear_group(src, 1); //Delete previous Kaensins val2 = (skilllv+1)/2 + 4; break; @@ -7231,6 +7156,17 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns } case UNT_TATAMIGAESHI: + { + struct skill_unit_group *sug; // better name needed :D + + if ( (sug = map_find_skill_unit_oncell(bl,bl->x,bl->y,NJ_TATAMIGAESHI,NULL)->group) != NULL ) + { + if ( DIFF_TICK(gettick(), sug->tick) <= skill_get_time2(sg->skill_id, sg->skill_lv) ) + skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); + } + break; + } + case UNT_DEMONSTRATION: skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); break; @@ -9207,11 +9143,8 @@ int skill_clear_group (struct block_list *bl, int flag) case SA_VIOLENTGALE: case SA_LANDPROTECTOR: case NJ_SUITON: - if (flag&1) - group[count++]= ud->skillunit[i]; - break; case NJ_KAENSIN: - if (flag&4) + if (flag&1) group[count++]= ud->skillunit[i]; break; default: @@ -9322,11 +9255,15 @@ int skill_landprotector (struct block_list *bl, va_list ap) case SA_VOLCANO: case SA_DELUGE: case SA_VIOLENTGALE: + case NJ_SUITON: + case NJ_KAENSIN: switch (unit->group->skill_id) { //These override each other. case SA_VOLCANO: case SA_DELUGE: case SA_VIOLENTGALE: + case NJ_SUITON: + case NJ_KAENSIN: (*alive) = 0; return 1; } @@ -10856,6 +10793,15 @@ void skill_init_unit_layout (void) memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); break; } + case NJ_KAENSIN: + { + static const int dx[] = {-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,}; + static const int dy[] = { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,}; + skill_unit_layout[pos].count = 24; + memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); + memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); + break; + } case NJ_TATAMIGAESHI: { //Level 1 (count 4, cross of 3x3) |