summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt2
-rw-r--r--src/map/clif.c53
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/pc.h1
-rw-r--r--src/map/skill.c39
-rw-r--r--src/map/status.c86
-rw-r--r--src/map/unit.c31
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 <src id>.L <dst id>.L <x pos>.W <y pos>.W <skill id>.W <property>.L <delaytime>.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)