From bb9704555b413ab267771434546f3eb05c0147da Mon Sep 17 00:00:00 2001 From: Skotlex Date: Tue, 23 Aug 2011 17:30:08 +0000 Subject: - Rewrote/updated the SC_COMBO logic. Got rid of state.combo and added usage of packet 0x7e1 (PACKET_ZC_SKILLINFO_UPDATE2) to report skill inf changes. - Cleaned up a bit the function clif_setlevel (these functions should be as lightweight as possible...) - Fixed the server sending twice the skill tree during login. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@14939 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 2 ++ src/map/clif.c | 53 +++++++++++++++------------------ src/map/clif.h | 1 + src/map/pc.h | 1 - src/map/skill.c | 39 +++++++++++------------- src/map/status.c | 86 ++++++++++++++++++++++++++++------------------------- src/map/unit.c | 31 +++++++++---------- 7 files changed, 106 insertions(+), 107 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index a51c29745..13cd831fa 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -1,5 +1,7 @@ Date Added +2011/08/23 + * Rewrote the combo logic. Now it uses packet 0x7e1 to signal skill state changes rather than resending the whole skill list. [Skotlex] 2011/08/21 * Fixed monsters above Lv99 displaying a Lv99 aura (bugreport:3986). [Ai4rei] - The server no longer caps the level sent to the client by default. diff --git a/src/map/clif.c b/src/map/clif.c index 5d4d20933..5e8ef2367 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -777,32 +777,15 @@ static int clif_setlevel_sub(int lv) static int clif_setlevel(struct block_list* bl) { int lv = status_get_lv(bl); - + if( battle_config.client_limit_unit_lv&bl->type ) + return clif_setlevel_sub(lv); switch( bl->type ) { - case BL_PC: - case BL_HOM: - case BL_MOB: - case BL_MER: - if( battle_config.client_limit_unit_lv&bl->type ) - { - lv = clif_setlevel_sub(lv); - } - break; case BL_NPC: case BL_PET: - if( battle_config.client_limit_unit_lv&bl->type ) - { - lv = clif_setlevel_sub(lv); - break; - } // npcs and pets do not have level return 0; - default: - ShowWarning("clif_setlevel: Unhandled bl type %d.\n", bl->type); - break; } - return lv; } @@ -4231,10 +4214,7 @@ int clif_skillinfoblock(struct map_session_data *sd) if( (id = sd->status.skill[i].id) != 0 ) { WFIFOW(fd,len) = id; - if( (id == MO_EXTREMITYFIST && sd->state.combo&1) || (id == TK_JUMPKICK && sd->state.combo&2) ) - WFIFOW(fd,len+2) = INF_SELF_SKILL; - else - WFIFOW(fd,len+2) = skill_get_inf(id); + WFIFOW(fd,len+2) = skill_get_inf(id); WFIFOW(fd,len+4) = 0; WFIFOW(fd,len+6) = sd->status.skill[i].lv; WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv); @@ -4268,10 +4248,7 @@ int clif_addskill(struct map_session_data *sd, int id ) WFIFOHEAD(fd, packet_len(0x111)); WFIFOW(fd,0) = 0x111; WFIFOW(fd,2) = id; - if( (id == MO_EXTREMITYFIST && sd->state.combo&1) || (id == TK_JUMPKICK && sd->state.combo&2) ) - WFIFOW(fd,4) = INF_SELF_SKILL; - else - WFIFOW(fd,4) = skill_get_inf(id); + WFIFOW(fd,4) = skill_get_inf(id); WFIFOW(fd,6) = 0; WFIFOW(fd,8) = sd->status.skill[id].lv; WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv); @@ -4327,6 +4304,24 @@ int clif_skillup(struct map_session_data *sd,int skill_num) return 0; } +//PACKET_ZC_SKILLINFO_UPDATE2 +//Like packet 0x0x10e, but also contains inf information +void clif_skillinfo(struct map_session_data *sd,int skill, int inf) +{ + const int fd = sd->fd; + WFIFOHEAD(fd,packet_len(0x7e1)); + WFIFOW(fd,0) = 0x7e1; + WFIFOW(fd,2) = skill; + WFIFOL(fd,4) = inf?inf:skill_get_inf(skill); + WFIFOW(fd,8) = sd->status.skill[skill].lv; + WFIFOW(fd,10) = skill_get_sp(skill,sd->status.skill[skill].lv); + WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill,sd->status.skill[skill].lv); + if( sd->status.skill[skill].flag == SKILL_FLAG_PERMANENT ) + WFIFOB(fd,14) = (sd->status.skill[skill].lv < skill_tree_get_max(skill, sd->status.class_))? 1:0; + else + WFIFOB(fd,14) = 0; + WFIFOSET(fd,packet_len(0x7e1)); +} /// Notifies clients, that an object is about to use a skill (ZC_USESKILL_ACK/ZC_USESKILL_ACK2) /// 013e .L .L .W .W .W .L .L @@ -10040,7 +10035,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) if( skillnotok(skillnum, sd) ) return; - if( sd->bl.id != target_id && (tmp&INF_SELF_SKILL || sd->state.combo) ) + if( sd->bl.id != target_id && tmp&INF_SELF_SKILL ) target_id = sd->bl.id; // never trust the client if( target_id < 0 && -target_id == sd->bl.id ) // for disguises [Valaris] @@ -15155,7 +15150,7 @@ static int packetdb_readdb(void) #else // 0x7d9 changed 6, 2, -1, 4, 4, 4, 4, 8, 8,268, 6, 8, 6, 54, 30, 54, #endif - 0, 0, 0, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 25, 0, 0, 26, 0, //#0x0800 #if PACKETVER < 20091229 diff --git a/src/map/clif.h b/src/map/clif.h index 58196c152..fe7603905 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -323,6 +323,7 @@ int clif_mob_equip(struct mob_data *md,int nameid); // [Valaris] int clif_skillinfoblock(struct map_session_data *sd); int clif_skillup(struct map_session_data *sd,int skill_num); +void clif_skillinfo(struct map_session_data *sd,int skill, int inf); int clif_addskill(struct map_session_data *sd, int skill); int clif_deleteskill(struct map_session_data *sd, int skill); diff --git a/src/map/pc.h b/src/map/pc.h index 17450bf19..4d1e929a0 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -101,7 +101,6 @@ struct map_session_data { unsigned int lr_flag : 2; unsigned int connect_new : 1; unsigned int arrow_atk : 1; - unsigned int combo : 2; // 1:Asura, 2:Kick [Inkfish] unsigned int gangsterparadise : 1; unsigned int rest : 1; unsigned int storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex] diff --git a/src/map/skill.c b/src/map/skill.c index 15be872f1..a596034c6 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1697,7 +1697,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if(sd) { int flag = 0; //Used to signal if this skill can be combo'ed later on. - if (sd->sc.data[SC_COMBO]) + struct status_change_entry *sce; + if ((sce = sd->sc.data[SC_COMBO])) { //End combo state after skill is invoked. [Skotlex] switch (skillid) { case TK_TURNKICK: @@ -1706,13 +1707,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds case TK_COUNTER: if (pc_famerank(sd->status.char_id,MAPID_TAEKWON)) { //Extend combo time. - sd->skillid_old = skillid; //Set as previous so you can't repeat - sd->skilllv_old = skilllv; - sd->sc.data[SC_COMBO]->val1 = skillid; //Update combo-skill - delete_timer(sd->sc.data[SC_COMBO]->timer, status_change_timer); - sd->sc.data[SC_COMBO]->timer = add_timer( - tick+sd->sc.data[SC_COMBO]->val4, - status_change_timer, src->id, SC_COMBO); + sce->val1 = skillid; //Update combo-skill + sce->val3 = skillid; + delete_timer(sce->timer, status_change_timer); + sce->timer = add_timer(tick+sce->val4, status_change_timer, src->id, SC_COMBO); break; } unit_cancel_combo(src); // Cancel combo wait @@ -1748,7 +1746,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if( (tstatus->race == RC_BRUTE || tstatus->race == RC_INSECT) && pc_checkskill(sd, HT_POWER)) { //TODO: This code was taken from Triple Blows, is this even how it should be? [Skotlex] - sc_start4(src,SC_COMBO,100,HT_POWER,bl->id,0,0,2000); + sc_start2(src,SC_COMBO,100,HT_POWER,bl->id,2000); clif_combo_delay(src,2000); } break; @@ -1771,9 +1769,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds } //Switch End if (flag) { //Possible to chain flag = DIFF_TICK(sd->ud.canact_tick, tick); - if (flag < 0) flag = 0; - flag += 300 * battle_config.combo_delay_rate/100; - sc_start(src,SC_COMBO,100,skillid,flag); + if (flag < 1) flag = 1; + sc_start2(src,SC_COMBO,100,skillid,bl->id,flag); clif_combo_delay(src, flag); } } @@ -8302,14 +8299,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh return 0; //Anti-Soul Linker check in case you job-changed with Stances active. if(!(sc && sc->data[SC_COMBO])) return 0; //Combo needs to be ready - if (pc_famerank(sd->status.char_id,MAPID_TAEKWON)) - { //Unlimited Combo - if (skill == sd->skillid_old) { - status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER); - sd->skillid_old = sd->skilllv_old = 0; - return 0; //Can't repeat previous combo skill. - } - break; + + if (sc->data[SC_COMBO]->val3) + { //Kick chain + //Do not repeat a kick. + if (sc->data[SC_COMBO]->val3 != skill) + break; + status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER); + return 0; } if(sc->data[SC_COMBO]->val1 != skill) { //Cancel combo wait. @@ -8329,7 +8326,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh if (skill_get_time( (sc->data[SC_DANCING]->val1&0xFFFF), //Dance Skill ID (sc->data[SC_DANCING]->val1>>16)) //Dance Skill LV - - time <= skill_get_time2(skill,lv)) + - time < skill_get_time2(skill,lv)) { clif_skill_fail(sd,skill,0,0); return 0; diff --git a/src/map/status.c b/src/map/status.c index 33ad82eb3..00708428e 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2411,6 +2411,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first) status_cpy(&sd->battle_status, status); // ----- CLIENT-SIDE REFRESH ----- + if(!sd->bl.prev) { + //Will update on LoadEndAck + calculating = 0; + return 0; + } if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill))) clif_skillinfoblock(sd); if(b_weight != sd->weight) @@ -5766,44 +5771,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val //val1: Skill ID //val2: When given, target (for autotargetting skills) //val3: When set, this combo time should NOT delay attack/movement - //val4: Combo time + //val3: TK: Last used kick + //val4: TK: Combo time struct unit_data *ud = unit_bl2ud(bl); - switch (val1) { - case TK_STORMKICK: - clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1); - break; - case TK_DOWNKICK: - clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1); - break; - case TK_TURNKICK: - clif_skill_nodamage(bl,bl,TK_READYTURN,1,1); - break; - case TK_COUNTER: - clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1); - break; - case MO_COMBOFINISH: - case CH_TIGERFIST: - case CH_CHAINCRUSH: - if( sd ) - { - sd->state.combo = 1; - clif_skillinfoblock(sd); - } - break; - case TK_JUMPKICK: - if( sd ) - { - sd->state.combo = 2; - clif_skillinfoblock(sd); - } - break; - } if (ud && !val3) { + tick += 300 * battle_config.combo_delay_rate/100; ud->attackabletime = gettick()+tick; unit_set_walkdelay(bl, gettick(), tick, 1); } - val4 = tick; //Store combo-time in val4. + val3 = 0; + val4 = tick; } break; case SC_EARTHSCROLL: @@ -6337,6 +6315,31 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_MERC_SPUP: status_percent_heal(bl, 0, 100); // Recover Full SP break; + case SC_COMBO: + switch (sce->val1) { + case TK_STORMKICK: + clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1); + break; + case TK_DOWNKICK: + clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1); + break; + case TK_TURNKICK: + clif_skill_nodamage(bl,bl,TK_READYTURN,1,1); + break; + case TK_COUNTER: + clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1); + break; + case MO_COMBOFINISH: + case CH_TIGERFIST: + case CH_CHAINCRUSH: + if (sd) + clif_skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL); + break; + case TK_JUMPKICK: + if (sd) + clif_skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL); + break; + } } if( opt_flag&2 && sd && sd->touching_id ) @@ -6675,16 +6678,17 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick()); } break; - case SC_COMBO: //Clear last used skill when it is part of a combo. + case SC_COMBO: if( sd ) - { - if( sd->state.combo ) - { - sd->state.combo = 0; - clif_skillinfoblock(sd); - } - if( sd->skillid_old == sce->val1 ) - sd->skillid_old = sd->skilllv_old = 0; + switch (sce->val1) { + case MO_COMBOFINISH: + case CH_TIGERFIST: + case CH_CHAINCRUSH: + clif_skillinfo(sd, MO_EXTREMITYFIST, 0); + break; + case TK_JUMPKICK: + clif_skillinfo(sd, TK_JUMPKICK, 0); + break; } break; diff --git a/src/map/unit.c b/src/map/unit.c index 2165532b4..09a19e27d 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -912,7 +912,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh struct map_session_data *sd = NULL; struct block_list * target = NULL; unsigned int tick = gettick(); - int temp; + int temp = 0; nullpo_ret(src); if(status_isdead(src)) @@ -927,14 +927,21 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh sc = NULL; //Unneeded //temp: used to signal combo-skills right now. - temp = ( target_id == src->id && - ( - ( !(skill_get_inf(skill_num)&INF_SELF_SKILL) && sd && sd->state.combo ) || - ( skill_get_inf(skill_num)&INF_SELF_SKILL && skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF ) - ) - ); - if (temp) - target_id = ud->target; //Auto-select skills. [Skotlex] + if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num) + { + if (sc->data[SC_COMBO]->val2) + target_id = sc->data[SC_COMBO]->val2; + else + target_id = ud->target; + temp = 1; + } else + if ( target_id == src->id && + skill_get_inf(skill_num)&INF_SELF_SKILL && + skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF ) + { + target_id = ud->target; //Auto-select target. [Skotlex] + temp = 1; + } if (sd) { //Target_id checking. @@ -949,12 +956,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh return 0; } break; - case TK_JUMPKICK: - case TK_COUNTER: - case HT_POWER: - if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num) - target_id = sc->data[SC_COMBO]->val2; - break; case WE_MALE: case WE_FEMALE: if (!sd->status.partner_id) -- cgit v1.2.3-70-g09d2