summaryrefslogtreecommitdiff
path: root/src/map/clif.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/clif.c')
-rw-r--r--src/map/clif.c281
1 files changed, 197 insertions, 84 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 524378439..905b6a3ce 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -2442,7 +2442,9 @@ void clif_addcards2(unsigned short *cards, struct item* item) {
/// 02d4 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W (ZC_ITEM_PICKUP_ACK3)
/// 0990 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.L <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W (ZC_ITEM_PICKUP_ACK_V5)
/// 0a0c <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.L <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W (ZC_ITEM_PICKUP_ACK_V6)
-void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
+/// 0a37 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.L <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W <favorite>.B <view id>.W (ZC_ITEM_PICKUP_ACK_V7)
+void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
+{
struct packet_additem p;
nullpo_retv(sd);
@@ -2483,6 +2485,10 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
#if PACKETVER >= 20150226
clif->add_item_options(&p.option_data[0], &sd->status.inventory[n]);
#endif
+#if PACKETVER >= 20160921
+ p.favorite = sd->status.inventory[n].favorite;
+ p.look = sd->inventory_data[n]->look;
+#endif
}
p.result = (unsigned char)fail;
@@ -2978,13 +2984,6 @@ void clif_updatestatus(struct map_session_data *sd,int type)
break;
case SP_HP:
WFIFOL(fd,4)=sd->battle_status.hp;
- // TODO: Won't these overwrite the current packet?
- if( map->list[sd->bl.m].hpmeter_visible )
- clif->hpmeter(sd);
- if( !battle_config.party_hp_mode && sd->status.party_id )
- clif->party_hp(sd);
- if( sd->bg_id )
- clif->bg_hp(sd);
break;
case SP_SP:
WFIFOL(fd,4)=sd->battle_status.sp;
@@ -3134,6 +3133,21 @@ void clif_updatestatus(struct map_session_data *sd,int type)
return;
}
WFIFOSET(fd,len);
+
+ // Additional update packets that should be sent right after
+ switch (type) {
+ case SP_BASELEVEL:
+ pc->update_job_and_level(sd);
+ break;
+ case SP_HP:
+ if (map->list[sd->bl.m].hpmeter_visible)
+ clif->hpmeter(sd);
+ if (!battle_config.party_hp_mode && sd->status.party_id)
+ clif->party_hp(sd);
+ if (sd->bg_id)
+ clif->bg_hp(sd);
+ break;
+ }
}
/// Notifies client of a parameter change of an another player (ZC_PAR_CHANGE_USER).
@@ -6345,10 +6359,13 @@ void clif_vendinglist(struct map_session_data* sd, unsigned int id, struct s_ven
const int offset = 12;
#endif
-#if PACKETVER >= 20150226
+#if PACKETVER < 20150226
+ const int item_length = 22;
+// [4144] date 20160921 not confirmend. Can be bigger or smaller
+#elif PACKETVER < 20160921
const int item_length = 47;
#else
- const int item_length = 22;
+ const int item_length = 53;
#endif
nullpo_retv(sd);
@@ -6381,6 +6398,11 @@ void clif_vendinglist(struct map_session_data* sd, unsigned int id, struct s_ven
#if PACKETVER >= 20150226
clif->add_item_options(WFIFOP(fd, offset + 22 + i * item_length), &vsd->status.cart[index]);
#endif
+// [4144] date 20160921 not confirmend. Can be bigger or smaller
+#if PACKETVER >= 20160921
+ WFIFOL(fd, offset + 47 + i * item_length) = pc->item_equippoint(sd, data);
+ WFIFOW(fd, offset + 51 + i * item_length) = data->look;
+#endif
}
WFIFOSET(fd,WFIFOW(fd,2));
}
@@ -6511,6 +6533,7 @@ void clif_party_created(struct map_session_data *sd,int result)
/// Adds new member to a party.
/// 0104 <account id>.L <role>.L <x>.W <y>.W <state>.B <party name>.24B <char name>.24B <map name>.16B (ZC_ADD_MEMBER_TO_GROUP)
/// 01e9 <account id>.L <role>.L <x>.W <y>.W <state>.B <party name>.24B <char name>.24B <map name>.16B <item pickup rule>.B <item share rule>.B (ZC_ADD_MEMBER_TO_GROUP2)
+/// 0a43 <account id>.L <role>.L <class>.W <base level>.W <x>.W <y>.W <state>.B <party name>.24B <char name>.24B <map name>.16B <item pickup rule>.B <item share rule>.B (ZC_ADD_MEMBER_TO_GROUP3)
/// role:
/// 0 = leader
/// 1 = normal
@@ -6519,35 +6542,50 @@ void clif_party_created(struct map_session_data *sd,int result)
/// 1 = disconnected
void clif_party_member_info(struct party_data *p, struct map_session_data *sd)
{
- unsigned char buf[81];
int i;
+#if PACKETVER < 20170502
+ unsigned char buf[81];
+ const int cmd = 0x1e9;
+ const int offset = 0;
+#else
+ unsigned char buf[85];
+// [4144] probably 0xa43 packet can works on older clients because in client was added in 2015-10-07
+ const int cmd = 0xa43;
+ int offset = 4;
+#endif
nullpo_retv(p);
nullpo_retv(sd);
if (!sd) { //Pick any party member (this call is used when changing item share rules)
- ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd != 0 );
+ ARR_FIND(0, MAX_PARTY, i, p->data[i].sd != 0);
} else {
- ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd == sd );
+ ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd);
}
- if (i >= MAX_PARTY) return; //Should never happen...
+ if (i >= MAX_PARTY)
+ return; //Should never happen...
sd = p->data[i].sd;
- WBUFW(buf, 0) = 0x1e9;
+ WBUFW(buf, 0) = cmd;
WBUFL(buf, 2) = sd->status.account_id;
- WBUFL(buf, 6) = (p->party.member[i].leader)?0:1;
- WBUFW(buf,10) = sd->bl.x;
- WBUFW(buf,12) = sd->bl.y;
- WBUFB(buf,14) = (p->party.member[i].online)?0:1;
- memcpy(WBUFP(buf,15), p->party.name, NAME_LENGTH);
- memcpy(WBUFP(buf,39), sd->status.name, NAME_LENGTH);
- mapindex->getmapname_ext(map->list[sd->bl.m].custom_name ? map->list[map->list[sd->bl.m].instance_src_map].name : map->list[sd->bl.m].name, WBUFP(buf,63));
- WBUFB(buf,79) = (p->party.item&1)?1:0;
- WBUFB(buf,80) = (p->party.item&2)?1:0;
- clif->send(buf,packet_len(0x1e9),&sd->bl,PARTY);
+ WBUFL(buf, 6) = (p->party.member[i].leader) ? 0 : 1;
+#if PACKETVER >= 20170502
+ WBUFW(buf, 10) = sd->status.class;
+ WBUFW(buf, 12) = sd->status.base_level;
+#endif
+ WBUFW(buf, offset + 10) = sd->bl.x;
+ WBUFW(buf, offset + 12) = sd->bl.y;
+ WBUFB(buf, offset + 14) = (p->party.member[i].online) ? 0 : 1;
+ memcpy(WBUFP(buf, offset + 15), p->party.name, NAME_LENGTH);
+ memcpy(WBUFP(buf, offset + 39), sd->status.name, NAME_LENGTH);
+ mapindex->getmapname_ext(map->list[sd->bl.m].custom_name ? map->list[map->list[sd->bl.m].instance_src_map].name : map->list[sd->bl.m].name, WBUFP(buf, offset + 63));
+ WBUFB(buf, offset + 79) = (p->party.item & 1) ? 1 : 0;
+ WBUFB(buf, offset + 80) = (p->party.item & 2) ? 1 : 0;
+ clif->send(buf, packet_len(cmd), &sd->bl, PARTY);
}
/// Sends party information (ZC_GROUP_LIST).
/// 00fb <packet len>.W <party name>.24B { <account id>.L <nick>.24B <map name>.16B <role>.B <state>.B }*
+/// 0a44 <packet len>.W <party name>.24B { <account id>.L <nick>.24B <map name>.16B <role>.B <state>.B <class>.W <base level>.W }* <item pickup rule>.B <item share rule>.B <unknown>.L
/// role:
/// 0 = leader
/// 1 = normal
@@ -6556,37 +6594,78 @@ void clif_party_member_info(struct party_data *p, struct map_session_data *sd)
/// 1 = disconnected
void clif_party_info(struct party_data* p, struct map_session_data *sd)
{
- unsigned char buf[2+2+NAME_LENGTH+(4+NAME_LENGTH+MAP_NAME_LENGTH_EXT+1+1)*MAX_PARTY];
struct map_session_data* party_sd = NULL;
int i, c;
+#if PACKETVER < 20170502
+ const int cmd = 0xfb;
+ const int size = 46;
+ unsigned char buf[2 + 2 + NAME_LENGTH + 46 * MAX_PARTY];
+#else
+// [4144] probably 0xa44 packet can works on older clients because in client was added in 2015-10-07
+ const int cmd = 0xa44;
+ const int size = 50;
+ unsigned char buf[2 + 2 + NAME_LENGTH + 50 * MAX_PARTY + 6];
+#endif
nullpo_retv(p);
- WBUFW(buf,0) = 0xfb;
- memcpy(WBUFP(buf,4), p->party.name, NAME_LENGTH);
+ WBUFW(buf, 0) = cmd;
+ memcpy(WBUFP(buf, 4), p->party.name, NAME_LENGTH);
for(i = 0, c = 0; i < MAX_PARTY; i++)
{
- struct party_member* m = &p->party.member[i];
- if(!m->account_id) continue;
+ struct party_member *m = &p->party.member[i];
+ if (!m->account_id)
+ continue;
- if(party_sd == NULL) party_sd = p->data[i].sd;
+ if (party_sd == NULL)
+ party_sd = p->data[i].sd;
- WBUFL(buf,28+c*46) = m->account_id;
- memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH);
- mapindex->getmapname_ext(mapindex_id2name(m->map), WBUFP(buf,28+c*46+28));
- WBUFB(buf,28+c*46+44) = (m->leader) ? 0 : 1;
- WBUFB(buf,28+c*46+45) = (m->online) ? 0 : 1;
+ WBUFL(buf, 28 + c * size) = m->account_id;
+ memcpy(WBUFP(buf, 28 + c * size + 4), m->name, NAME_LENGTH);
+ mapindex->getmapname_ext(mapindex_id2name(m->map), WBUFP(buf, 28 + c * size + 28));
+ WBUFB(buf, 28 + c * size + 44) = (m->leader) ? 0 : 1;
+ WBUFB(buf, 28 + c * size + 45) = (m->online) ? 0 : 1;
+#if PACKETVER >= 20170502
+ WBUFW(buf, 28 + c * size + 46) = m->class;
+ WBUFW(buf, 28 + c * size + 48) = m->lv;
+#endif
c++;
}
- WBUFW(buf,2) = 28+c*46;
+#if PACKETVER < 20170502
+ WBUFW(buf, 2) = 28 + c * size;
+#else
+ WBUFB(buf, 28 + c * size) = (p->party.item & 1) ? 1 : 0;
+ WBUFB(buf, 28 + c * size + 1) = (p->party.item & 2) ? 1 : 0;
+ WBUFL(buf, 28 + c * size + 2) = 0; // unknown
+ WBUFW(buf, 2) = 28 + c * size + 6;
+#endif
- if(sd) { // send only to self
- clif->send(buf, WBUFW(buf,2), &sd->bl, SELF);
+ if (sd) { // send only to self
+ clif->send(buf, WBUFW(buf, 2), &sd->bl, SELF);
} else if (party_sd) { // send to whole party
- clif->send(buf, WBUFW(buf,2), &party_sd->bl, PARTY);
+ clif->send(buf, WBUFW(buf, 2), &party_sd->bl, PARTY);
}
}
+/// Updates the job and level of a party member
+/// 0abd <account id>.L <job>.W <level>.W
+void clif_party_job_and_level(struct map_session_data *sd)
+{
+// [4144] packet 0xabd added in client in 2017-02-15 because this probably it can works for clients older than 20170502
+#if PACKETVER >= 20170502
+ unsigned char buf[10];
+
+ nullpo_retv(sd);
+
+ WBUFW(buf, 0) = 0xabd;
+ WBUFL(buf, 2) = sd->status.account_id;
+ WBUFW(buf, 6) = sd->status.class;
+ WBUFW(buf, 8) = sd->status.base_level;
+
+ clif_send(buf, packet_len(0xabd), &sd->bl, PARTY);
+#endif
+}
+
/// The player's 'party invite' state, sent during login (ZC_PARTY_CONFIG).
/// 02c9 <flag>.B
/// flag:
@@ -7433,36 +7512,48 @@ void clif_guild_masterormember(struct map_session_data *sd)
/// Guild basic information (Territories [Valaris])
/// 0150 <guild id>.L <level>.L <member num>.L <member max>.L <exp>.L <max exp>.L <points>.L <honor>.L <virtue>.L <emblem id>.L <name>.24B <master name>.24B <manage land>.16B (ZC_GUILD_INFO)
/// 01b6 <guild id>.L <level>.L <member num>.L <member max>.L <exp>.L <max exp>.L <points>.L <honor>.L <virtue>.L <emblem id>.L <name>.24B <master name>.24B <manage land>.16B <zeny>.L (ZC_GUILD_INFO2)
-void clif_guild_basicinfo(struct map_session_data *sd) {
+void clif_guild_basicinfo(struct map_session_data *sd)
+{
int fd;
struct guild *g;
+#if PACKETVER < 20160622
+ const int cmd = 0x1b6; //0x150; [4144] this is packet for older versions?
+#else
+ const int cmd = 0xa84;
+#endif
+
nullpo_retv(sd);
fd = sd->fd;
- if( (g = sd->guild) == NULL )
+ if ((g = sd->guild) == NULL)
return;
- WFIFOHEAD(fd,packet_len(0x1b6));
- WFIFOW(fd, 0)=0x1b6;//0x150;
- WFIFOL(fd, 2)=g->guild_id;
- WFIFOL(fd, 6)=g->guild_lv;
- WFIFOL(fd,10)=g->connect_member;
- WFIFOL(fd,14)=g->max_member;
- WFIFOL(fd,18)=g->average_lv;
- WFIFOL(fd,22)=(uint32)cap_value(g->exp,0,INT32_MAX);
- WFIFOL(fd,26)=g->next_exp;
- WFIFOL(fd,30)=0; // Tax Points
- WFIFOL(fd,34)=0; // Honor: (left) Vulgar [-100,100] Famed (right)
- WFIFOL(fd,38)=0; // Virtue: (down) Wicked [-100,100] Righteous (up)
- WFIFOL(fd,42)=g->emblem_id;
- memcpy(WFIFOP(fd,46),g->name, NAME_LENGTH);
- memcpy(WFIFOP(fd,70),g->master, NAME_LENGTH);
-
- safestrncpy(WFIFOP(fd,94),msg_sd(sd,300+guild->checkcastles(g)),16); // "'N' castles"
- WFIFOL(fd,110) = 0; // zeny
+ WFIFOHEAD(fd, packet_len(cmd));
+ WFIFOW(fd, 0) = cmd;
+ WFIFOL(fd, 2) = g->guild_id;
+ WFIFOL(fd, 6) = g->guild_lv;
+ WFIFOL(fd, 10) = g->connect_member;
+ WFIFOL(fd, 14) = g->max_member;
+ WFIFOL(fd, 18) = g->average_lv;
+ WFIFOL(fd, 22) = (uint32)cap_value(g->exp, 0, INT32_MAX);
+ WFIFOL(fd, 26) = g->next_exp;
+ WFIFOL(fd, 30) = 0; // Tax Points
+ WFIFOL(fd, 34) = 0; // Honor: (left) Vulgar [-100,100] Famed (right)
+ WFIFOL(fd, 38) = 0; // Virtue: (down) Wicked [-100,100] Righteous (up)
+ WFIFOL(fd, 42) = g->emblem_id;
+ memcpy(WFIFOP(fd, 46), g->name, NAME_LENGTH);
+#if PACKETVER < 20160622
+ memcpy(WFIFOP(fd, 70), g->master, NAME_LENGTH);
+ safestrncpy(WFIFOP(fd, 94), msg_sd(sd, 300 + guild->checkcastles(g)), 16); // "'N' castles"
+ WFIFOL(fd, 110) = 0; // zeny
+#else
+ safestrncpy(WFIFOP(fd, 70), msg_sd(sd, 300 + guild->checkcastles(g)), 16); // "'N' castles"
+ WFIFOL(fd, 86) = 0; // zeny
+ WFIFOL(fd, 90) = g->member[0].char_id; // leader
+#endif
- WFIFOSET(fd,packet_len(0x1b6));
+ WFIFOSET(fd, packet_len(cmd));
}
/// Guild alliance and opposition list (ZC_MYGUILD_BASIC_INFO).
@@ -7504,35 +7595,47 @@ void clif_guild_memberlist(struct map_session_data *sd)
int fd;
int i,c;
struct guild *g;
+#if PACKETVER < 20161026
+ const int cmd = 0x154;
+ const int size = 104;
+#else
+ const int cmd = 0xaa5;
+ const int size = 34;
+#endif
+
nullpo_retv(sd);
- if( (fd = sd->fd) == 0 )
+ if ((fd = sd->fd) == 0)
return;
- if( (g = sd->guild) == NULL )
+ if ((g = sd->guild) == NULL)
return;
- WFIFOHEAD(fd, g->max_member * 104 + 4);
- WFIFOW(fd, 0)=0x154;
- for(i=0,c=0;i<g->max_member;i++){
- struct guild_member *m=&g->member[i];
- if(m->account_id==0)
+ WFIFOHEAD(fd, g->max_member * size + 4);
+ WFIFOW(fd, 0) = cmd;
+ for (i = 0, c = 0; i < g->max_member; i++) {
+ struct guild_member *m = &g->member[i];
+ if (m->account_id == 0)
continue;
- WFIFOL(fd,c*104+ 4)=m->account_id;
- WFIFOL(fd,c*104+ 8)=m->char_id;
- WFIFOW(fd,c*104+12)=m->hair;
- WFIFOW(fd,c*104+14)=m->hair_color;
- WFIFOW(fd,c*104+16)=m->gender;
- WFIFOW(fd,c*104+18)=m->class;
- WFIFOW(fd,c*104+20)=m->lv;
- WFIFOL(fd,c*104+22)=(int)cap_value(m->exp,0,INT32_MAX);
- WFIFOL(fd,c*104+26)=m->online;
- WFIFOL(fd,c*104+30)=m->position;
- memset(WFIFOP(fd,c*104+34),0,50); //[Ind] - This is displayed in the 'note' column but being you can't edit it it's sent empty.
- memcpy(WFIFOP(fd,c*104+84),m->name,NAME_LENGTH);
+ WFIFOL(fd, c * size + 4) = m->account_id;
+ WFIFOL(fd, c * size + 8) = m->char_id;
+ WFIFOW(fd, c * size + 12) = m->hair;
+ WFIFOW(fd, c * size + 14) = m->hair_color;
+ WFIFOW(fd, c * size + 16) = m->gender;
+ WFIFOW(fd, c * size + 18) = m->class;
+ WFIFOW(fd, c * size + 20) = m->lv;
+ WFIFOL(fd, c * size + 22) = (int)cap_value(m->exp, 0, INT32_MAX);
+ WFIFOL(fd, c * size + 26) = m->online;
+ WFIFOL(fd, c * size + 30) = m->position;
+#if PACKETVER < 20161026
+ memset(WFIFOP(fd, c * size + 34), 0, 50); //[Ind] - This is displayed in the 'note' column but being you can't edit it it's sent empty.
+ memcpy(WFIFOP(fd, c * size + 84), m->name, NAME_LENGTH);
+#else
+ WFIFOL(fd, c * size + 34) = 0; // [4144] this is member last login time. But in hercules it not present.
+#endif
c++;
}
- WFIFOW(fd, 2)=c*104+4;
- WFIFOSET(fd,WFIFOW(fd,2));
+ WFIFOW(fd, 2) = c * size + 4;
+ WFIFOSET(fd, WFIFOW(fd, 2));
}
/// Guild position name information (ZC_POSITION_ID_NAME_INFO).
@@ -12953,13 +13056,22 @@ void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd) _
void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd)
{
int i;
+ int len = RFIFOW(fd, 2);
if(!sd->state.gmaster_flag)
return;
+ // Guild leadership change
+ if (len == 16 && RFIFOL(fd, 12) == 0) {
+ guild->gm_change(sd->status.guild_id, RFIFOL(fd, 8));
+ return;
+ }
+
for(i=4;i<RFIFOW(fd,2);i+=12){
- guild->change_memberposition(sd->status.guild_id,
- RFIFOL(fd,i),RFIFOL(fd,i+4),RFIFOL(fd,i+8));
+ int position = RFIFOL(fd, i + 8);
+ if (position > 0) {
+ guild->change_memberposition(sd->status.guild_id, RFIFOL(fd, i), RFIFOL(fd, i + 4), position);
+ }
}
}
@@ -19702,6 +19814,7 @@ void clif_defaults(void) {
clif->party_created = clif_party_created;
clif->party_member_info = clif_party_member_info;
clif->party_info = clif_party_info;
+ clif->party_job_and_level = clif_party_job_and_level;
clif->party_invite = clif_party_invite;
clif->party_inviteack = clif_party_inviteack;
clif->party_option = clif_party_option;