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.c692
1 files changed, 360 insertions, 332 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index e55a27108..c5796555a 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -168,9 +168,9 @@ static inline unsigned char clif_bl_type(struct block_list *bl) {
case BL_ITEM: return 0x2; //ITEM_TYPE
case BL_SKILL: return 0x3; //SKILL_TYPE
case BL_CHAT: return 0x4; //UNKNOWN_TYPE
- case BL_MOB: return pcdb_checkid(((TBL_MOB*)bl)->vd->class_)?0x0:0x5; //NPC_MOB_TYPE
+ case BL_MOB: return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x5; //NPC_MOB_TYPE
case BL_NPC: return 0x6; //NPC_EVT_TYPE
- case BL_PET: return 0x7; //NPC_PET_TYPE
+ case BL_PET: return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x7; //NPC_PET_TYPE
case BL_HOM: return 0x8; //NPC_HOM_TYPE
case BL_MER: return 0x9; //NPC_MERSOL_TYPE
// case BL_ELEM: return 0xA; //NPC_ELEMENTAL_TYPE
@@ -658,7 +658,7 @@ int clif_clearflooritem(struct flooritem_data *fitem, int fd)
* 3 - teleported / logged out
* fd : the target client
*------------------------------------------*/
-int clif_clearunit_single(int id, uint8 type, int fd)
+int clif_clearunit_single(int id, clr_type type, int fd)
{
WFIFOHEAD(fd, packet_len(0x80));
WFIFOW(fd,0) = 0x80;
@@ -676,7 +676,7 @@ int clif_clearunit_single(int id, uint8 type, int fd)
* 2 - respawned
* 3 - teleported / logged out
*------------------------------------------*/
-int clif_clearunit_area(struct block_list* bl, uint8 type)
+int clif_clearunit_area(struct block_list* bl, clr_type type)
{
unsigned char buf[16];
@@ -686,7 +686,7 @@ int clif_clearunit_area(struct block_list* bl, uint8 type)
WBUFL(buf,2) = bl->id;
WBUFB(buf,6) = type;
- clif_send(buf, packet_len(0x80), bl, type == 1 ? AREA : AREA_WOS);
+ clif_send(buf, packet_len(0x80), bl, type == CLR_DEAD ? AREA : AREA_WOS);
if(disguised(bl)) {
WBUFL(buf,2) = -bl->id;
@@ -699,7 +699,7 @@ int clif_clearunit_area(struct block_list* bl, uint8 type)
static int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr data)
{
struct block_list *bl = (struct block_list *)data;
- clif_clearunit_area(bl, 0);
+ clif_clearunit_area(bl, CLR_OUTSIGHT);
aFree(bl);
return 0;
}
@@ -1059,16 +1059,6 @@ static void clif_spiritball_single(int fd, struct map_session_data *sd)
WFIFOSET(fd, packet_len(0x1e1));
}
-// new and improved weather display [Valaris]
-static void clif_weather_sub(int fd, int id, int type)
-{
- WFIFOHEAD(fd,packet_len(0x1f3));
- WFIFOW(fd,0) = 0x1f3;
- WFIFOL(fd,2) = id;
- WFIFOL(fd,6) = type;
- WFIFOSET(fd,packet_len(0x1f3));
-}
-
/*==========================================
*
*------------------------------------------*/
@@ -1086,24 +1076,24 @@ static void clif_weather_check(struct map_session_data *sd)
|| map[m].flag.clouds2)
{
if (map[m].flag.snow)
- clif_weather_sub(fd, sd->bl.id, 162);
+ clif_specialeffect_single(&sd->bl, 162, fd);
if (map[m].flag.clouds)
- clif_weather_sub(fd, sd->bl.id, 233);
+ clif_specialeffect_single(&sd->bl, 233, fd);
if (map[m].flag.clouds2)
- clif_weather_sub(fd, sd->bl.id, 516);
+ clif_specialeffect_single(&sd->bl, 516, fd);
if (map[m].flag.fog)
- clif_weather_sub(fd, sd->bl.id, 515);
+ clif_specialeffect_single(&sd->bl, 515, fd);
if (map[m].flag.fireworks) {
- clif_weather_sub(fd, sd->bl.id, 297);
- clif_weather_sub(fd, sd->bl.id, 299);
- clif_weather_sub(fd, sd->bl.id, 301);
+ clif_specialeffect_single(&sd->bl, 297, fd);
+ clif_specialeffect_single(&sd->bl, 299, fd);
+ clif_specialeffect_single(&sd->bl, 301, fd);
}
if (map[m].flag.sakura)
- clif_weather_sub(fd, sd->bl.id, 163);
+ clif_specialeffect_single(&sd->bl, 163, fd);
if (map[m].flag.leaves)
- clif_weather_sub(fd, sd->bl.id, 333);
+ clif_specialeffect_single(&sd->bl, 333, fd);
if (map[m].flag.rain)
- clif_weather_sub(fd, sd->bl.id, 161);
+ clif_specialeffect_single(&sd->bl, 161, fd);
}
}
@@ -1280,13 +1270,14 @@ int clif_homskillinfoblock(struct map_session_data *sd)
void clif_homskillup(struct map_session_data *sd, int skill_num)
{ //[orn]
struct homun_data *hd;
- int fd=sd->fd, skillid;
- WFIFOHEAD(fd, packet_len(0x239));
+ int fd, skillid;
nullpo_retv(sd);
skillid = skill_num - HM_SKILLBASE;
+ fd=sd->fd;
hd=sd->hd;
+ WFIFOHEAD(fd, packet_len(0x239));
WFIFOW(fd,0) = 0x239;
WFIFOW(fd,2) = skill_num;
WFIFOW(fd,4) = hd->homunculus.hskill[skillid].lv;
@@ -1468,9 +1459,10 @@ void clif_blown(struct block_list *bl)
clif_slide(bl, bl->x, bl->y);
}
-/*==========================================
- *
- *------------------------------------------*/
+/// Visually moves(slides) a character to x,y. If the target cell
+/// isn't walkable, the char doesn't move at all. If the char is
+/// sitting it will stand up.
+/// S 0088 <gid>.L <x>.W <y>.W
void clif_fixpos(struct block_list *bl)
{
unsigned char buf[10];
@@ -1529,9 +1521,7 @@ int clif_buylist(struct map_session_data *sd, struct npc_data *nd)
if( id == NULL )
continue;
WFIFOL(fd, 4+c*11) = val;
- if (!id->flag.value_notdc)
- val = pc_modifybuyvalue(sd,val);
- WFIFOL(fd, 8+c*11) = val;
+ WFIFOL(fd, 8+c*11) = pc_modifybuyvalue(sd,val);
WFIFOB(fd,12+c*11) = itemtype(id->type);
WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
c++;
@@ -1570,9 +1560,7 @@ int clif_selllist(struct map_session_data *sd)
continue;
WFIFOW(fd,4+c*10)=i+2;
WFIFOL(fd,6+c*10)=val;
- if( !sd->inventory_data[i]->flag.value_notoc )
- val=pc_modifysellvalue(sd,val);
- WFIFOL(fd,10+c*10)=val;
+ WFIFOL(fd,10+c*10)=pc_modifysellvalue(sd,val);
c++;
}
}
@@ -2166,7 +2154,7 @@ void clif_equiplist(struct map_session_data *sd)
}
}
-void clif_storagelist(struct map_session_data* sd, struct storage_data* stor)
+void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length)
{
struct item_data *id;
int i,n,ne;
@@ -2187,21 +2175,21 @@ void clif_storagelist(struct map_session_data* sd, struct storage_data* stor)
const int cmd = 28;
#endif
- buf = (unsigned char*)aMallocA(MAX_STORAGE * s + 4);
- bufe = (unsigned char*)aMallocA(MAX_STORAGE * cmd + 4);
+ buf = (unsigned char*)aMallocA(items_length * s + 4);
+ bufe = (unsigned char*)aMallocA(items_length * cmd + 4);
- for( i = 0, n = 0, ne = 0; i < MAX_STORAGE; i++ )
+ for( i = 0, n = 0, ne = 0; i < items_length; i++ )
{
- if( stor->items[i].nameid <= 0 )
+ if( items[i].nameid <= 0 )
continue;
- id = itemdb_search(stor->items[i].nameid);
+ id = itemdb_search(items[i].nameid);
if( !itemdb_isstackable2(id) )
{ //Equippable
WBUFW(bufe,ne*cmd+4)=i+1;
- clif_item_sub(bufe, ne*cmd+6, &stor->items[i], id, id->equip);
- clif_addcards(WBUFP(bufe, ne*cmd+16), &stor->items[i]);
+ clif_item_sub(bufe, ne*cmd+6, &items[i], id, id->equip);
+ clif_addcards(WBUFP(bufe, ne*cmd+16), &items[i]);
#if PACKETVER >= 20071002
- WBUFL(bufe,ne*cmd+24)=stor->items[i].expire_time;
+ WBUFL(bufe,ne*cmd+24)=items[i].expire_time;
WBUFW(bufe,ne*cmd+28)=0; //Unknown
#endif
ne++;
@@ -2209,93 +2197,12 @@ void clif_storagelist(struct map_session_data* sd, struct storage_data* stor)
else
{ //Stackable
WBUFW(buf,n*s+4)=i+1;
- clif_item_sub(buf, n*s+6, &stor->items[i], id,-1);
+ clif_item_sub(buf, n*s+6, &items[i], id,-1);
#if PACKETVER >= 5
- clif_addcards(WBUFP(buf,n*s+14), &stor->items[i]);
+ clif_addcards(WBUFP(buf,n*s+14), &items[i]);
#endif
#if PACKETVER >= 20080102
- WBUFL(buf,n*s+22)=stor->items[i].expire_time;
-#endif
- n++;
- }
- }
- if( n )
- {
-#if PACKETVER < 5
- WBUFW(buf,0)=0xa5;
-#elif PACKETVER < 20080102
- WBUFW(buf,0)=0x1f0;
-#else
- WBUFW(buf,0)=0x2ea;
-#endif
- WBUFW(buf,2)=4+n*s;
- clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
- }
- if( ne )
- {
-#if PACKETVER < 20071002
- WBUFW(bufe,0)=0xa6;
-#else
- WBUFW(bufe,0)=0x2d1;
-#endif
- WBUFW(bufe,2)=4+ne*cmd;
- clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
- }
-
- if( buf ) aFree(buf);
- if( bufe ) aFree(bufe);
-}
-
-//Unified storage function which sends all of the storage (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
-void clif_guildstoragelist(struct map_session_data *sd,struct guild_storage *stor)
-{
- struct item_data *id;
- int i,n,ne;
- unsigned char *buf;
- unsigned char *bufe;
-#if PACKETVER < 5
- const int s = 10; //Entry size.
-#elif PACKETVER < 20080102
- const int s = 18;
-#else
- const int s = 22;
-#endif
-#if PACKETVER < 20071002
- const int cmd = 20;
-#elif PACKETVER < 20100629
- const int cmd = 26;
-#else
- const int cmd = 28;
-#endif
-
- buf = (unsigned char*)aMallocA(MAX_GUILD_STORAGE * s + 4);
- bufe = (unsigned char*)aMallocA(MAX_GUILD_STORAGE * cmd + 4);
-
- for( i = 0, n = 0, ne = 0; i < MAX_GUILD_STORAGE; i++ )
- {
- if( stor->storage_[i].nameid <= 0 )
- continue;
- id = itemdb_search(stor->storage_[i].nameid);
- if( !itemdb_isstackable2(id) )
- { //Equippable
- WBUFW(bufe,ne*cmd+4)=i+1;
- clif_item_sub(bufe, ne*cmd+6, &stor->storage_[i], id, id->equip);
- clif_addcards(WBUFP(bufe, ne*cmd+16), &stor->storage_[i]);
-#if PACKETVER >= 20071002
- WBUFL(bufe,ne*cmd+24)=stor->storage_[i].expire_time;
- WBUFW(bufe,ne*cmd+28)=0; //Unknown
-#endif
- ne++;
- }
- else
- { //Stackable
- WBUFW(buf,n*s+4)=i+1;
- clif_item_sub(buf, n*s+6, &stor->storage_[i], id,-1);
-#if PACKETVER >= 5
- clif_addcards(WBUFP(buf,n*s+14), &stor->storage_[i]);
-#endif
-#if PACKETVER >= 20080102
- WBUFL(buf,n*s+22)=stor->storage_[i].expire_time;
+ WBUFL(buf,n*s+22)=items[i].expire_time;
#endif
n++;
}
@@ -3089,23 +2996,7 @@ int clif_misceffect(struct block_list* bl,int type)
return 0;
}
-int clif_misceffect2(struct block_list *bl, int type)
-{
- unsigned char buf[24];
-
- nullpo_ret(bl);
-
- memset(buf, 0, packet_len(0x1f3));
-
- WBUFW(buf,0) = 0x1f3;
- WBUFL(buf,2) = bl->id;
- WBUFL(buf,6) = type;
-
- clif_send(buf, packet_len(0x1f3), bl, AREA);
-
- return 0;
-}
/*==========================================
* 表示オプション変更
*------------------------------------------*/
@@ -3226,11 +3117,13 @@ int clif_useitemack(struct map_session_data *sd,int index,int amount,int ok)
return 0;
}
-/*==========================================
- * Inform client whether chatroom creation was successful or not
- * R 00d6 <fail>.B
- *------------------------------------------*/
-void clif_createchat(struct map_session_data* sd, int fail)
+/// Inform client whether chatroom creation was successful or not
+/// R 00d6 <flag>.B
+/// flag:
+/// 0 = Room has been successfully created (opens chat room)
+/// 1 = Room limit exceeded
+/// 2 = Same room already exists
+void clif_createchat(struct map_session_data* sd, int flag)
{
int fd;
@@ -3239,7 +3132,7 @@ void clif_createchat(struct map_session_data* sd, int fail)
fd = sd->fd;
WFIFOHEAD(fd,packet_len(0xd6));
WFIFOW(fd,0) = 0xd6;
- WFIFOB(fd,2) = fail;
+ WFIFOB(fd,2) = flag;
WFIFOSET(fd,packet_len(0xd6));
}
@@ -3327,10 +3220,18 @@ int clif_clearchat(struct chat_data *cd,int fd)
return 0;
}
-/*==========================================
- *
- *------------------------------------------*/
-int clif_joinchatfail(struct map_session_data *sd,int fail)
+/// Displays message (mostly) regarding join chat
+/// failures
+/// R 0x00da <flag>.B
+/// flag:
+/// 0 = The room is already full.
+/// 1 = Incorrect password, please try again.
+/// 2 = You have been kicked out of the room.
+/// 4 = You don't have enough money.
+/// 5 = You are not the required level.
+/// 6 = Too high level for this job.
+/// 7 = Not the suitable job for this type of work.
+int clif_joinchatfail(struct map_session_data *sd,int flag)
{
int fd;
@@ -3340,7 +3241,7 @@ int clif_joinchatfail(struct map_session_data *sd,int fail)
WFIFOHEAD(fd,packet_len(0xda));
WFIFOW(fd,0) = 0xda;
- WFIFOB(fd,2) = fail;
+ WFIFOB(fd,2) = flag;
WFIFOSET(fd,packet_len(0xda));
return 0;
@@ -3393,7 +3294,7 @@ int clif_addchat(struct chat_data* cd,struct map_session_data *sd)
/*==========================================
* Announce the new owner
- * R 00e1 <index>.l <nick>.24B
+ * R 00e1 <owner flag>.l <nick>.24B
*------------------------------------------*/
void clif_changechatowner(struct chat_data* cd, struct map_session_data* sd)
{
@@ -3405,6 +3306,8 @@ void clif_changechatowner(struct chat_data* cd, struct map_session_data* sd)
//FIXME: this announces a swap between positions 0 and 1 (probably not what we want) [ultramage]
//FIXME: aegis sends obviously incorrect packets; need to figure out what to send to display it correctly :X
//TODO: is it just owner swap, or can it do general-purpose reordering?
+ // It's not position, but operator flag, everyone set to 1 gets chat
+ // operator menu (yes, that means a chat may host multiple operators) [Ai4rei]
WBUFW(buf, 0) = 0xe1;
WBUFL(buf, 2) = 1;
@@ -3690,41 +3593,6 @@ void clif_updateguildstorageamount(struct map_session_data* sd, int amount)
}
/*==========================================
- *
- *------------------------------------------*/
-void clif_guildstorageitemadded(struct map_session_data* sd, struct item* i, int index, int amount)
-{
- int view,fd;
- unsigned char *buf;
-#if PACKETVER < 20090603
- const int cmd = 0xf4;
-#else
- const int cmd = 0x1c4;
-#endif
-
- nullpo_retv(sd);
- nullpo_retv(i);
- fd=sd->fd;
- view = itemdb_viewid(i->nameid);
- buf = WFIFOP(fd,0);
-
- WFIFOHEAD(fd,packet_len(cmd));
- WBUFW(buf, 0) = cmd; // Storage item added
- WBUFW(buf, 2) = index+1; // index
- WBUFL(buf, 4) = amount; // amount
- WBUFW(buf, 8) = ( view > 0 ) ? view : i->nameid; // id
-#if PACKETVER >= 20090603
- WBUFB(buf,10) = itemdb_type(i->nameid); //type
- buf = WBUFP(buf,1); //Advance 1B
-#endif
- WBUFB(buf,10) = i->identify; //identify flag
- WBUFB(buf,11) = i->attribute; // attribute
- WBUFB(buf,12) = i->refine; //refine
- clif_addcards(WBUFP(buf,13), i);
- WFIFOSET(fd,packet_len(cmd));
-}
-
-/*==========================================
* カプラ倉庫からアイテムを取り去る
*------------------------------------------*/
void clif_storageitemremoved(struct map_session_data* sd, int index, int amount)
@@ -3885,7 +3753,8 @@ 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
+ * R 008a <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.W <div>.W <type>.B <damage2>.W
+ * R 02e1 <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.L <div>.W <type>.B <damage2>.L
*
* type=00 damage [param1: total damage, param2: div, param3: assassin dual-wield damage]
* type=01 pick up item
@@ -4131,12 +4000,11 @@ void clif_skill_delunit(struct skill_unit *unit)
}
/*==========================================
- * Unknown... trap related?
- * Sent when an object gets ankle-snared
+ * Sent when an object gets ankle-snared (ZC_SKILL_UPDATE)
* Only affects units with class [139,153] client-side
* R 01ac <object id>.l
*------------------------------------------*/
-void clif_01ac(struct block_list* bl)
+void clif_skillunit_update(struct block_list* bl)
{
unsigned char buf[6];
nullpo_retv(bl);
@@ -4195,7 +4063,7 @@ int clif_outsight(struct block_list *bl,va_list ap)
switch(bl->type){
case BL_PC:
if (sd->vd.class_ != INVISIBLE_CLASS)
- clif_clearunit_single(bl->id,0,tsd->fd);
+ clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
if(sd->chatID){
struct chat_data *cd;
cd=(struct chat_data*)map_id2bl(sd->chatID);
@@ -4213,14 +4081,14 @@ int clif_outsight(struct block_list *bl,va_list ap)
break;
default:
if ((vd=status_get_viewdata(bl)) && vd->class_ != INVISIBLE_CLASS)
- clif_clearunit_single(bl->id,0,tsd->fd);
+ clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
break;
}
}
if (sd && sd->fd)
{ //sd is watching tbl go out of view.
if ((vd=status_get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS)
- clif_clearunit_single(tbl->id,0,sd->fd);
+ clif_clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd);
}
return 0;
}
@@ -4414,6 +4282,15 @@ int clif_skillup(struct map_session_data *sd,int skill_num)
/*==========================================
* スキル詠唱エフェクトを送信する
+ * pl:
+ * 0 = Yellow cast aura
+ * 1 = Water elemental cast aura
+ * 2 = Earth elemental cast aura
+ * 3 = Fire elemental cast aura
+ * 4 = Wind elemental cast aura
+ * 5 = Poison elemental cast aura
+ * 6 = White cast aura
+ * ? = like 0
*------------------------------------------*/
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)
@@ -7081,8 +6958,8 @@ int clif_guild_notice(struct map_session_data* sd, struct guild* g)
WFIFOHEAD(fd,packet_len(0x16f));
WFIFOW(fd,0) = 0x16f;
- memcpy(WFIFOP(fd,2), g->mes1, 60);
- memcpy(WFIFOP(fd,62), g->mes2, 120);
+ memcpy(WFIFOP(fd,2), g->mes1, MAX_GUILDMES1);
+ memcpy(WFIFOP(fd,62), g->mes2, MAX_GUILDMES2);
WFIFOSET(fd,packet_len(0x16f));
return 0;
}
@@ -7106,7 +6983,12 @@ int clif_guild_invite(struct map_session_data *sd,struct guild *g)
return 0;
}
/*==========================================
- * ギルドメンバ勧誘結果
+ * Reply to invite request
+ * Flag:
+ * 0 = Already in guild.
+ * 1 = Offer rejected.
+ * 2 = Offer accepted.
+ * 3 = Guild full.
*------------------------------------------*/
int clif_guild_inviteack(struct map_session_data *sd,int flag)
{
@@ -7285,7 +7167,11 @@ int clif_guild_delalliance(struct map_session_data *sd,int guild_id,int flag)
return 0;
}
/*==========================================
- * ギルド敵対結果
+ * Reply to opposition request
+ * Flag:
+ * 0 = Antagonist has been set.
+ * 1 = Guild has too many Antagonists.
+ * 2 = Already set as an Antagonist.
*------------------------------------------*/
int clif_guild_oppositionack(struct map_session_data *sd,int flag)
{
@@ -7579,20 +7465,17 @@ int clif_wisall(struct map_session_data *sd,int type,int flag)
/*==========================================
* Play a BGM! [Rikter/Yommy]
*------------------------------------------*/
-void clif_playBGM(struct map_session_data* sd, struct block_list* bl, const char* name)
+void clif_playBGM(struct map_session_data* sd, const char* name)
{
int fd;
nullpo_retv(sd);
- nullpo_retv(bl);
fd = sd->fd;
WFIFOHEAD(fd,packet_len(0x7fe));
WFIFOW(fd,0) = 0x7fe;
safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH);
WFIFOSET(fd,packet_len(0x7fe));
-
- return;
}
/*==========================================
@@ -7742,7 +7625,7 @@ int clif_refresh(struct map_session_data *sd)
if( pc_issit(sd) )
clif_sitting(&sd->bl); // FIXME: just send to self, not area
if( pc_isdead(sd) ) //When you refresh, resend the death packet.
- clif_clearunit_single(sd->bl.id,1,sd->fd);
+ clif_clearunit_single(sd->bl.id,CLR_DEAD,sd->fd);
else
clif_changed_dir(&sd->bl, SELF);
@@ -7928,6 +7811,9 @@ int clif_charnameupdate (struct map_session_data *ssd)
return 0;
}
+/// Visually moves(instant) a character to x,y. The char moves even
+/// when the target cell isn't walkable. If the char is sitting it
+/// stays that way.
void clif_slide(struct block_list *bl, int x, int y)
{
unsigned char buf[10];
@@ -8014,21 +7900,58 @@ void clif_gospel_info(struct map_session_data *sd, int type)
WFIFOSET(fd, packet_len(0x215));
}
+
+/// Multi purpose mission information packet (ZC_STARSKILL).
+/// 0x20e <mapname>.24B <monster_id>.L <star>.B <result>.B
+/// result:
+/// 0 = Star Gladiator %s has designed <mapname>'s as the %s.
+/// star:
+/// 0 = Place of the Sun
+/// 1 = Place of the Moon
+/// 2 = Place of the Stars
+/// 1 = Star Gladiator %s's %s: <mapname>
+/// star:
+/// 0 = Place of the Sun
+/// 1 = Place of the Moon
+/// 2 = Place of the Stars
+/// 10 = Star Gladiator %s has designed <mapname>'s as the %s.
+/// star:
+/// 0 = Target of the Sun
+/// 1 = Target of the Moon
+/// 2 = Target of the Stars
+/// 11 = Star Gladiator %s's %s: <mapname used as monster name>
+/// star:
+/// 0 = Monster of the Sun
+/// 1 = Monster of the Moon
+/// 2 = Monster of the Stars
+/// 20 = [TaeKwon Mission] Target Monster : <mapname used as monster name> (<star>%)
+/// 21 = [Taming Mission] Target Monster : <mapname used as monster name>
+/// 22 = [Collector Rank] Target Item : <monster_id used as item id>
+/// 30 = [Sun, Moon and Stars Angel] Designed places and monsters have been reset.
+/// 40 = Target HP : <monster_id used as HP>
+void clif_starskill(struct map_session_data* sd, const char* mapname, int monster_id, unsigned char star, unsigned char result)
+{
+ int fd = sd->fd;
+
+ WFIFOHEAD(fd,packet_len(0x20e));
+ WFIFOW(fd,0) = 0x20e;
+ safestrncpy((char*)WFIFOP(fd,2), mapname, NAME_LENGTH);
+ WFIFOL(fd,26) = monster_id;
+ WFIFOB(fd,30) = star;
+ WFIFOB(fd,31) = result;
+ WFIFOSET(fd,packet_len(0x20e));
+}
+
/*==========================================
* Info about Star Glaldiator save map [Komurka]
* type: 1: Information, 0: Map registered
*------------------------------------------*/
void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsigned char type)
{
- int fd=sd->fd;
+ char mapname[MAP_NAME_LENGTH_EXT];
- WFIFOHEAD(fd,packet_len(0x20e));
- WFIFOW(fd,0) = 0x20e;
- mapindex_getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), (char*)WFIFOP(fd,2));
- WFIFOL(fd,26) = sd->bl.id;
- WFIFOB(fd,30) = feel_level;
- WFIFOB(fd,31) = type?1:0;
- WFIFOSET(fd,packet_len(0x20e));
+ mapindex_getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), mapname);
+ clif_starskill(sd, mapname, 0, feel_level, type ? 1 : 0);
}
/*==========================================
@@ -8037,19 +7960,18 @@ void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsig
*------------------------------------------*/
void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int class_, unsigned char type)
{
- int fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x20e));
- WFIFOW(fd,0)=0x20e;
- if (pcdb_checkid(class_))
- strncpy((char*)WFIFOP(fd,2),job_name(class_), NAME_LENGTH);
- else if (mobdb_checkid(class_))
- strncpy((char*)WFIFOP(fd,2),mob_db(class_)->jname, NAME_LENGTH);
- else //Really shouldn't happen...
- memset(WFIFOP(fd,2), 0, NAME_LENGTH);
- WFIFOL(fd,26)=sd->bl.id;
- WFIFOB(fd,30)=hate_level;
- WFIFOB(fd,31)=type?10:11; //Register/Info
- WFIFOSET(fd, packet_len(0x20e));
+ if( pcdb_checkid(class_) )
+ {
+ clif_starskill(sd, job_name(class_), class_, hate_level, type ? 10 : 11);
+ }
+ else if( mobdb_checkid(class_) )
+ {
+ clif_starskill(sd, mob_db(class_)->jname, class_, hate_level, type ? 10 : 11);
+ }
+ else
+ {
+ ShowWarning("clif_hate_info: Received invalid class %d for this packet (char_id=%d, hate_level=%u, type=%u).\n", class_, sd->status.char_id, (unsigned int)hate_level, (unsigned int)type);
+ }
}
/*==========================================
@@ -8057,14 +7979,7 @@ void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int cl
*------------------------------------------*/
void clif_mission_info(struct map_session_data *sd, int mob_id, unsigned char progress)
{
- int fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x20e));
- WFIFOW(fd,0)=0x20e;
- strncpy((char*)WFIFOP(fd,2),mob_db(mob_id)->jname, NAME_LENGTH);
- WFIFOL(fd,26)=mob_id;
- WFIFOB(fd,30)=progress; //Message to display
- WFIFOB(fd,31)=20;
- WFIFOSET(fd, packet_len(0x20e));
+ clif_starskill(sd, mob_db(mob_id)->jname, mob_id, progress, 20);
}
/*==========================================
@@ -8072,14 +7987,7 @@ void clif_mission_info(struct map_session_data *sd, int mob_id, unsigned char pr
*------------------------------------------*/
void clif_feel_hate_reset(struct map_session_data *sd)
{
- int fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0x20e));
- WFIFOW(fd,0)=0x20e;
- memset(WFIFOP(fd,2), 0, NAME_LENGTH); //Blank name as all was reset.
- WFIFOL(fd,26)=sd->bl.id;
- WFIFOB(fd,30)=0; //Feel/hate level: irrelevant
- WFIFOB(fd,31)=30;
- WFIFOSET(fd, packet_len(0x20e));
+ clif_starskill(sd, "", 0, 0, 30);
}
/*==========================================
@@ -8175,12 +8083,9 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts
WFIFOSET(fd, WFIFOW(fd, 2));
}
-/*==========================================
- * View player equip request denied
- * R 0291 <message>.W
- * TODO: this looks like a general-purpose packet to print msgstringtable entries.
- *------------------------------------------*/
-void clif_viewequip_fail(struct map_session_data* sd)
+/// Display msgstringtable.txt string (ZC_MSG)
+/// R 0291 <message>.W
+void clif_msg(struct map_session_data* sd, unsigned short id)
{
int fd;
nullpo_retv(sd);
@@ -8188,10 +8093,16 @@ void clif_viewequip_fail(struct map_session_data* sd)
WFIFOHEAD(fd, packet_len(0x291));
WFIFOW(fd, 0) = 0x291;
- WFIFOW(fd, 2) = 0x54d; // This controls which message is displayed. 0x54d is the correct one. Maybe it's used for something else too?
+ WFIFOW(fd, 2) = id; // zero-based msgstringtable.txt index
WFIFOSET(fd, packet_len(0x291));
}
+/// View player equip request denied
+void clif_viewequip_fail(struct map_session_data* sd)
+{
+ clif_msg(sd, 0x54d);
+}
+
/// Validates one global/guild/party/whisper message packet and tries to recognize its components.
/// Returns true if the packet was parsed successfully.
/// Formats: 0 - <packet id>.w <packet len>.w (<name> : <message>).?B 00
@@ -8329,6 +8240,10 @@ static int clif_guess_PacketVer(int fd, int get_previous, int *error)
err = n;\
//define SET_ERROR
+ // FIXME: If the packet is not received at once, this will FAIL.
+ // Figure out, when it happens, that only part of the packet is
+ // received, or fix the function to be able to deal with that
+ // case.
#define CHECK_PACKET_VER() \
if( cmd != clif_config.connect_cmd[packet_ver] || packet_len != packet_db[packet_ver][cmd].len )\
;/* not wanttoconnection or wrong length */\
@@ -8561,20 +8476,22 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
// must use foreachinarea (CIRCULAR_AREA interferes with foreachinrange)
map_foreachinarea(clif_getareachar, sd->bl.m, sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, BL_ALL, sd);
- //TODO: merge it with the code below
- if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m) && sd->pd)
- { //Return the pet to egg. [Skotlex]
- clif_displaymessage(sd->fd, "Pets are not allowed in Guild Wars.");
- pet_menu(sd, 3); //Option 3 is return to egg.
- }
-
// pet
- if(sd->pd) {
- map_addblock(&sd->pd->bl);
- clif_spawn(&sd->pd->bl);
- clif_send_petdata(sd,sd->pd,0,0);
- clif_send_petstatus(sd);
-// skill_unit_move(&sd->pd->bl,gettick(),1);
+ if( sd->pd )
+ {
+ if( battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m) )
+ { //Return the pet to egg. [Skotlex]
+ clif_displaymessage(sd->fd, "Pets are not allowed in Guild Wars.");
+ pet_menu(sd, 3); //Option 3 is return to egg.
+ }
+ else
+ {
+ map_addblock(&sd->pd->bl);
+ clif_spawn(&sd->pd->bl);
+ clif_send_petdata(sd,sd->pd,0,0);
+ clif_send_petstatus(sd);
+// skill_unit_move(&sd->pd->bl,gettick(),1);
+ }
}
//homunculus [blackhole89]
@@ -8605,7 +8522,9 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
sd->state.connect_new = 0;
clif_skillinfoblock(sd);
clif_hotkeys_send(sd);
+ clif_updatestatus(sd,SP_BASEEXP);
clif_updatestatus(sd,SP_NEXTBASEEXP);
+ clif_updatestatus(sd,SP_JOBEXP);
clif_updatestatus(sd,SP_NEXTJOBEXP);
clif_updatestatus(sd,SP_SKILLPOINT);
clif_initialstatus(sd);
@@ -8720,7 +8639,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
// If player is dead, and is spawned (such as @refresh) send death packet. [Valaris]
if(pc_isdead(sd))
- clif_clearunit_area(&sd->bl, 1);
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
// Uncomment if you want to make player face in the same direction he was facing right before warping. [Skotlex]
// else
// clif_changed_dir(&sd->bl, SELF);
@@ -8821,7 +8740,7 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
int cmd;
if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl, 1);
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
return;
}
@@ -8940,6 +8859,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
WFIFOW(fd,2) = 8 + textlen;
WFIFOL(fd,4) = sd->bl.id;
safestrncpy((char*)WFIFOP(fd,8), text, textlen);
+ //FIXME: chat has range of 9 only
clif_send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
// send back message to the speaker
@@ -9063,10 +8983,10 @@ void clif_parse_ChangeDir(int fd, struct map_session_data *sd)
*------------------------------------------*/
void clif_parse_Emotion(int fd, struct map_session_data *sd)
{
- unsigned char buf[64];
+ int emoticon = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 2) {
- if (RFIFOB(fd,2) == 34) {// prevent use of the mute emote [Valaris]
+ if (emoticon == E_MUTE) {// prevent use of the mute emote [Valaris]
clif_skill_fail(sd, 1, 0, 1);
return;
}
@@ -9077,11 +8997,13 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd)
return;
}
sd->emotionlasttime = time(NULL) + 1; // not more than 1 per second (using /commands the client can spam it)
-
- WBUFW(buf,0) = 0xc0;
- WBUFL(buf,2) = sd->bl.id;
- WBUFB(buf,6) = RFIFOB(fd,2);
- clif_send(buf, packet_len(0xc0), &sd->bl, AREA);
+
+ if(battle_config.client_reshuffle_dice && emoticon>=E_DICE1 && emoticon<=E_DICE6)
+ {// re-roll dice
+ emoticon = rand()%6+E_DICE1;
+ }
+
+ clif_emotion(&sd->bl, emoticon);
} else
clif_skill_fail(sd, 1, 0, 1);
}
@@ -9100,7 +9022,7 @@ void clif_parse_HowManyConnections(int fd, struct map_session_data *sd)
void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, unsigned int tick)
{
if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl, 1);
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
return;
}
@@ -9198,7 +9120,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd)
{
switch(RFIFOB(fd,2)) {
case 0x00:
- pc_respawn(sd,2);
+ pc_respawn(sd,CLR_RESPAWN);
break;
case 0x01:
/* Rovert's Prevent logout option - Fixed [Valaris] */
@@ -9219,7 +9141,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd)
/*==========================================
* Validates and processes whispered messages
- * S 0096 <packet len>.w <nick>.23B 00 <message>.?B
+ * S 0096 <packet len>.w <nick>.24B <message>.?B
*------------------------------------------*/
void clif_parse_WisMessage(int fd, struct map_session_data* sd)
{
@@ -9416,7 +9338,7 @@ void clif_parse_TakeItem(int fd, struct map_session_data *sd)
do {
if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl, 1);
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
break;
}
@@ -9451,7 +9373,8 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd)
{
int item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
int item_amount = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
- do {
+
+ for(;;) {
if (pc_isdead(sd))
break;
@@ -9469,7 +9392,7 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd)
break;
return;
- } while (0);
+ }
//Because the client does not like being ignored.
clif_dropitem(sd, item_index,0);
@@ -9483,7 +9406,7 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd)
int n;
if (pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl, 1);
+ clif_clearunit_area(&sd->bl, CLR_DEAD);
return;
}
@@ -9516,7 +9439,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
int index;
if(pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl,1);
+ clif_clearunit_area(&sd->bl,CLR_DEAD);
return;
}
index = RFIFOW(fd,2)-2;
@@ -9559,7 +9482,7 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
int index;
if(pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl,1);
+ clif_clearunit_area(&sd->bl,CLR_DEAD);
return;
}
@@ -9581,7 +9504,7 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
struct block_list *bl;
if(pc_isdead(sd)) {
- clif_clearunit_area(&sd->bl,1);
+ clif_clearunit_area(&sd->bl,CLR_DEAD);
return;
}
@@ -9592,8 +9515,6 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
if (!bl) return;
switch (bl->type) {
case BL_MOB:
- clif_parse_ActionRequest_sub(sd, 0x07, bl->id, gettick());
- break;
case BL_PC:
clif_parse_ActionRequest_sub(sd, 0x07, bl->id, gettick());
break;
@@ -10260,6 +10181,11 @@ void clif_parse_Cooking(int fd,struct map_session_data *sd)
//int type = RFIFOW(fd,2); // '1' for cooking, but what do other values mean?
int nameid = RFIFOW(fd,4);
+ if( sd->menuskill_id != AM_PHARMACY )
+ {
+ return;
+ }
+
if (pc_istrading(sd)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif_skill_fail(sd,sd->ud.skillid,0,0);
@@ -10379,9 +10305,15 @@ void clif_parse_NpcCloseClicked(int fd,struct map_session_data *sd)
*------------------------------------------*/
void clif_parse_ItemIdentify(int fd,struct map_session_data *sd)
{
+ short idx = RFIFOW(fd,2);
+
if (sd->menuskill_id != MC_IDENTIFY)
return;
- skill_identify(sd,RFIFOW(fd,2)-2);
+ if( idx == -1 )
+ {// cancel pressed
+ return;
+ }
+ skill_identify(sd,idx-2);
sd->menuskill_val = sd->menuskill_id = 0;
}
/*==========================================
@@ -10585,7 +10517,7 @@ void clif_parse_StoragePassword(int fd, struct map_session_data *sd)
/*==========================================
* Party creation request
* S 00f9 <party name>.24S
- * S 01e8 <party name>.24S <item1>.B <item2>.B
+ * S 01e8 <party name>.24S <share flag>.B <share type>.B
*------------------------------------------*/
void clif_parse_CreateParty(int fd, struct map_session_data *sd)
{
@@ -10796,10 +10728,10 @@ void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data* sd)
{
short level = RFIFOW(fd,2);
short mapid = RFIFOW(fd,4);
- short job[6];
+ short job[PARTY_BOOKING_JOBS];
int i;
- for(i=0; i<6; i++)
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
job[i] = RFIFOB(fd,6+i*2);
party_booking_register(sd, level, mapid, job);
@@ -10832,7 +10764,7 @@ void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data* sd)
/*==========================================
* more_result: 0 - no more, 1 - more
*------------------------------------------*/
-void clif_PartyBookingSearchAck(int fd, unsigned long *index, int count, bool more_result)
+void clif_PartyBookingSearchAck(int fd, struct party_booking_ad_info** results, int count, bool more_result)
{
int i, j;
int size = sizeof(struct party_booking_ad_info); // structure size (48)
@@ -10840,17 +10772,16 @@ void clif_PartyBookingSearchAck(int fd, unsigned long *index, int count, bool mo
WFIFOHEAD(fd,size*count + 5);
WFIFOW(fd,0) = 0x805;
WFIFOW(fd,2) = size*count + 5;
- WFIFOB(fd,4) = (bool)more_result;
+ WFIFOB(fd,4) = more_result;
for(i=0; i<count; i++)
{
- pb_ad = party_booking_getdata(index[i]);
- if(pb_ad == NULL) return;
+ pb_ad = results[i];
WFIFOL(fd,i*size+5) = pb_ad->index;
memcpy(WFIFOP(fd,i*size+9),pb_ad->charname,NAME_LENGTH);
WFIFOL(fd,i*size+33) = pb_ad->starttime;
WFIFOW(fd,i*size+37) = pb_ad->p_detail.level;
WFIFOW(fd,i*size+39) = pb_ad->p_detail.mapid;
- for(j=0; j<6; j++)
+ for(j=0; j<PARTY_BOOKING_JOBS; j++)
WFIFOW(fd,i*size+41+j*2) = pb_ad->p_detail.job[j];
}
WFIFOSET(fd,WFIFOW(fd,2));
@@ -10858,7 +10789,7 @@ void clif_PartyBookingSearchAck(int fd, unsigned long *index, int count, bool mo
void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data* sd)
{
- if(party_booking_delete(sd, false))
+ if(party_booking_delete(sd))
clif_PartyBookingDeleteAck(sd, 0);
}
@@ -10877,10 +10808,10 @@ void clif_PartyBookingDeleteAck(struct map_session_data* sd, int flag)
void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data* sd)
{
- short job[6];
+ short job[PARTY_BOOKING_JOBS];
int i;
- for(i=0; i<6; i++)
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
job[i] = RFIFOW(fd,2+i*2);
party_booking_update(sd, job);
@@ -10889,32 +10820,32 @@ void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data* sd)
void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad)
{
int i;
+ uint8 buf[38+PARTY_BOOKING_JOBS*2];
if(pb_ad == NULL) return;
- WFIFOHEAD(sd->fd,packet_len(0x809));
- WFIFOW(sd->fd,0) = 0x809;
- WFIFOL(sd->fd,2) = pb_ad->index;
- memcpy(WFIFOP(sd->fd,6),pb_ad->charname,NAME_LENGTH);
- WFIFOL(sd->fd,30) = pb_ad->starttime;
- WFIFOW(sd->fd,34) = pb_ad->p_detail.level;
- WFIFOW(sd->fd,36) = pb_ad->p_detail.mapid;
- for(i=0; i<6; i++)
- WFIFOW(sd->fd,38+i*2) = pb_ad->p_detail.job[i];
+ WBUFW(buf,0) = 0x809;
+ WBUFL(buf,2) = pb_ad->index;
+ memcpy(WBUFP(buf,6),pb_ad->charname,NAME_LENGTH);
+ WBUFL(buf,30) = pb_ad->starttime;
+ WBUFW(buf,34) = pb_ad->p_detail.level;
+ WBUFW(buf,36) = pb_ad->p_detail.mapid;
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
+ WBUFW(buf,38+i*2) = pb_ad->p_detail.job[i];
- WFIFOSET(sd->fd,packet_len(0x809));
+ clif_send(buf, packet_len(0x809), &sd->bl, ALL_CLIENT);
}
void clif_PartyBookingUpdateNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad)
{
int i;
- uint8 buf[18];
+ uint8 buf[6+PARTY_BOOKING_JOBS*2];
if(pb_ad == NULL) return;
WBUFW(buf,0) = 0x80a;
WBUFL(buf,2) = pb_ad->index;
- for(i=0; i<6; i++)
+ for(i=0; i<PARTY_BOOKING_JOBS; i++)
WBUFW(buf,6+i*2) = pb_ad->p_detail.job[i];
clif_send(buf,packet_len(0x80a),&sd->bl,ALL_CLIENT); // Now UPDATE all client.
}
@@ -10941,10 +10872,11 @@ void clif_parse_CloseVending(int fd, struct map_session_data* sd)
*------------------------------------------*/
void clif_parse_VendingListReq(int fd, struct map_session_data* sd)
{
- vending_vendinglistreq(sd,RFIFOL(fd,2));
-
if( sd->npc_id )
- npc_event_dequeue(sd);
+ {// using an NPC
+ return;
+ }
+ vending_vendinglistreq(sd,RFIFOL(fd,2));
}
/*==========================================
@@ -11075,6 +11007,7 @@ void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd)
/*==========================================
* ギルドメンバ役職変更
+ * S 0155 <packet len>.W {<account id>.L <char id>.L <idx>.L}
*------------------------------------------*/
void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd)
{
@@ -11103,6 +11036,7 @@ void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd)
/*==========================================
* ギルドエンブレム変更
+ * S 0153 <packet len>.W <emblem data>.?B
*------------------------------------------*/
void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd)
{
@@ -11128,7 +11062,7 @@ void clif_parse_GuildChangeNotice(int fd, struct map_session_data* sd)
// compensate for some client defects when using multilanguage mode
if (msg1[0] == '|' && msg1[3] == '|') msg1+= 3; // skip duplicate marker
if (msg2[0] == '|' && msg2[3] == '|') msg2+= 3; // skip duplicate marker
- if (msg2[0] == '|') msg2[strnlen(msg2, 120)-1] = '\0'; // delete extra space at the end of string
+ if (msg2[0] == '|') msg2[strnlen(msg2, MAX_GUILDMES2)-1] = '\0'; // delete extra space at the end of string
guild_change_notice(sd, guild_id, msg1, msg2);
}
@@ -11186,7 +11120,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd)
/*==========================================
* Request to expel a member of a guild
- * S 015b <guild_id>.L <account_id>.L <char_id>.L <reason>.39B 00
+ * S 015b <guild_id>.L <account_id>.L <char_id>.L <reason>.40B
*------------------------------------------*/
void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd)
{
@@ -11458,10 +11392,11 @@ void clif_parse_GMKickAll(int fd, struct map_session_data* sd)
}
/*==========================================
- * /shift <name>
+ * /remove <account name>
+ * /shift <char name>
*------------------------------------------*/
void clif_parse_GMShift(int fd, struct map_session_data *sd)
-{
+{// FIXME: remove is supposed to receive account name for clients prior 20100803RE
char *player_name;
int lv;
@@ -11480,11 +11415,47 @@ void clif_parse_GMShift(int fd, struct map_session_data *sd)
}
}
+
+/// Warps oneself to the location of the character given by account id ( /remove <account id> ).
+/// R 0843 <account id>.L
+void clif_parse_GMRemove2(int fd, struct map_session_data* sd)
+{
+ int account_id, lv;
+ struct map_session_data* pl_sd;
+
+ if( battle_config.atc_gmonly && !pc_isGM(sd) )
+ {
+ return;
+ }
+
+ if( pc_isGM(sd) < ( lv = get_atcommand_level(atcommand_jumpto) ) )
+ {
+ return;
+ }
+
+ account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+
+ if( ( pl_sd = map_id2sd(account_id) ) != NULL && pc_isGM(sd) >= pc_isGM(pl_sd) )
+ {
+ pc_warpto(sd, pl_sd);
+ }
+
+ if( log_config.gm && lv >= log_config.gm )
+ {
+ char message[32];
+
+ sprintf(message, "/remove %d", account_id);
+ log_atcommand(sd, message);
+ }
+}
+
+
/*==========================================
- * /recall <name>
+ * /recall <account name>
+ * /summon <char name>
*------------------------------------------*/
void clif_parse_GMRecall(int fd, struct map_session_data *sd)
-{
+{// FIXME: recall is supposed to receive account name for clients prior 20100803RE
char *player_name;
int lv;
@@ -11504,8 +11475,44 @@ void clif_parse_GMRecall(int fd, struct map_session_data *sd)
}
}
+
+/// Summons a character given by account id to one's own position ( /recall <account id> )
+/// R 0842 <account id>.L
+void clif_parse_GMRecall2(int fd, struct map_session_data* sd)
+{
+ int account_id, lv;
+ struct map_session_data* pl_sd;
+
+ if( battle_config.atc_gmonly && !pc_isGM(sd) )
+ {
+ return;
+ }
+
+ if( pc_isGM(sd) < ( lv = get_atcommand_level(atcommand_recall) ) )
+ {
+ return;
+ }
+
+ account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
+
+ if( ( pl_sd = map_id2sd(account_id) ) != NULL && pc_isGM(sd) >= pc_isGM(pl_sd) )
+ {
+ pc_recall(sd, pl_sd);
+ }
+
+ if( log_config.gm && lv >= log_config.gm )
+ {
+ char message[32];
+
+ sprintf(message, "/recall %d", account_id);
+ log_atcommand(sd, message);
+ }
+}
+
+
/*==========================================
* /monster /item
+ * R 01F3 <name>.24B
*------------------------------------------*/
void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
{
@@ -11663,11 +11670,11 @@ void clif_parse_GMReqAccountName(int fd, struct map_session_data *sd)
/*==========================================
* GM single cell type change request
- * /changemaptype <x> <y> <type>
+ * /changemaptype <x> <y> <type:0-1>
* S 0198 <x>.W <y>.W <gat>.W
*------------------------------------------*/
void clif_parse_GMChangeMapType(int fd, struct map_session_data *sd)
-{
+{// FIXME: type sent by client is 0 or 1 (even if you enter 2+); that suggests, that it is walkable gat attribute
int x,y,type;
if( battle_config.atc_gmonly && !pc_isGM(sd) )
@@ -12107,6 +12114,7 @@ void clif_parse_PVPInfo(int fd,struct map_session_data *sd)
/*==========================================
* /blacksmith
+ * S 0217
*------------------------------------------*/
void clif_parse_Blacksmith(int fd,struct map_session_data *sd)
{
@@ -12150,6 +12158,7 @@ int clif_fame_blacksmith(struct map_session_data *sd, int points)
/*==========================================
* /alchemist
+ * S 0218
*------------------------------------------*/
void clif_parse_Alchemist(int fd,struct map_session_data *sd)
{
@@ -12193,6 +12202,7 @@ int clif_fame_alchemist(struct map_session_data *sd, int points)
/*==========================================
* /taekwon
+ * S 0225
*------------------------------------------*/
void clif_parse_Taekwon(int fd,struct map_session_data *sd)
{
@@ -12234,7 +12244,8 @@ int clif_fame_taekwon(struct map_session_data *sd, int points)
}
/*==========================================
- * PK Ranking table?
+ * /pk
+ * S 0237
*------------------------------------------*/
void clif_parse_RankingPk(int fd,struct map_session_data *sd)
{
@@ -12259,7 +12270,7 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
if (sd->menuskill_id != SG_FEEL)
return;
i = sd->menuskill_val-1;
- if (i<0 || i > 2) return; //Bug?
+ if (i<0 || i >= MAX_PC_FEELHATE) return; //Bug?
sd->feel_map[i].index = map_id2index(sd->bl.m);
sd->feel_map[i].m = sd->bl.m;
@@ -12738,9 +12749,10 @@ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd)
/*------------------------------------------
* Mail Window Operation
+ * S 0246 <flag>.W
* 0 : Switch to 'new mail' window, or Close mailbox
* 1 : ???
- * 2 : ???
+ * 2 : Zeny entering start
*------------------------------------------*/
void clif_parse_Mail_winopen(int fd, struct map_session_data *sd)
{
@@ -13592,12 +13604,9 @@ void clif_parse_mercenary_action(int fd, struct map_session_data* sd)
* 2 = Your mercenary soldier has been fired.
* 3 = Your mercenary soldier has ran away.
*------------------------------------------*/
-void clif_mercenary_message(int fd, int message)
+void clif_mercenary_message(struct map_session_data* sd, int message)
{
- WFIFOHEAD(fd,4);
- WFIFOW(fd,0) = 0x0291;
- WFIFOW(fd,2) = 1266 + message;
- WFIFOSET(fd,4);
+ clif_msg(sd, 1266 + message);
}
/*------------------------------------------
@@ -13959,6 +13968,23 @@ void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, b
return;
}
+/// Displays digital clock digits on top of the screen (ZC_SHOWDIGIT).
+/// type:
+/// 0: Displays 'value' for 5 seconds.
+/// 1: Incremental counter (1 tick/second), negated 'value' specifies start value (e.g. using -10 lets the counter start at 10).
+/// 2: Decremental counter (1 tick/second), negated 'value' specifies start value (does not stop when reaching 0, but overflows).
+/// 3: Decremental counter (2 ticks/second), 'value' specifies start value (stops when reaching 0, displays at most 2 digits).
+/// value:
+/// Except for type 3 it is interpreted as seconds for displaying as DD:HH:MM:SS, HH:MM:SS, MM:SS or SS (leftmost '00' is not displayed).
+void clif_showdigit(struct map_session_data* sd, unsigned char type, int value)
+{
+ WFIFOHEAD(sd->fd, packet_len(0x1b1));
+ WFIFOW(sd->fd,0) = 0x1b1;
+ WFIFOB(sd->fd,0) = type;
+ WFIFOL(sd->fd,0) = value;
+ WFIFOSET(sd->fd, packet_len(0x1b1));
+}
+
/*==========================================
* パケットデバッグ
*------------------------------------------*/
@@ -13987,10 +14013,10 @@ int clif_parse(int fd)
TBL_PC* sd;
int pnum;
- //TODO apply deplays or disconnect based on packet throughput [FlavioJS]
+ //TODO apply delays or disconnect based on packet throughput [FlavioJS]
// Note: "click masters" can do 80+ clicks in 10 seconds
- for( pnum = 0; pnum < 3; ++pnum )// Limit max packets per cycle to 3 (delay packet spammers) [FlavioJS]
+ for( pnum = 0; pnum < 3; ++pnum )// Limit max packets per cycle to 3 (delay packet spammers) [FlavioJS] -- This actually aids packet spammers, but stuff like /str+ gets slow without it [Ai4rei]
{ // begin main client packet processing loop
sd = (TBL_PC *)session[fd]->session_data;
@@ -14491,6 +14517,8 @@ static int packetdb_readdb(void)
{clif_parse_GMShift,"shift"},
{clif_parse_GMChangeMapType,"changemaptype"},
{clif_parse_GMRc,"rc"},
+ {clif_parse_GMRecall2,"recall2"},
+ {clif_parse_GMRemove2,"remove2"},
{clif_parse_NoviceDoriDori,"sndoridori"},
{clif_parse_NoviceExplosionSpirits,"snexplosionspirits"},