From c7c7cf8234180753db71c3da91e6bb3a2dd44593 Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 7 Mar 2006 21:31:01 +0000 Subject: - Added a check that forces self skills to cast on yourself in skill_use_id - Skills with INF_SELF_SKILL + INF2_NO_TARGET_SELF are now "combo" skills in the sense they auto-select your attack target, and do not stop your attacking animation. Attackable time by default is adjusted by amotion. - Gospel won't start taking effect until after 10 secs have passed. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5501 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 10 +++++++++ db/skill_db.txt | 19 ++++++++-------- src/map/clif.c | 6 +++++- src/map/skill.c | 62 ++++++++++++++--------------------------------------- src/map/skill.h | 2 +- 5 files changed, 41 insertions(+), 58 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 8b426f46b..382eb9270 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -5,6 +5,16 @@ 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/03/07 + * Gospel won't start taking effect until after 10 secs have passed since + invocation. [Skotlex] + * Now if a skill has inf set to 4 (self skill) and inf2 512 (cannot target + self) this skill becomes a target-auto-select skill, which targets your + current attack target, and won't stop your current attack. The current + attack is delayed by your aspd (except for a few skills such as the monk + combo skills which readjust this delay). All Monk combo skills plus Taekwon + kick skills have been updated to use this. [Skotlex] + * Added a check that forces self skills (inf = 4) to select yourself as + target to prevent oddities from crafted packets. [Skotlex] * More ground work for Ninja/Gunslinger [Vicious] * status_calc_pc now assumes that if your max hp is negative, it has overflowed, and as such, it is set to the max_hp setting instead of 1. This diff --git a/db/skill_db.txt b/db/skill_db.txt index b15f7c153..10fdf38d1 100644 --- a/db/skill_db.txt +++ b/db/skill_db.txt @@ -13,7 +13,7 @@ // 12 inf2 (skill information 2) (1- quest skill, 2- npc skill, 4- wedding skill // 8- spirit skill, 16- guild skill, 32- song/dance, 64- ensemble skill // 128- trap (can be targetted), 256- skill that damages/targets yourself -// 512- skill that cannot be casted on self +// 512- cannot be casted on self (if inf = 4, auto-select target skill) // 1024- usable only on party-members, 2048- usable only on guild-mates) // 13 maxcount: max amount of skill instances to place on the ground when // player_land_skill_limit/monster_land_skill_limit is enabled. @@ -289,9 +289,8 @@ 268,0,6,4,0,1,0,5,1,no,0,0,0,weapon,0 //MO_STEELBODY#Mental Strength# 269,0,6,4,0,1,0,5,1,no,0,0,0,weapon,0 //MO_BLADESTOP#Root# 270,0,6,4,0,1,0,5,0,no,0,0,0,weapon,0 //MO_EXPLOSIONSPIRITS#Fury# -271,-2,6,4,0,0,0,5,1,yes,0,0,0,weapon,0 //MO_EXTREMITYFIST#Asura Strike# -272,-2,8,4,-1,0,0,5,4,no,0,0,0,weapon,0 //MO_CHAINCOMBO#Raging Quadruple Blow# -273,-2,6,4,-1,2,2,5,1,no,0,0,0,weapon,0 //MO_COMBOFINISH#Raging Thrust# +271,-2,6,4,0,0,0,5,1,yes,0,512,0,weapon,0 //MO_EXTREMITYFIST#Asura Strike# +272,-2,8,4,-1,0,0,5,4,no,0,512,0,weapon,0 //MO_CHAINCOMBO#Raging Quadruple Blow#273,-2,6,4,-1,2,2,5,1,no,0,512,0,weapon,0 //MO_COMBOFINISH#Raging Thrust# 274,0,0,0,0,0,0,10,0,no,0,0,0,weapon,0 //SA_ADVANCEDBOOK#Study# 275,0,6,4,0,1,0,5,1,no,0,0,0,magic,0 //SA_CASTCANCEL#Cast Cancel# 276,0,6,4,0,1,0,5,1,yes,0,0,0,magic,0 //SA_MAGICROD#Magic Rod# @@ -389,8 +388,8 @@ 368,0,6,4,0,1,0,5,1,yes,0,0,0,weapon,0 //PA_SACRIFICE# Martyr's Reckoning# 369,0,6,4,0,1,0,10,1,yes,0,0,0,misc,0 //PA_GOSPEL#Battle Chant# 370,-2,6,1,-1,0,0,5,1,yes,0,0,0,weapon,3 //CH_PALMSTRIKE#Raging Palm Strike# -371,-2,8,4,-1,0,0,5,1,no,0,0,0,weapon,0 //CH_TIGERFIST#Glacier Fist# -372,-2,8,4,-1,0,0,10,1:1:2:2:3:3:4:4:5:5,no,0,0,0,weapon,0 //CH_CHAINCRUSH#Chain Crush Combo# +371,-2,8,4,-1,0,0,5,1,no,0,512,0,weapon,0 //CH_TIGERFIST#Glacier Fist# +372,-2,8,4,-1,0,0,10,1:1:2:2:3:3:4:4:5:5,no,0,512,0,weapon,0 //CH_CHAINCRUSH#Chain Crush Combo# 373,0,6,4,0,1,0,5,1,no,0,0,0,magic,0 //PF_HPCONVERSION#Health Conversion# 374,9,6,16,0,1,0,1,1,yes,0,3072,0,none,0 //PF_SOULCHANGE#Soul Exhale# 375,9,6,1,0,0,0,5,1,yes,0,0,0,magic,0 //PF_SOULBURN#Soul Siphon# @@ -431,13 +430,13 @@ 410,9,6,4,0,1,0,1,1,yes,0,4,0,none,0 //WE_CALLBABY#Call Baby# 411,0,6,4,0,1,0,10,1,yes,0,0,0,misc,0 //TK_RUN#Running# 412,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_READYSTORM#Prepare Whirlwind# -413,0,6,4,-1,2,2,7,1,no,0,0,0,weapon,0 //TK_STORMKICK#Whirlwind Kick# +413,0,6,4,-1,2,2,7,1,no,0,512,0,weapon,0 //TK_STORMKICK#Whirlwind Kick# 414,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_READYDOWN#Prepare Axe Kick# -415,-2,6,4,-1,0,0,7,1,no,0,0,0,weapon,0 //TK_DOWNKICK#Axe Kick# +415,-2,6,4,-1,0,0,7,1,no,0,512,0,weapon,0 //TK_DOWNKICK#Axe Kick# 416,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_READYTURN#Prepare Round Kick# -417,-2,6,4,-1,2,1,7,1,no,0,0,0,weapon,2 //TK_TURNKICK#Round Kick# +417,-2,6,4,-1,2,1,7,1,no,0,512,0,weapon,2 //TK_TURNKICK#Round Kick# 418,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_READYCOUNTER#Prepare Counter Kick# -419,-2,6,4,-1,0,0,7,1,no,0,0,0,weapon,0 //TK_COUNTER#Counter Kick# +419,-2,6,4,-1,0,0,7,1,no,0,512,0,weapon,0 //TK_COUNTER#Counter Kick# 420,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_DODGE#Break Fall# 421,10,6,4,-1,0,0,7,1,no,0,0,0,weapon,0 //TK_JUMPKICK#Flying Side Kick# 422,0,0,0,0,0,1,10,0,no,0,0,0,none,0 //TK_HPTIME#Peaceful Rest# diff --git a/src/map/clif.c b/src/map/clif.c index cba560a30..ccf647414 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10033,6 +10033,11 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) { if (skillnotok(skillnum, sd)) return; + if (sd->bl.id != target_id && + !sd->state.skill_flag && + skill_get_inf(skillnum)&INF_SELF_SKILL) + target_id = sd->bl.id; //What good is it to mess up the target in self skills? Wished I knew... [Skotlex] + if (sd->skilltimer != -1) { if (skillnum != SA_CASTCANCEL) return; @@ -10093,7 +10098,6 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) { } } - if ((lv = pc_checkskill(sd, skillnum)) > 0) { if (skilllv > lv) skilllv = lv; diff --git a/src/map/skill.c b/src/map/skill.c index 28c6cfbc8..38a880df8 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1833,12 +1833,6 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds if(sd->status.party_id>0 && (level = pc_checkskill(sd,SG_FRIEND))) party_skill_check(sd, sd->status.party_id, TK_COUNTER,level); } - case TK_STORMKICK: - case TK_DOWNKICK: - case TK_TURNKICK: - // Delay normal attack table until skill's delay has passed. Let's make it skip one attack motion. [Skotlex] - sd->attackabletime = tick + status_get_amotion(&sd->bl); - battle_set_walkdelay(src, tick, status_get_amotion(&sd->bl), 1); break; case SL_STIN: case SL_STUN: @@ -6493,14 +6487,12 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid, val3 = HW_MAGICPOWER; //Store the magic power flag. [Skotlex] nullpo_retr(NULL, group=skill_initunitgroup(src,(count > 0 ? count : layout->count), - skillid,skilllv,skill_get_unit_id(skillid,flag&1))); - group->limit=limit; + skillid,skilllv,skill_get_unit_id(skillid,flag&1), limit, interval)); group->val1=val1; group->val2=val2; group->val3=val3; group->target_flag=target; group->bl_flag= skill_get_unit_bl_target(skillid); - group->interval=interval; if(skillid==HT_TALKIEBOX || skillid==RG_GRAFFITI){ group->valstr=(char *) aCallocA(MESSAGE_SIZE, sizeof(char)); @@ -8367,44 +8359,27 @@ int skill_use_id (struct map_session_data *sd, int target_id, int skill_num, int return 0; sc = sd->sc.count?&sd->sc:NULL; - + + //casttime is reused as a combo-skill checker (needed to invoke battle_stopattack) [Skotlex] + casttime = (target_id == sd->bl.id + && skill_get_inf(skill_num)&INF_SELF_SKILL + && skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF); + if (casttime) + target_id = sd->attacktarget; //Auto-select skills. [Skotlex] switch(skill_num) { //Check for skills that auto-select target case MO_CHAINCOMBO: - target_id = sd->attacktarget; if (sc && sc->data[SC_BLADESTOP].timer != -1){ if ((bl=(struct block_list *)sc->data[SC_BLADESTOP].val4) == NULL) //タ?ゲットがいない? return 0; target_id = bl->id; } break; - case MO_COMBOFINISH: - case CH_CHAINCRUSH: - case CH_TIGERFIST: - case TK_STORMKICK: // Taekwon kicks [Dralnu] - case TK_DOWNKICK: - case TK_TURNKICK: - target_id = sd->attacktarget; - break; - case TK_JUMPKICK: case TK_COUNTER: case HT_POWER: if (sc && sc->data[SC_COMBO].timer != -1 && sc->data[SC_COMBO].val1 == skill_num) target_id = sc->data[SC_COMBO].val2; - else if (skill_num == TK_COUNTER) //This one is for Ranking TKers - target_id = sd->attacktarget; - else if (skill_num == HT_POWER) - return 0; - break; -// -- moonsoul (altered to allow proper usage of extremity from new champion combos) -// - case MO_EXTREMITYFIST: /*阿修羅覇鳳拳*/ - if (sc && sc->data[SC_COMBO].timer != -1 && - (sc->data[SC_COMBO].val1 == MO_COMBOFINISH || - sc->data[SC_COMBO].val1 == CH_TIGERFIST || - sc->data[SC_COMBO].val1 == CH_CHAINCRUSH)) - target_id = sd->attacktarget; break; case WE_MALE: case WE_FEMALE: @@ -8516,17 +8491,10 @@ int skill_use_id (struct map_session_data *sd, int target_id, int skill_num, int return 0; } - if ((skill_num != MO_CHAINCOMBO && - skill_num != MO_COMBOFINISH && - skill_num != MO_EXTREMITYFIST && - skill_num != CH_TIGERFIST && - skill_num != CH_CHAINCRUSH && - skill_num != TK_STORMKICK && - skill_num != TK_DOWNKICK && - skill_num != TK_TURNKICK && - skill_num != TK_COUNTER) || - (skill_num == MO_EXTREMITYFIST && sd->state.skill_flag)) + if (!casttime) //Stop attack on non-combo skills [Skotlex] pc_stopattack(sd); + else if(sd->attacktimer != -1) //Elsewise, delay current attack sequence + sd->attackabletime = tick + status_get_amotion(&sd->bl); casttime = skill_castfix(&sd->bl, skill_num, skill_lv, 0); sd->state.skillcastcancel = skill_get_castcancel(skill_num); @@ -9832,7 +9800,7 @@ int skill_delunit(struct skill_unit *unit) */ static int skill_unit_group_newid = MAX_SKILL_DB; struct skill_unit_group *skill_initunitgroup(struct block_list *src, - int count,int skillid,int skilllv,int unit_id) + int count,int skillid,int skilllv,int unit_id, int limit, int interval) { int i; struct skill_unit_group *group=NULL, *list=NULL; @@ -9890,11 +9858,13 @@ struct skill_unit_group *skill_initunitgroup(struct block_list *src, group->skill_lv=skilllv; group->unit_id=unit_id; group->map=src->m; - group->limit=10000; - group->interval=1000; + group->limit=limit; + group->interval=interval; group->tick=gettick(); if (skillid == PR_SANCTUARY) //Sanctuary starts healing +1500ms after casted. [Skotlex] group->tick += 1500; + else if (skillid == PA_GOSPEL) //Prevent Gospel from triggering bonuses right away. [Skotlex] + group->tick += interval; group->valstr=NULL; i = skill_get_unit_flag(skillid); //Reuse for faster access from here on. [Skotlex] diff --git a/src/map/skill.h b/src/map/skill.h index 0d359e507..1613a47c2 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -183,7 +183,7 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid, struct skill_unit *skill_initunit(struct skill_unit_group *group,int idx,int x,int y); int skill_delunit(struct skill_unit *unit); struct skill_unit_group *skill_initunitgroup(struct block_list *src, - int count,int skillid,int skilllv,int unit_id); + int count,int skillid,int skilllv,int unit_id, int limit, int interval); int skill_delunitgroup(struct skill_unit_group *group); int skill_clear_unitgroup(struct block_list *src); int skill_clear_element_field(struct block_list *bl); -- cgit v1.2.3-60-g2f50