diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-10-16 19:00:03 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-10-16 19:00:03 +0000 |
commit | 68584f714db13e550ae532674fc39a6aeff428dc (patch) | |
tree | 0a2b44b4189ce91417218aa7c281b366d707057d | |
parent | 0a9a02fb7798c957e1493aa20ab5904413d291e6 (diff) | |
download | hercules-68584f714db13e550ae532674fc39a6aeff428dc.tar.gz hercules-68584f714db13e550ae532674fc39a6aeff428dc.tar.bz2 hercules-68584f714db13e550ae532674fc39a6aeff428dc.tar.xz hercules-68584f714db13e550ae532674fc39a6aeff428dc.zip |
* Fixed a copy-paste mistake in disguise code (from r5833)
* Commented out clif_skill_damage2() as it is not used anymore
* Made Venom Splasher a splash attack that distributes damage
* Fixed displaying of several splash skills (see bugreport:238)
- added flag SD_PREAMBLE for skills that need the 'magic' packet (fixes Grimtooth / Cart Revolution displaying out of sync)
- hacked together Venom Splasher's "no animation for central mob"
- hacked in a custom packet to make Dragonfear display semi-correctly
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11491 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r-- | Changelog-Trunk.txt | 8 | ||||
-rw-r--r-- | db/skill_db.txt | 2 | ||||
-rw-r--r-- | src/map/atcommand.c | 3 | ||||
-rw-r--r-- | src/map/battle.c | 26 | ||||
-rw-r--r-- | src/map/battle.h | 2 | ||||
-rw-r--r-- | src/map/clif.c | 19 | ||||
-rw-r--r-- | src/map/clif.h | 17 | ||||
-rw-r--r-- | src/map/skill.c | 184 | ||||
-rw-r--r-- | src/map/skill.h | 12 | ||||
-rw-r--r-- | src/map/status.c | 2 |
10 files changed, 134 insertions, 141 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 4461d63ea..4575582e4 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,14 @@ 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. 2007/10/16 + * Fixed displaying of several splash skills (see bugreport:238) + - added flag SD_PREAMBLE for skills that need the 'magic' packet + (fixes Grimtooth / Cart Revolution displaying out of sync) + - hacked together Venom Splasher's "no animation for central mob" + - hacked in a custom packet to make Dragonfear display semi-correctly + * Made Venom Splasher a splash attack that distributes damage + * Commented out clif_skill_damage2() as it is not used anymore + * Fixed a copy-paste mistake in disguise code (from r5833) [ultramage] * Tweaked the loop in parse_script to better handle when the outer brackets aren't checked. * Fixed a typo in skip_space that stopped skipping characters when it diff --git a/db/skill_db.txt b/db/skill_db.txt index 18e5f86fa..7d18ed5d2 100644 --- a/db/skill_db.txt +++ b/db/skill_db.txt @@ -180,7 +180,7 @@ 138,1,6,16,5,0x1,0,10,1,no,0,0x400,0,weapon,0 //AS_ENCHANTPOISON#Enchant Poison# 139,0,6,4,0,0,0,10,1,no,0,0,0,weapon,0 //AS_POISONREACT#Poison React# 140,2,6,2,5,0x1,0,10,1,no,0,0,0,weapon,0 //AS_VENOMDUST#Venom Dust# -141,1,6,1,-1,0x9,2,10,1,yes,0,0,0,weapon,0 //AS_SPLASHER#Venom Splasher# +141,1,6,1,-1,0xF,2,10,1,yes,0,0,0,weapon,0 //AS_SPLASHER#Venom Splasher# 142,0,6,4,0,0x1,0,1,1,no,0,0x1,0,none,0 //NV_FIRSTAID#First Aid# 143,0,6,4,0,0x1,0,1,1,no,0,0x1,0,none,0 //NV_TRICKDEAD#Act Dead# 144,0,0,0,0,0,0,1,0,no,0,0x1,0,none,0 //SM_MOVINGRECOVERY#Moving HP-Recovery# diff --git a/src/map/atcommand.c b/src/map/atcommand.c index b584c6218..d5a3442e7 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -6522,8 +6522,7 @@ int atcommand_displayskill(const int fd, struct map_session_data* sd, const char } status = status_get_status_data(&sd->bl); tick = gettick(); - clif_skill_damage(&sd->bl,&sd->bl, tick, status->amotion, status->dmotion, - 1, 1, skillnum, skilllv, 5); + clif_skill_damage(&sd->bl,&sd->bl, tick, status->amotion, status->dmotion, 1, 1, skillnum, skilllv, 5); clif_skill_nodamage(&sd->bl, &sd->bl, skillnum, skilllv, 1); clif_skill_poseffect(&sd->bl, skillnum, skilllv, sd->bl.x, sd->bl.y, tick); return 0; diff --git a/src/map/battle.c b/src/map/battle.c index 475787dd1..1d0cbd046 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2432,8 +2432,7 @@ struct Damage battle_calc_magic_attack( /*========================================== * ̑_??[WvZ *------------------------------------------*/ -struct Damage battle_calc_misc_attack( - struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag) +struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag) { int skill; short i, nk; @@ -2495,14 +2494,15 @@ struct Damage battle_calc_misc_attack( if(mflag > 1) //Autocasted Blitz. nk|=NK_SPLASHSPLIT; - if (skill_num == HT_BLITZBEAT) - break; - //Div fix of Blitzbeat - skill = skill_get_num(HT_BLITZBEAT, 5); - damage_div_fix(md.damage, skill); + if (skill_num == SN_FALCONASSAULT) + { + //Div fix of Blitzbeat + skill = skill_get_num(HT_BLITZBEAT, 5); + damage_div_fix(md.damage, skill); - //Falcon Assault Modifier - md.damage=md.damage*(150+70*skill_lv)/100; + //Falcon Assault Modifier + md.damage=md.damage*(150+70*skill_lv)/100; + } break; case TF_THROWSTONE: md.damage=50; @@ -2658,13 +2658,13 @@ struct Damage battle_calc_misc_attack( /*========================================== * _??[WvZꊇ??p *------------------------------------------*/ -struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag) +struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int count) { struct Damage d; switch(attack_type) { - case BF_WEAPON: d = battle_calc_weapon_attack(bl,target,skill_num,skill_lv,flag); break; - case BF_MAGIC: d = battle_calc_magic_attack(bl,target,skill_num,skill_lv,flag); break; - case BF_MISC: d = battle_calc_misc_attack(bl,target,skill_num,skill_lv,flag); break; + case BF_WEAPON: d = battle_calc_weapon_attack(bl,target,skill_num,skill_lv,count); break; + case BF_MAGIC: d = battle_calc_magic_attack(bl,target,skill_num,skill_lv,count); break; + case BF_MISC: d = battle_calc_misc_attack(bl,target,skill_num,skill_lv,count); break; default: if (battle_config.error_log) ShowError("battle_calc_attack: unknown attack type! %d\n",attack_type); diff --git a/src/map/battle.h b/src/map/battle.h index 9bfd9efd3..abd877785 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -23,7 +23,7 @@ struct block_list; // _[WvZ -struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag); +struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int count); int battle_calc_return_damage(struct block_list *bl, int damage, int flag); diff --git a/src/map/clif.c b/src/map/clif.c index d6cb74288..bb5d2a7ec 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3739,7 +3739,7 @@ static int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int da /*========================================== * Sends a 'damage' packet (src performs action on dst) * R 008a <src ID>.l <dst ID>.l <server tick>.l <src speed>.l <dst speed>.l <param1>.w <param2>.w <type>.B <param3>.w - * + * * type=00 damage [param1: total damage, param2: div, param3: assassin dual-wield damage] * type=01 pick up item * type=02 sit down @@ -4318,10 +4318,10 @@ int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype) } /*========================================== - * XLUGtFNg_[W + * skill attack effect and damage + * R 01de <skill ID>.w <src ID>.l <dst ID>.l <tick>.l <src delay>.l <dst delay>.l <damage>.l <skillv>.w <div>.w <type>.B *------------------------------------------*/ -int clif_skill_damage(struct block_list *src,struct block_list *dst, - unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type) +int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type) { unsigned char buf[64]; struct status_change *sc; @@ -4329,7 +4329,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst, nullpo_retr(0, src); nullpo_retr(0, dst); - type = (type>0)?type:skill_get_hit(skill_id); + if( type == 0 ) type = skill_get_hit(skill_id); type = clif_calc_delay(type, ddelay); sc = status_get_sc(dst); @@ -4409,8 +4409,8 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst, /*========================================== * XLUGtFNg_[W *------------------------------------------*/ -int clif_skill_damage2(struct block_list *src,struct block_list *dst, - unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type) +/* +int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type) { unsigned char buf[64]; struct status_change *sc; @@ -4463,6 +4463,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst, //Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex] return clif_calc_walkdelay(dst,ddelay,type,damage,div); } +*/ /*========================================== * x/XLGtFNg @@ -4483,14 +4484,14 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst,int skill_ if (disguised(dst)) { WBUFL(buf,6)=-dst->id; - clif_send(buf,packet_len(0x115),dst,SELF); + clif_send(buf,packet_len(0x11a),dst,SELF); } if(src && disguised(src)) { WBUFL(buf,10)=-src->id; if (disguised(dst)) WBUFL(buf,6)=dst->id; - clif_send(buf,packet_len(0x115),src,SELF); + clif_send(buf,packet_len(0x11a),src,SELF); } return fail; diff --git a/src/map/clif.h b/src/map/clif.h index 40916cb58..d809b854d 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -196,20 +196,13 @@ int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int range); int clif_skillinfoblock(struct map_session_data *sd); int clif_skillup(struct map_session_data *sd,int skill_num); -int clif_skillcasting(struct block_list* bl, - int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int pl, int casttime); +int clif_skillcasting(struct block_list* bl,int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int pl,int casttime); int clif_skillcastcancel(struct block_list* bl); int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype); -int clif_skill_damage(struct block_list *src,struct block_list *dst, - unsigned int tick,int sdelay,int ddelay,int damage,int div, - int skill_id,int skill_lv,int type); -int clif_skill_damage2(struct block_list *src,struct block_list *dst, - unsigned int tick,int sdelay,int ddelay,int damage,int div, - int skill_id,int skill_lv,int type); -int clif_skill_nodamage(struct block_list *src,struct block_list *dst, - int skill_id,int heal,int fail); -int clif_skill_poseffect(struct block_list *src,int skill_id, - int val,int x,int y,int tick); +int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type); +//int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type); +int clif_skill_nodamage(struct block_list *src,struct block_list *dst,int skill_id,int heal,int fail); +int clif_skill_poseffect(struct block_list *src,int skill_id,int val,int x,int y,int tick); int clif_skill_estimation(struct map_session_data *sd,struct block_list *dst); void clif_skill_warppoint(struct map_session_data* sd, int skill_num, int skill_lv, int map1, int map2, int map3, int map4); int clif_skill_memo(struct map_session_data *sd,int flag); diff --git a/src/map/skill.c b/src/map/skill.c index 2e805347e..c1617ab06 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1024,8 +1024,8 @@ struct s_skill_unit_layout* skill_get_unit_layout (int skillid, int skilllv, str *------------------------------------------*/ int skill_additional_effect (struct block_list* src, struct block_list *bl, int skillid, int skilllv, int attack_type, unsigned int tick) { - struct map_session_data *sd=NULL, *dstsd=NULL; - struct mob_data *md=NULL, *dstmd=NULL; + struct map_session_data *sd, *dstsd; + struct mob_data *md, *dstmd; struct status_data *sstatus, *tstatus; struct status_change *sc, *tsc; @@ -1037,29 +1037,16 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int if(skillid < 0) { // remove the debug print when this case is finished - ShowDebug("skill_additional_effect: skillid=%i\ncall: %p %p %i %i %i %i",skillid, - src, bl,skillid,skilllv,attack_type,tick); + ShowDebug("skill_additional_effect: skillid=%i\ncall: %p %p %i %i %i %i",skillid,src,bl,skillid,skilllv,attack_type,tick); return 0; } if(skillid > 0 && skilllv <= 0) return 0; // don't forget auto attacks! - celest - switch (src->type) { - case BL_PC: - sd = (struct map_session_data *)src; - break; - case BL_MOB: - md = (struct mob_data *)src; - break; - } + BL_CAST(BL_PC, src, sd); + BL_CAST(BL_MOB, src, md); + BL_CAST(BL_PC, bl, dstsd); + BL_CAST(BL_MOB, bl, dstmd); - switch (bl->type) { - case BL_PC: - dstsd=(struct map_session_data *)bl; - break; - case BL_MOB: - dstmd=(struct mob_data *)bl; - break; - } sc = status_get_sc(src); tsc = status_get_sc(bl); sstatus = status_get_status_data(src); @@ -1067,10 +1054,9 @@ 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; - if (sc && !sc->count) - sc = NULL; - switch(skillid){ + switch(skillid) + { case 0: // Normal attacks (no skill used) { if(sd) { @@ -1968,7 +1954,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds sc= status_get_sc(bl); if (sc && !sc->count) sc = NULL; //Don't need it. -// Is this check really needed? FrostNova won't hurt you if you step right where the caster is? + // Is this check really needed? FrostNova won't hurt you if you step right where the caster is? if(skillid == WZ_FROSTNOVA && dsrc->x == bl->x && dsrc->y == bl->y) return 0; //Trick Dead protects you from damage, but not from buffs and the like, hence it's placed here. @@ -2151,8 +2137,13 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds } } + // Cart Revolution and Grimtooth need this weirdo dummy packet for the first target to display correctly + if( flag&SD_PREAMBLE ) + clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, -30000, dmg.div_, skillid, skilllv, 6); + //Display damage. - switch(skillid){ + switch( skillid ) + { case PA_GOSPEL: //Should look like Holy Cross [Skotlex] dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, 5); break; @@ -2162,19 +2153,25 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if(src->type==BL_PC) dmg.blewcount = 10; dmg.amotion = 0; //Disable delay or attack will do no damage since source is dead by the time it takes effect. [Skotlex] - + // fall through case KN_AUTOCOUNTER: case NPC_CRITICALSLASH: - case NPC_SPLASHATTACK: case TF_DOUBLE: case GS_CHAINACTION: dmg.dmotion = clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2); break; + + case AS_SPLASHER: + if( flag&SD_ANIMATION ) // the surrounding targets + dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -1, 5); // needs -1 as skill level + else // the central target doesn't display an animation + dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -2, 5); // needs -2(!) as skill level + break; + default: - //Disabling skill animation doesn't works on multi-hit. - dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, - damage, dmg.div_, skillid, flag&SD_LEVEL?-1:skilllv, - (flag&SD_ANIMATION && dmg.div_ < 2?5:type)); + if( flag&SD_ANIMATION && dmg.div_ < 2 ) //Disabling skill animation doesn't works on multi-hit. + type = 5; + dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, flag&SD_LEVEL?-1:skilllv, type); break; } @@ -2316,7 +2313,8 @@ int skill_area_sub (struct block_list *bl, va_list ap) func=va_arg(ap,SkillFunc); if(battle_check_target(src,bl,flag) > 0) - func(src,bl,skill_id,skill_lv,tick,flag); + return func(src,bl,skill_id,skill_lv,tick,flag); + return 0; } @@ -2599,8 +2597,6 @@ static int skill_check_condition_hom (struct homun_data *hd, int skill, int lv, *------------------------------------------*/ int skill_area_sub_count (struct block_list *src, struct block_list *target, int skillid, int skilllv, unsigned int tick, int flag) { - if(skill_area_temp[0] < 0xffff) - skill_area_temp[0]++; return 1; } @@ -2810,8 +2806,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int if (skillid && skill_get_type(skillid) == BF_MAGIC && status_isimmune(bl) == 100) { //GTB makes all targetted magic display miss with a single bolt. - clif_skill_damage(src, bl, tick, status_get_amotion(src), status_get_dmotion(bl), - 0, 1, skillid, skilllv, skill_get_hit(skillid)); + clif_skill_damage(src, bl, tick, status_get_amotion(src), status_get_dmotion(bl), 0, 1, skillid, skilllv, skill_get_hit(skillid)); return 1; } @@ -3085,14 +3080,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int break; //Splash attack skills. - case NPC_PULSESTRIKE: - case NPC_HELLJUDGEMENT: - skill_attack(skill_get_type(skillid), src, src, bl, - skillid, skilllv, tick, skill_area_temp[0]|(flag&SD_LEVEL)); - break; - - case AS_SPLASHER: case AS_GRIMTOOTH: + case AS_SPLASHER: case SM_MAGNUM: case HT_BLITZBEAT: case MC_CARTREVOLUTION: @@ -3108,49 +3097,56 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case GS_DESPERADO: case GS_SPREADATTACK: case NPC_EARTHQUAKE: - if (flag&1) - { //Invoked from map_foreachinarea, skill_area_temp[0] holds number of targets to divide damage by. - if (skill_area_temp[1] != bl->id) - skill_attack(skill_get_type(skillid), src, src, bl, - skillid, skilllv, tick, skill_area_temp[0]|SD_ANIMATION|(flag&SD_LEVEL)); - break; + case NPC_PULSESTRIKE: + case NPC_HELLJUDGEMENT: + if( flag&1 ) + { //Recursive invocation + // skill_area_temp[0] holds number of targets in area + // skill_area_temp[1] holds the id of the original target + // skill_area_temp[2] counts how many targets have already been processed + int sflag = skill_area_temp[0] & 0xFFF; + if( flag&SD_LEVEL ) + sflag |= SD_LEVEL; // -1 will be used in packets instead of the skill level + if( skill_area_temp[1] != bl->id && !(skill_get_inf2(skillid)&INF2_NPC_SKILL) ) + sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills) + if( skill_area_temp[2] == 0 && (skillid == AS_GRIMTOOTH || skillid == MC_CARTREVOLUTION || skillid == NPC_SPLASHATTACK) ) + sflag |= SD_PREAMBLE; // a fake packet will be sent for the first target to be hit + + skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, sflag); + skill_area_temp[2]++; } - if ( skillid == NJ_BAKUENRYU ) - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_area_temp[0] = 0; - skill_area_temp[1] = bl->id; - //SD_LEVEL -> Forced splash damage for Auto Blitz-Beat - if (flag&SD_LEVEL || skill_get_nk(skillid)&NK_SPLASHSPLIT) - map_foreachinrange(skill_area_sub, bl, - skill_get_splash(skillid, skilllv), BL_CHAR, - src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count); - else if (skillid==AS_SPLASHER) //Need split damage anyway. - skill_area_temp[0] = 2; + else + { + if ( skillid == NJ_BAKUENRYU ) + clif_skill_nodamage(src,bl,skillid,skilllv,1); - map_foreachinrange(skill_area_sub, bl, - skill_get_splash(skillid, skilllv), splash_target(src), - src, skillid, skilllv, tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); + skill_area_temp[0] = 0; + skill_area_temp[1] = bl->id; + skill_area_temp[2] = 0; + + // if skill damage should be split among targets, count them + //SD_LEVEL -> Forced splash damage for Auto Blitz-Beat -> count targets + if( flag&SD_LEVEL || skill_get_nk(skillid)&NK_SPLASHSPLIT ) + skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR, src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count); - //Splasher Should do 100% damage on targetted character. - skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, - tick, (skillid == AS_SPLASHER?0:skill_area_temp[0])|(flag&SD_LEVEL)); + // recursive invocation of skill_castend_damage_id() with flag|1 + map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); - if (skillid == SM_MAGNUM) { - //Initiate 10% of your damage becomes fire element. - sc_start4(src,SC_WATK_ELEMENT,100,3,20,0,0,skill_get_time2(skillid, skilllv)); - if (sd) skill_blockpc_start (sd, skillid, skill_get_time(skillid, skilllv)); + //FIXME: move this to skill_additional_effect or some such? [ultramage] + if (skillid == SM_MAGNUM) { + //Initiate 10% of your damage becomes fire element. + sc_start4(src,SC_WATK_ELEMENT,100,3,20,0,0,skill_get_time2(skillid, skilllv)); + if (sd) skill_blockpc_start (sd, skillid, skill_get_time(skillid, skilllv)); + } } break; case KN_BRANDISHSPEAR: //Coded apart for it needs the flag passed to the damage calculation. if (skill_area_temp[1] != bl->id) - skill_attack(skill_get_type(skillid), src, src, bl, - skillid, skilllv, tick, flag|SD_ANIMATION); + skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag|SD_ANIMATION); else - skill_attack(skill_get_type(skillid), src, src, bl, - skillid, skilllv, tick, flag); + skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag); break; case KN_BOWLINGBASH: @@ -3167,16 +3163,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int for(i=0;i<c;i++){ if (!skill_blown(src,bl,1,(unit_getdir(src)+4)%8,0x1)) break; //Can't knockback - 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); - if(skill_area_temp[0]>1) break; // collision + skill_area_temp[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); + if( skill_area_temp[0] > 1 ) break; // collision } clif_blown(bl); //Update target pos. if (i!=c) { //Splash - skill_area_temp[1]=bl->id; - map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), - src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); + skill_area_temp[1] = bl->id; + map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); } //Weirdo dual-hit property, two attacks for 500% skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0); @@ -3871,8 +3864,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in skill_area_temp[1] = 0; map_foreachinrange(skill_area_sub, src, skill_get_splash(skillid, skilllv), splash_target(src), src,skillid,skilllv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id); - //Initiate 10% of your damage becomes fire element. clif_skill_nodamage (src,src,skillid,skilllv,1); + //Initiate 10% of your damage becomes fire element. sc_start4(src,SC_WATK_ELEMENT,100,3,20,0,0,skill_get_time2(skillid, skilllv)); if (sd) skill_blockpc_start (sd, skillid, skill_get_time(skillid, skilllv)); break; @@ -4173,23 +4166,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in status_change_end(src, SC_HIDING, -1); break; - case NPC_EARTHQUAKE: case ASC_METEORASSAULT: case GS_SPREADATTACK: - skill_area_temp[0] = 0; - if (skill_get_nk(skillid)&NK_SPLASHSPLIT) - map_foreachinrange(skill_area_sub, bl, - skill_get_splash(skillid, skilllv), BL_CHAR, - src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count); + case NPC_EARTHQUAKE: clif_skill_nodamage(src,bl,skillid,skilllv,1); case NPC_HELLJUDGEMENT: case NPC_PULSESTRIKE: - skill_area_temp[1] = bl->id; - //Mob casted skills should also hit skills. - map_foreachinrange(skill_area_sub, bl, - skill_get_splash(skillid, skilllv), splash_target(src), - src,skillid,skilllv,tick, flag|BCT_ENEMY|1, - skill_castend_damage_id); + skill_castend_damage_id(src, src, skillid, skilllv, tick, flag); break; case KN_BRANDISHSPEAR: @@ -5722,13 +5705,22 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if (hd) skill_blockmerc_start(hd, skillid, skill_get_time2(skillid,skilllv)); break; + case NPC_DRAGONFEAR: if (flag&1) { const int sc[] = { SC_STUN, SC_CURSE, SC_SILENCE, SC_BLEEDING }; i = rand()%ARRAYLENGTH(sc); sc_start(bl,sc[i],100,skilllv,skill_get_time2(skillid,i+1)); - break; + } else { + // hacked-together packet (not correct) that shows the animation + clif_skill_damage(src, src, tick, 1, 1, -1, 0, skillid, skilllv, 6); + map_foreachinrange(skill_area_sub, bl, + skill_get_splash(skillid, skilllv),BL_CHAR, + src,skillid,skilllv,tick, flag|BCT_ENEMY|1, + skill_castend_nodamage_id); } + break; + case NPC_WIDEBLEEDING: case NPC_WIDECONFUSE: case NPC_WIDECURSE: diff --git a/src/map/skill.h b/src/map/skill.h index 1025e4aea..7c7cce429 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -53,9 +53,10 @@ //Walk intervals at which chase-skills are attempted to be triggered. #define WALK_SKILL_INTERVAL 5 -// To be passed to skill_attack, whether the skill damage should disable level or animation. [Skotlex] -#define SD_LEVEL 0x1000 -#define SD_ANIMATION 0x2000 +// Flags passed to skill_attack +#define SD_LEVEL 0x1000 // will send -1 instead of skill level (affects display of some skills) +#define SD_ANIMATION 0x2000 // will use '5' instead of the skill's 'type' (this makes skills show an animation) +#define SD_PREAMBLE 0x4000 // will transmit a 'magic' damage packet (-30000 dmg) for the first target to be hit // XLf?^x?X struct s_skill_db { @@ -267,8 +268,7 @@ int skill_blockpc_start (struct map_session_data*,int,int); // [celest] int skill_blockmerc_start (struct homun_data*,int,int); //[orn] // XLU?ꊇ? -int skill_attack( int attack_type, struct block_list* src, struct block_list *dsrc, - struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); +int skill_attack( int attack_type, struct block_list* src, struct block_list *dsrc,struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag ); void skill_reload(void); @@ -289,7 +289,7 @@ enum { ST_WATER, }; -enum _skill { +enum s_skill { NV_BASIC = 1, SM_SWORD, diff --git a/src/map/status.c b/src/map/status.c index 64d6ab28c..c0d81950a 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -6296,7 +6296,7 @@ int status_change_end( struct block_list* bl , int type,int tid ) { struct block_list *src=map_id2bl(sc->data[type].val3); if(src && tid!=-1) - skill_castend_damage_id(src, bl,sc->data[type].val2,sc->data[type].val1,gettick(),0 ); + skill_castend_damage_id(src, bl, sc->data[type].val2, sc->data[type].val1, gettick(), SD_LEVEL ); } break; case SC_CLOSECONFINE2: |