summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c2
-rw-r--r--src/char/int_guild.c11
-rw-r--r--src/common/HPMDataCheck.h6
-rw-r--r--src/common/mmo.h17
-rw-r--r--src/map/clif.c211
-rw-r--r--src/map/clif.h4
-rw-r--r--src/map/guild.c4
-rw-r--r--src/map/guild.h2
-rw-r--r--src/map/intif.c4
-rw-r--r--src/map/packets.h23
-rw-r--r--src/map/packets_keys_main.h12
-rw-r--r--src/map/packets_keys_zero.h12
-rw-r--r--src/map/packets_shuffle_main.h40
-rw-r--r--src/map/packets_shuffle_zero.h40
-rw-r--r--src/map/packets_struct.h111
-rw-r--r--src/map/pc.c1
-rw-r--r--src/map/pc.h3
-rw-r--r--src/map/quest.c8
-rw-r--r--src/map/script.c43
-rw-r--r--src/map/unit.c1
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc10
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc12
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc3
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc90
24 files changed, 601 insertions, 69 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 0069e7f1d..93fb1be75 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -3328,7 +3328,7 @@ void char_char_name_ack(int fd, int char_id)
WFIFOHEAD(fd,30);
WFIFOW(fd,0) = 0x2b09;
WFIFOL(fd,2) = char_id;
-#if !defined(PACKETVER_ZERO) && (PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221))
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
if (chr->loadName(char_id, WFIFOP(fd,6)) == 0)
WFIFOL(fd, 6) = 0;
#else
diff --git a/src/char/int_guild.c b/src/char/int_guild.c
index 0102f11a0..3f34e883b 100644
--- a/src/char/int_guild.c
+++ b/src/char/int_guild.c
@@ -417,8 +417,8 @@ struct guild * inter_guild_fromsql(int guild_id)
}
// load guild member info
- if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name` "
- "FROM `%s` WHERE `guild_id`='%d' ORDER BY `position`", guild_member_db, guild_id) )
+ if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT g.`account_id`,g.`char_id`,g.`hair`,g.`hair_color`,g.`gender`,g.`class`,g.`lv`,g.`exp`,g.`exp_payper`,g.`online`,g.`position`,g.`name`,c.`last_login`"
+ "FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d' ORDER BY `position`", guild_member_db, char_db, guild_id) )
{
Sql_ShowDebug(inter->sql_handle);
aFree(g);
@@ -442,6 +442,7 @@ struct guild * inter_guild_fromsql(int guild_id)
if( m->position >= MAX_GUILDPOSITION ) // Fix reduction of MAX_GUILDPOSITION [PoW]
m->position = MAX_GUILDPOSITION - 1;
SQL->GetData(inter->sql_handle, 11, &data, &len); memcpy(m->name, data, min(len, NAME_LENGTH));
+ SQL->GetData(inter->sql_handle, 12, &data, NULL); m->last_login = atoi(data);
m->modified = GS_MEMBER_UNMODIFIED;
}
@@ -975,7 +976,7 @@ int mapif_guild_withdraw(int guild_id,int account_id,int char_id,int flag, const
// Send short member's info
int mapif_guild_memberinfoshort(struct guild *g, int idx)
{
- unsigned char buf[19];
+ unsigned char buf[23];
nullpo_ret(g);
Assert_ret(idx >= 0 && idx < MAX_GUILD);
WBUFW(buf, 0)=0x3835;
@@ -985,7 +986,8 @@ int mapif_guild_memberinfoshort(struct guild *g, int idx)
WBUFB(buf,14)=(unsigned char)g->member[idx].online;
WBUFW(buf,15)=g->member[idx].lv;
WBUFW(buf,17)=g->member[idx].class;
- mapif->sendall(buf,19);
+ WBUFL(buf,19)=g->member[idx].last_login;
+ mapif->sendall(buf,23);
return 0;
}
@@ -1366,6 +1368,7 @@ int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id,
g->member[i].online = online;
g->member[i].lv = lv;
g->member[i].class = class;
+ g->member[i].last_login = (uint32)time(NULL);
g->member[i].modified = GS_MEMBER_MODIFIED;
mapif->guild_memberinfoshort(g,i);
}
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index 4bcb33e23..30cb01857 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -656,8 +656,14 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "packet_npc_market_result_ack", sizeof(struct packet_npc_market_result_ack), SERVER_TYPE_MAP },
{ "packet_package_item_announce", sizeof(struct packet_package_item_announce), SERVER_TYPE_MAP },
{ "packet_party_leader_changed", sizeof(struct packet_party_leader_changed), SERVER_TYPE_MAP },
+ { "packet_quest_add_header", sizeof(struct packet_quest_add_header), SERVER_TYPE_MAP },
+ { "packet_quest_hunt_info", sizeof(struct packet_quest_hunt_info), SERVER_TYPE_MAP },
+ { "packet_quest_hunt_info_sub", sizeof(struct packet_quest_hunt_info_sub), SERVER_TYPE_MAP },
+ { "packet_quest_hunt_sub", sizeof(struct packet_quest_hunt_sub), SERVER_TYPE_MAP },
{ "packet_quest_list_header", sizeof(struct packet_quest_list_header), SERVER_TYPE_MAP },
{ "packet_quest_list_info", sizeof(struct packet_quest_list_info), SERVER_TYPE_MAP },
+ { "packet_quest_update_header", sizeof(struct packet_quest_update_header), SERVER_TYPE_MAP },
+ { "packet_quest_update_hunt", sizeof(struct packet_quest_update_hunt), SERVER_TYPE_MAP },
{ "packet_roulette_close_ack", sizeof(struct packet_roulette_close_ack), SERVER_TYPE_MAP },
{ "packet_roulette_generate_ack", sizeof(struct packet_roulette_generate_ack), SERVER_TYPE_MAP },
{ "packet_roulette_info_ack", sizeof(struct packet_roulette_info_ack), SERVER_TYPE_MAP },
diff --git a/src/common/mmo.h b/src/common/mmo.h
index f9cbc57de..4f047361e 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -81,6 +81,22 @@
#undef ENABLE_PACKETVER_ZERO
#endif // DISABLE_PACKETVER_ZERO
+#if !defined(PACKETVER_RE) && !defined(PACKETVER_ZERO)
+ #define PACKETVER_MAIN_NUM PACKETVER
+#else
+ #define PACKETVER_MAIN_NUM 0
+#endif
+#ifdef PACKETVER_RE
+ #define PACKETVER_RE_NUM PACKETVER
+#else
+ #define PACKETVER_RE_NUM 0
+#endif
+#ifdef PACKETVER_ZERO
+ #define PACKETVER_ZERO_NUM PACKETVER
+#else
+ #define PACKETVER_ZERO_NUM 0
+#endif
+
// Client support for experimental RagexeRE UI present in 2012-04-10 and 2012-04-18
#if defined(PACKETVER_RE) && ( PACKETVER == 20120410 || PACKETVER == 20120418 )
#define PARTY_RECRUIT
@@ -746,6 +762,7 @@ struct guild_member {
char name[NAME_LENGTH];
struct map_session_data *sd;
unsigned char modified;
+ uint32 last_login;
};
struct guild_position {
diff --git a/src/map/clif.c b/src/map/clif.c
index cf5edd0e0..afe8aac40 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1539,6 +1539,7 @@ bool clif_spawn(struct block_list *bl)
clif->spiritcharm(sd);
if (sd->status.look.robe != 0)
clif->refreshlook(bl, bl->id, LOOK_ROBE, sd->status.look.robe, AREA);
+ clif->hat_effect(bl, NULL, AREA);
}
break;
case BL_MOB:
@@ -4395,6 +4396,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) {
clif->sendbgemblem_single(sd->fd,tsd);
if (tsd->status.look.robe != 0)
clif->refreshlook(&sd->bl, bl->id, LOOK_ROBE, tsd->status.look.robe, SELF);
+ clif->hat_effect(bl, &sd->bl, SELF);
}
break;
case BL_MER: // Devotion Effects
@@ -6092,7 +6094,7 @@ void clif_wis_end(int fd, int flag) {
void clif_solved_charname(int fd, int charid, const char* name)
{
nullpo_retv(name);
-#if !defined(PACKETVER_ZERO) && (PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221))
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
WFIFOHEAD(fd, packet_len(0x0af7));
WFIFOW(fd, 0) = 0xaf7;
if (*name == 0) {
@@ -7715,7 +7717,7 @@ void clif_guild_memberlist(struct map_session_data *sd)
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.
+ WFIFOL(fd, c * size + 34) = m->last_login; // [Megasantos] - Shows last date online
#endif
c++;
}
@@ -14218,10 +14220,8 @@ void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int cha
WFIFOL(fd, 2) = sd->status.friends[i].account_id;
WFIFOL(fd, 6) = sd->status.friends[i].char_id;
WFIFOB(fd, 10) = !online; //Yeah, a 1 here means "logged off", go figure...
-#ifndef PACKETVER_ZERO
-#if PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221)
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
memcpy(WFIFOP(fd, 11), sd->status.friends[i].name, NAME_LENGTH);
-#endif
#endif // PACKETVER_ZERO
WFIFOSET(fd, packet_len(0x206));
@@ -14245,7 +14245,7 @@ void clif_friendslist_send(struct map_session_data *sd)
{
int i = 0, n, fd = sd->fd;
-#if !defined(PACKETVER_ZERO) && (PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221))
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
const int offset = 8;
#else
const int offset = 32;
@@ -14257,7 +14257,7 @@ void clif_friendslist_send(struct map_session_data *sd)
for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++) {
WFIFOL(fd, 4 + offset * i + 0) = sd->status.friends[i].account_id;
WFIFOL(fd, 4 + offset * i + 4) = sd->status.friends[i].char_id;
-#if !(!defined(PACKETVER_ZERO) && (PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221)))
+#if !(PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221)
memcpy(WFIFOP(fd, 4 + offset * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
#endif
}
@@ -16126,6 +16126,7 @@ void clif_parse_PartyTick(int fd, struct map_session_data* sd)
/// Sends list of all quest states (ZC_ALL_QUEST_LIST).
/// 02b1 <packet len>.W <num>.L { <quest id>.L <active>.B }*num
/// 097a <packet len>.W <num>.L { <quest id>.L <active>.B <remaining time>.L <time>.L <count>.W { <mob_id>.L <killed>.W <total>.W <mob name>.24B }*count }*num
+/// 09f8 <packet len>.W <num>.L { <quest id>.L <active>.B <remaining time>.L <time>.L <count>.W { <hunt identification>.L <mob type>.L <mob_id>.L <min level>.L <max level>.L <killed>.W <total>.W <mob name>.24B }*count }*num
void clif_quest_send_list(struct map_session_data *sd)
{
int i, len, real_len;
@@ -16164,8 +16165,16 @@ void clif_quest_send_list(struct map_session_data *sd)
real_len += sizeof(info->objectives[j]);
mob_data = mob->db(qi->objectives[j].mob);
-
+#if PACKETVER >= 20150513
+ info->objectives[j].huntIdent = (sd->quest_log[i].quest_id * 1000) + j;
+ info->objectives[j].mobType = 0; // Info Needed
+#endif
info->objectives[j].mob_id = qi->objectives[j].mob;
+#if PACKETVER >= 20150513
+ // Info Needed
+ info->objectives[j].levelMin = 0;
+ info->objectives[j].levelMax = 0;
+#endif
info->objectives[j].huntCount = sd->quest_log[i].count[j];
info->objectives[j].maxCount = qi->objectives[j].count;
safestrncpy(info->objectives[j].mobName, mob_data->jname, sizeof(info->objectives[j].mobName));
@@ -16213,33 +16222,53 @@ void clif_quest_send_mission(struct map_session_data *sd)
/// Notification about a new quest (ZC_ADD_QUEST).
/// 02b3 <quest id>.L <active>.B <start time>.L <expire time>.L <mobs>.W { <mob id>.L <mob count>.W <mob name>.24B }*3
+/// 09f9 <quest id>.L <active>.B <start time>.L <expire time>.L <mobs>.W { <hunt identification>.L <mob type>.L <mob id>.L <min level>.L <max level>.L <mob count>.W <mob name>.24B }*3
void clif_quest_add(struct map_session_data *sd, struct quest *qd)
{
- int fd;
- int i;
+ int i, len;
+ uint8 *buf = NULL;
+ struct packet_quest_add_header *packet = NULL;
struct quest_db *qi;
nullpo_retv(sd);
nullpo_retv(qd);
- fd = sd->fd;
+
qi = quest->db(qd->quest_id);
- WFIFOHEAD(fd, packet_len(0x2b3));
- WFIFOW(fd, 0) = 0x2b3;
- WFIFOL(fd, 2) = qd->quest_id;
- WFIFOB(fd, 6) = qd->state;
- WFIFOB(fd, 7) = qd->time - qi->time;
- WFIFOL(fd, 11) = qd->time;
- WFIFOW(fd, 15) = qi->objectives_count;
+ Assert_retv(qi->objectives_count < MAX_QUEST_OBJECTIVES);
+
+ len = sizeof(struct packet_quest_add_header)
+ + MAX_QUEST_OBJECTIVES * sizeof(struct packet_quest_hunt_sub); // >= than the actual length
+
+ buf = aCalloc(1, len);
+ packet = (struct packet_quest_add_header *)WBUFP(buf, 0);
+
+ packet->PacketType = questAddType;
+ packet->questID = qd->quest_id;
+ packet->active = qd->state;
+ packet->quest_svrTime = qd->time - qi->time;
+ packet->quest_endTime = qd->time;
+ packet->count = qi->objectives_count;
for (i = 0; i < qi->objectives_count; i++) {
struct mob_db *monster;
- WFIFOL(fd, i*30+17) = qi->objectives[i].mob;
- WFIFOW(fd, i*30+21) = qd->count[i];
+
monster = mob->db(qi->objectives[i].mob);
- memcpy(WFIFOP(fd, i*30+23), monster->jname, NAME_LENGTH);
- }
- WFIFOSET(fd, packet_len(0x2b3));
+#if PACKETVER >= 20150513
+ packet->objectives[i].huntIdent = (qd->quest_id * 1000) + i;
+ packet->objectives[i].mobType = 0; // Info Needed
+#endif
+ packet->objectives[i].mob_id = qi->objectives[i].mob;
+#if PACKETVER >= 20150513
+ // Info Needed
+ packet->objectives[i].levelMin = 0;
+ packet->objectives[i].levelMax = 0;
+#endif
+ packet->objectives[i].huntCount = qd->count[i];
+ memcpy(packet->objectives[i].mobName, monster->jname, NAME_LENGTH);
+ }
+ clif->send(buf, len, &sd->bl, SELF);
+ aFree(buf);
}
/// Notification about a quest being removed (ZC_DEL_QUEST).
@@ -16257,32 +16286,82 @@ void clif_quest_delete(struct map_session_data *sd, int quest_id) {
/// Notification of an update to the hunting mission counter (ZC_UPDATE_MISSION_HUNT).
/// 02b5 <packet len>.W <mobs>.W { <quest id>.L <mob id>.L <total count>.W <current count>.W }*3
+/// 09fa <packet len>.W <mobs>.W { <quest id>.L <hunt identification>.L <total count>.W <current count>.W }*3
void clif_quest_update_objective(struct map_session_data *sd, struct quest *qd)
{
- int fd;
- int i;
+ int i, len, real_len;
+ uint8 *buf = NULL;
+ struct packet_quest_update_header *packet = NULL;
struct quest_db *qi;
- int len;
nullpo_retv(sd);
nullpo_retv(qd);
- fd = sd->fd;
+
qi = quest->db(qd->quest_id);
- len = qi->objectives_count * 12 + 6;
+ Assert_retv(qi->objectives_count < MAX_QUEST_OBJECTIVES);
+
+ len = sizeof(struct packet_quest_update_header)
+ + MAX_QUEST_OBJECTIVES * sizeof(struct packet_quest_update_hunt); // >= than the actual length
- WFIFOHEAD(fd, len);
- WFIFOW(fd, 0) = 0x2b5;
- WFIFOW(fd, 2) = len;
- WFIFOW(fd, 4) = qi->objectives_count;
+ buf = aCalloc(1, len);
+ packet = (struct packet_quest_update_header *)WBUFP(buf, 0);
+ real_len = sizeof(*packet);
+
+ packet->PacketType = questUpdateType;
+ packet->count = qi->objectives_count;
for (i = 0; i < qi->objectives_count; i++) {
- WFIFOL(fd, i*12+6) = qd->quest_id;
- WFIFOL(fd, i*12+10) = qi->objectives[i].mob;
- WFIFOW(fd, i*12+14) = qi->objectives[i].count;
- WFIFOW(fd, i*12+16) = qd->count[i];
+ real_len += sizeof(packet->objectives[i]);
+
+ packet->objectives[i].questID = qd->quest_id;
+#if PACKETVER >= 20150513
+ packet->objectives[i].huntIdent = (qd->quest_id * 1000) + i;
+#else
+ packet->objectives[i].mob_id = qi->objectives[i].mob;
+#endif
+ packet->objectives[i].maxCount = qi->objectives[i].count;
+ packet->objectives[i].count = qd->count[i];
}
+ packet->PacketLength = real_len;
+ clif->send(buf, real_len, &sd->bl, SELF);
+ aFree(buf);
+}
- WFIFOSET(fd, len);
+/// Notification of an hunting mission counter just after quest is added (ZC_HUNTING_QUEST_INFO).
+/// 08fe <packet len>.W { <quest id>.L <mob id>.L <total count>.W <current count>.W }*3
+void clif_quest_notify_objective(struct map_session_data *sd, struct quest *qd)
+{
+ int i, len, real_len;
+ uint8 *buf = NULL;
+ struct packet_quest_hunt_info *packet = NULL;
+ struct quest_db *qi;
+
+ nullpo_retv(sd);
+ nullpo_retv(qd);
+
+ qi = quest->db(qd->quest_id);
+ Assert_retv(qi->objectives_count < MAX_QUEST_OBJECTIVES);
+
+ len = sizeof(struct packet_quest_hunt_info)
+ + MAX_QUEST_OBJECTIVES * sizeof(struct packet_quest_hunt_info_sub); // >= than the actual length
+
+ buf = aCalloc(1, len);
+ packet = (struct packet_quest_hunt_info *)WBUFP(buf, 0);
+ real_len = sizeof(*packet);
+
+ packet->PacketType = questUpdateType2;
+
+ for (i = 0; i < qi->objectives_count; i++) {
+ real_len += sizeof(packet->info[i]);
+
+ packet->info[i].questID = qd->quest_id;
+ packet->info[i].mob_id = qi->objectives[i].mob;
+ packet->info[i].maxCount = qi->objectives[i].count;
+ packet->info[i].count = qd->count[i];
+ }
+ packet->PacketLength = real_len;
+ clif->send(buf, real_len, &sd->bl, SELF);
+ aFree(buf);
}
void clif_parse_questStateAck(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -20228,6 +20307,60 @@ void clif_skill_scale(struct block_list *bl, int src_id, int x, int y, uint16 sk
#endif
}
+/// Send hat effects to the client (ZC_HAT_EFFECT).
+/// 0A3B <Length>.W <AID>.L <Status>.B { <HatEffectId>.W }
+void clif_hat_effect(struct block_list *bl, struct block_list *tbl, enum send_target target)
+{
+#if PACKETVER >= 20150422
+ unsigned char *buf;
+ int len, i;
+ struct map_session_data *sd;
+
+ nullpo_retv(bl);
+
+ sd = BL_CAST(BL_PC, bl);
+
+ nullpo_retv(sd);
+
+ len = 9 + VECTOR_LENGTH(sd->hatEffectId) * 2;
+
+ buf = (unsigned char*)aMalloc(len);
+
+ WBUFW(buf, 0) = 0xa3b;
+ WBUFW(buf, 2) = len;
+ WBUFL(buf, 4) = bl->id;
+ WBUFB(buf, 8) = 1;
+
+ for( i = 0; i < VECTOR_LENGTH(sd->hatEffectId); i++ ){
+ WBUFW(buf, 9 + i * 2) = VECTOR_INDEX(sd->hatEffectId, i);
+ }
+
+ if (tbl != NULL) {
+ clif->send(buf, len, tbl, target);
+ } else {
+ clif->send(buf, len, bl, target);
+ }
+
+ aFree(buf);
+#endif
+}
+
+void clif_hat_effect_single(struct block_list *bl, uint16 effectId, bool enable){
+#if PACKETVER >= 20150422
+ unsigned char buf[13];
+
+ nullpo_retv(bl);
+
+ WBUFW(buf,0) = 0xa3b;
+ WBUFW(buf,2) = 13;
+ WBUFL(buf,4) = bl->id;
+ WBUFB(buf,8) = enable;
+ WBUFL(buf,9) = effectId;
+
+ clif_send(buf, 13, bl, AREA);
+#endif
+}
+
/*==========================================
* Main client packet processing function
*------------------------------------------*/
@@ -20924,6 +21057,7 @@ void clif_defaults(void) {
clif->quest_delete = clif_quest_delete;
clif->quest_update_status = clif_quest_update_status;
clif->quest_update_objective = clif_quest_update_objective;
+ clif->quest_notify_objective = clif_quest_notify_objective;
clif->quest_show_event = clif_quest_show_event;
/* mail-related */
clif->mail_window = clif_Mail_window;
@@ -21318,4 +21452,7 @@ void clif_defaults(void) {
clif->clan_leave = clif_clan_leave;
clif->clan_message = clif_clan_message;
clif->pClanMessage = clif_parse_ClanMessage;
+ // -- Hat Effect
+ clif->hat_effect = clif_hat_effect;
+ clif->hat_effect_single = clif_hat_effect_single;
}
diff --git a/src/map/clif.h b/src/map/clif.h
index acf79c373..873188f84 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -1021,6 +1021,7 @@ struct clif_interface {
void (*quest_delete) (struct map_session_data *sd, int quest_id);
void (*quest_update_status) (struct map_session_data *sd, int quest_id, bool active);
void (*quest_update_objective) (struct map_session_data *sd, struct quest *qd);
+ void (*quest_notify_objective) (struct map_session_data *sd, struct quest *qd);
void (*quest_show_event) (struct map_session_data *sd, struct block_list *bl, short state, short color);
/* mail-related */
void (*mail_window) (int fd, int flag);
@@ -1413,6 +1414,9 @@ struct clif_interface {
void (*clan_leave) (struct map_session_data *sd);
void (*clan_message) (struct clan *c, const char *mes, int len);
void (*pClanMessage) (int fd, struct map_session_data* sd);
+ /* Hat Effect */
+ void (*hat_effect) (struct block_list *bl, struct block_list *tbl, enum send_target target);
+ void (*hat_effect_single) (struct block_list *bl, uint16 effectId, bool enable);
};
#ifdef HERCULES_CORE
diff --git a/src/map/guild.c b/src/map/guild.c
index 11609ec81..d33df5e08 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -275,6 +275,7 @@ void guild_makemember(struct guild_member *m,struct map_session_data *sd)
m->online = 1;
m->position = MAX_GUILDPOSITION-1;
memcpy(m->name,sd->status.name,NAME_LENGTH);
+ m->last_login = (uint32)time(NULL); // When player create or join a guild the date is updated
return;
}
@@ -1001,7 +1002,7 @@ int guild_send_memberinfoshort(struct map_session_data *sd,int online)
return 0;
}
-int guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int16 class)
+int guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login)
{ // cleaned up [LuzZza]
int i, alv, c, idx = INDEX_NOT_FOUND, om = 0, oldonline = -1;
struct guild *g = guild->search(guild_id);
@@ -1017,6 +1018,7 @@ int guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int on
m->online=online;
m->lv=lv;
m->class = class;
+ m->last_login = last_login;
idx=i;
}
alv+=m->lv;
diff --git a/src/map/guild.h b/src/map/guild.h
index 9296f9ec0..d6bba2a56 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -126,7 +126,7 @@ struct guild_interface {
int (*check_alliance) (int guild_id1, int guild_id2, int flag);
/* */
int (*send_memberinfoshort) (struct map_session_data *sd,int online);
- int (*recv_memberinfoshort) (int guild_id, int account_id, int char_id, int online, int lv, int16 class);
+ int (*recv_memberinfoshort) (int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login);
int (*change_memberposition) (int guild_id,int account_id,int char_id,short idx);
int (*memberposition_changed) (struct guild *g,int idx,int pos);
int (*change_position) (int guild_id,int idx,int mode,int exp_mode,const char *name);
diff --git a/src/map/intif.c b/src/map/intif.c
index f656a0df9..e9bf0e96b 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -1494,7 +1494,7 @@ void intif_parse_GuildMemberWithdraw(int fd) {
// ACK guild member basic info
void intif_parse_GuildMemberInfoShort(int fd) {
- guild->recv_memberinfoshort(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17));
+ guild->recv_memberinfoshort(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17),RFIFOL(fd,19));
}
// ACK guild break
@@ -2846,7 +2846,7 @@ void intif_defaults(void) {
-1,-1,27,-1, -1,-1,37,-1, 7, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
- 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
+ 10,-1,15, 0, 79,23, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
-1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840
-1,-1, 7, 7, 7,11, 8, 0, 10, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari] Clan System[Murilo BiO]
-1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish]
diff --git a/src/map/packets.h b/src/map/packets.h
index 462efd31b..d18abf4da 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -4044,4 +4044,27 @@ packet(0x96e,-1,clif->ackmergeitems);
#endif
#endif // PACKETVER_ZERO
+#ifndef PACKETVER_ZERO
+// 2018-03-21aRagexe, 2018-03-21aRagexeRE
+#if PACKETVER >= 20180321
+// new packets
+ packet(0x0af8,11,clif->pDull/*,XXX*/);
+// changed packet sizes
+ packet(0x0ae7,34,clif->pDull/*,XXX*/);
+#endif
+#endif // PACKETVER_ZERO
+
+#ifdef PACKETVER_ZERO
+// 2018-03-28_1aRagexe_zero
+#if PACKETVER >= 20180328
+// new packets
+ packet(0x0af8,11,clif->pDull/*,XXX*/);
+ packet(0x0af9,6,clif->pDull/*,XXX*/);
+ packet(0x0afa,54,clif->pDull/*,XXX*/);
+// changed packet sizes
+ packet(0x0206,35); // ZC_FRIENDS_STATE
+ packet(0x0ae7,38,clif->pDull/*,XXX*/);
+#endif
+#endif // PACKETVER_ZERO
+
#endif /* MAP_PACKETS_H */
diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h
index 066e7d2c3..8d20780d4 100644
--- a/src/map/packets_keys_main.h
+++ b/src/map/packets_keys_main.h
@@ -874,11 +874,14 @@
packetKeys(0x6A596301,0x76866D0E,0x32294A45);
#endif
-// 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe
+// 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE
#if PACKETVER == 20131223 || \
PACKETVER == 20140508 || \
PACKETVER == 20140611 || \
- PACKETVER == 20150225
+ PACKETVER == 20150225 || \
+ PACKETVER == 20180315 || \
+ PACKETVER == 20180321 || \
+ PACKETVER == 20180328
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
@@ -1976,5 +1979,10 @@
packetKeys(0x47DA10EB,0x4B922CCF,0x765C5055);
#endif
+// 2018-03-14nRagexe
+#if PACKETVER == 20180314
+ packetKeys(0x2FF07149,0x00596EA3,0x2B853026);
+#endif
+
#endif /* MAP_PACKETS_MAIN_KEYS_H */
diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h
index 75196e6b4..2bd6f1604 100644
--- a/src/map/packets_keys_zero.h
+++ b/src/map/packets_keys_zero.h
@@ -29,7 +29,7 @@
/* This file is autogenerated, please do not commit manual changes */
-// 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero
+// 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero
#if PACKETVER == 20171019 || \
PACKETVER == 20171023 || \
PACKETVER == 20171024 || \
@@ -38,7 +38,10 @@
PACKETVER == 20171030 || \
PACKETVER == 20171031 || \
PACKETVER == 20171109 || \
- PACKETVER == 20171113
+ PACKETVER == 20171113 || \
+ PACKETVER == 20180315 || \
+ PACKETVER == 20180321 || \
+ PACKETVER == 20180328
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
@@ -141,5 +144,10 @@
packetKeys(0x56C82ABE,0x61AE2B2E,0x472E272E);
#endif
+// 2018-03-14nRagexe_zero
+#if PACKETVER == 20180314
+ packetKeys(0x2FC330DD,0x01C04E1F,0x4D914DE2);
+#endif
+
#endif /* MAP_PACKETS_ZERO_KEYS_H */
diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h
index aabf9c3f3..d1f9a2062 100644
--- a/src/map/packets_shuffle_main.h
+++ b/src/map/packets_shuffle_main.h
@@ -3178,10 +3178,13 @@
packet(0x096a,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
#endif
-// 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe
+// 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE
#if PACKETVER == 20140508 || \
PACKETVER == 20140611 || \
- PACKETVER == 20150225
+ PACKETVER == 20150225 || \
+ PACKETVER == 20180315 || \
+ PACKETVER == 20180321 || \
+ PACKETVER == 20180328
packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
@@ -9667,5 +9670,38 @@
packet(0x0969,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
#endif
+// 2018-03-14nRagexe
+#if PACKETVER == 20180314
+ packet(0x0361,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0366,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0369,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0436,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x085a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0862,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0863,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0868,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x086e,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0874,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x087a,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0888,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x088a,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x088d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0894,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x089b,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0921,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0927,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x092f,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0933,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0935,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0945,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x094d,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x094e,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0956,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0959,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x095f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0962,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0967,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+#endif
+
#endif /* MAP_PACKETS_SHUFFLE_MAIN_H */
diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h
index 463ab1679..7cd52d971 100644
--- a/src/map/packets_shuffle_zero.h
+++ b/src/map/packets_shuffle_zero.h
@@ -36,7 +36,7 @@
/* This file is autogenerated, please do not commit manual changes */
-// 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero
+// 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero
#if PACKETVER == 20171019 || \
PACKETVER == 20171023 || \
PACKETVER == 20171024 || \
@@ -45,7 +45,10 @@
PACKETVER == 20171030 || \
PACKETVER == 20171031 || \
PACKETVER == 20171109 || \
- PACKETVER == 20171113
+ PACKETVER == 20171113 || \
+ PACKETVER == 20180315 || \
+ PACKETVER == 20180321 || \
+ PACKETVER == 20180328
packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
@@ -652,5 +655,38 @@
packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
#endif
+// 2018-03-14nRagexe_zero
+#if PACKETVER == 20180314
+ packet(0x023b,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0438,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x07ec,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x083c,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x085d,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x085f,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0866,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0878,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x088d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0891,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0897,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0899,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x089e,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x08a1,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0917,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0918,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x091f,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0920,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0923,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0930,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0931,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x093f,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0946,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x094a,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x094e,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0954,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0956,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0958,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+#endif
+
#endif /* MAP_PACKETS_SHUFFLE_ZERO_H */
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 2a65eb6cf..d8a2c6b31 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -302,7 +302,7 @@ enum packet_headers {
rouletteinfoackType = 0xa1c,
roulettgenerateackType = 0xa20,
roulettercvitemackType = 0xa22,
-#if 0 // Unknown
+#if PACKETVER >= 20150513 // [4144] 0x09f8 handling in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE
questListType = 0x9f8, ///< ZC_ALL_QUEST_LIST3
#elif PACKETVER >= 20141022
questListType = 0x97a, ///< ZC_ALL_QUEST_LIST2
@@ -357,6 +357,17 @@ enum packet_headers {
clanLeave = 0x0989, ///< ZC_ACK_CLAN_LEAVE
clanMessage = 0x098E, ///< ZC_NOTIFY_CLAN_CHAT
#endif
+#if PACKETVER >= 20150513 // [4144] 0x09f9 handled in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE
+ questAddType = 0x9f9,
+#else
+ questAddType = 0x2b3,
+#endif // PACKETVER < 20150513
+#if PACKETVER >= 20150513
+ questUpdateType = 0x9fa,
+#else
+ questUpdateType = 0x2b5,
+#endif // PACKETVER < 20150513
+ questUpdateType2 = 0x8fe,
};
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
@@ -1248,10 +1259,19 @@ struct packet_hotkey {
} __attribute__((packed));
/**
- * MISSION_HUNT_INFO
+ * MISSION_HUNT_INFO (PACKETVER >= 20141022)
+ * MISSION_HUNT_INFO_EX (PACKETVER >= 20150513)
*/
struct packet_mission_info_sub {
- int32 mob_id;
+#if PACKETVER >= 20150513
+ uint32 huntIdent;
+ uint32 mobType;
+#endif
+ uint32 mob_id;
+#if PACKETVER >= 20150513
+ int16 levelMin;
+ int16 levelMax;
+#endif
int16 huntCount;
int16 maxCount;
char mobName[NAME_LENGTH];
@@ -1259,7 +1279,7 @@ struct packet_mission_info_sub {
/**
* PACKET_ZC_ALL_QUEST_LIST2_INFO (PACKETVER >= 20141022)
- * PACKET_ZC_ALL_QUEST_LIST3_INFO (PACKETVER Unknown) / unused
+ * PACKET_ZC_ALL_QUEST_LIST3_INFO (PACKETVER >= 20150513)
*/
struct packet_quest_list_info {
int32 questID;
@@ -1276,7 +1296,7 @@ struct packet_quest_list_info {
* Header for:
* PACKET_ZC_ALL_QUEST_LIST (PACKETVER < 20141022)
* PACKET_ZC_ALL_QUEST_LIST2 (PACKETVER >= 20141022)
- * PACKET_ZC_ALL_QUEST_LIST3 (PACKETVER Unknown) / unused
+ * PACKET_ZC_ALL_QUEST_LIST3 (PACKETVER >= 20150513)
*
* @remark
* Contains (is followed by) a variable-length array of packet_quest_list_info
@@ -1598,6 +1618,87 @@ struct PACKET_ZC_NOTIFY_CLAN_CHAT {
char Message[];
} __attribute__((packed));
+/**
+ * PACKET_ZC_MISSION_HUNT (PACKETVER < 20150513)
+ * PACKET_ZC_MISSION_HUNT_EX (PACKETVER >= 20150513)
+ */
+struct packet_quest_hunt_sub {
+#if PACKETVER >= 20150513
+ uint32 huntIdent;
+ uint32 mobType;
+#endif
+ uint32 mob_id;
+#if PACKETVER >= 20150513
+ int16 levelMin;
+ int16 levelMax;
+#endif
+ int16 huntCount;
+ char mobName[NAME_LENGTH];
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * PACKET_ZC_ADD_QUEST (PACKETVER < 20150513)
+ * PACKET_ZC_ADD_QUEST_EX (PACKETVER >= 20150513)
+ */
+struct packet_quest_add_header {
+ uint16 PacketType;
+ uint32 questID;
+ uint8 active;
+ int32 quest_svrTime;
+ int32 quest_endTime;
+ int16 count;
+ struct packet_quest_hunt_sub objectives[];
+} __attribute__((packed));
+
+/**
+ * PACKET_MOB_HUNTING (PACKETVER < 20150513)
+ * PACKET_MOB_HUNTING_EX (PACKETVER >= 20150513)
+ */
+struct packet_quest_update_hunt {
+ uint32 questID;
+#if PACKETVER >= 20150513
+ uint32 huntIdent;
+#else
+ uint32 mob_id;
+#endif // PACKETVER < 20150513
+ int16 maxCount;
+ int16 count;
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * PACKET_ZC_UPDATE_MISSION_HUNT (PACKETVER < 20150513)
+ * PACKET_ZC_UPDATE_MISSION_HUNT_EX (PACKETVER >= 20150513)
+ */
+struct packet_quest_update_header {
+ uint16 PacketType;
+ uint16 PacketLength;
+ int16 count;
+ struct packet_quest_update_hunt objectives[];
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * PACKET_MOB_HUNTING (PACKETVER >= 20150513)
+ */
+struct packet_quest_hunt_info_sub {
+ uint32 questID;
+ uint32 mob_id;
+ int16 maxCount;
+ int16 count;
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * ZC_HUNTING_QUEST_INFO (PACKETVER >= 20150513)
+ */
+struct packet_quest_hunt_info {
+ uint16 PacketType;
+ uint16 PacketLength;
+ struct packet_quest_hunt_info_sub info[];
+} __attribute__((packed));
+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris
diff --git a/src/map/pc.c b/src/map/pc.c
index cd4b2a54f..4404101b9 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1293,6 +1293,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
VECTOR_INIT(sd->script_queues);
VECTOR_INIT(sd->storage.item); // initialize storage item vector.
+ VECTOR_INIT(sd->hatEffectId);
sd->state.dialog = 0;
diff --git a/src/map/pc.h b/src/map/pc.h
index a01152df5..e699e5750 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -618,6 +618,9 @@ END_ZEROED_BLOCK;
const char* delunit_prevfile;
int delunit_prevline;
+ // HatEffect
+ VECTOR_DECL(int) hatEffectId;
+
};
#define EQP_WEAPON EQP_HAND_R
diff --git a/src/map/quest.c b/src/map/quest.c
index 4c5dcb59f..581ecf45e 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -148,7 +148,11 @@ int quest_add(struct map_session_data *sd, int quest_id, unsigned int time_limit
sd->save_quest = true;
clif->quest_add(sd, &sd->quest_log[n]);
+#if PACKETVER >= 20150513
+ clif->quest_notify_objective(sd, &sd->quest_log[n]);
+#else
clif->quest_update_objective(sd, &sd->quest_log[n]);
+#endif
if ((map->save_settings & 64) != 0)
chrif->save(sd, 0);
@@ -201,7 +205,11 @@ int quest_change(struct map_session_data *sd, int qid1, int qid2)
clif->quest_delete(sd, qid1);
clif->quest_add(sd, &sd->quest_log[i]);
+#if PACKETVER >= 20150513
+ clif->quest_notify_objective(sd, &sd->quest_log[i]);
+#else
clif->quest_update_objective(sd, &sd->quest_log[i]);
+#endif
if( map->save_settings&64 )
chrif->save(sd,0);
diff --git a/src/map/script.c b/src/map/script.c
index d653800cc..275601dcc 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -12815,12 +12815,12 @@ enum mapinfo_info {
BUILDIN(getmapinfo)
{
enum mapinfo_info mode = script_getnum(st, 2);
- int16 m;
+ int16 m = -1;
if (script_hasdata(st, 3)) {
if (script_isstringtype(st, 3)) {
const char *str = script_getstr(st, 3);
- m = map->mapname2mapid(str);
+ m = map->mapindex2mapid(strdb_iget(mapindex->db, str));
} else {
m = script_getnum(st, 3);
}
@@ -23965,6 +23965,42 @@ BUILDIN(clan_master)
}
/**
+ * hateffect(EffectID, Enable_State)
+ */
+BUILDIN(hateffect)
+{
+#if PACKETVER >= 20150422
+ struct map_session_data *sd = script_rid2sd(st);
+ int effectId, enabled = 0;
+ int i;
+
+ if (sd == NULL)
+ return false;
+
+ effectId = script_getnum(st, 2);
+ enabled = script_getnum(st, 3);
+
+ for (i = 0; i < VECTOR_LENGTH(sd->hatEffectId); ++i) {
+ if (VECTOR_INDEX(sd->hatEffectId, i) == effectId) {
+ if (enabled == 1) { // Already Enabled
+ return true;
+ } else { // Remove
+ VECTOR_ERASE(sd->hatEffectId, i);
+ clif->hat_effect_single(&sd->bl, effectId, enabled);
+ return true;
+ }
+ }
+ }
+
+ VECTOR_ENSURE(sd->hatEffectId, 1, 1);
+ VECTOR_PUSH(sd->hatEffectId, effectId);
+
+ clif->hat_effect_single(&sd->bl, effectId, enabled);
+#endif
+ return true;
+}
+
+/**
* Adds a built-in script function.
*
* @param buildin Script function data
@@ -24679,6 +24715,9 @@ void script_parse_builtin(void) {
BUILDIN_DEF2(rodex_sendmail2, "rodex_sendmail_acc2", "isss?????????????????????????????????????????"),
BUILDIN_DEF(_,"s"),
BUILDIN_DEF2(_, "_$", "s"),
+
+ // -- HatEffect
+ BUILDIN_DEF(hateffect, "ii"),
};
int i, len = ARRAYLENGTH(BUILDIN);
RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
diff --git a/src/map/unit.c b/src/map/unit.c
index c40aa7000..64bd17edc 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2766,6 +2766,7 @@ int unit_free(struct block_list *bl, clr_type clrtype)
}
VECTOR_CLEAR(sd->script_queues);
VECTOR_CLEAR(sd->storage.item);
+ VECTOR_CLEAR(sd->hatEffectId);
sd->storage.received = false;
if( sd->quest_log != NULL ) {
aFree(sd->quest_log);
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index bd17dc7fe..da70abc12 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -1692,6 +1692,8 @@ typedef void (*HPMHOOK_pre_clif_quest_update_status) (struct map_session_data **
typedef void (*HPMHOOK_post_clif_quest_update_status) (struct map_session_data *sd, int quest_id, bool active);
typedef void (*HPMHOOK_pre_clif_quest_update_objective) (struct map_session_data **sd, struct quest **qd);
typedef void (*HPMHOOK_post_clif_quest_update_objective) (struct map_session_data *sd, struct quest *qd);
+typedef void (*HPMHOOK_pre_clif_quest_notify_objective) (struct map_session_data **sd, struct quest **qd);
+typedef void (*HPMHOOK_post_clif_quest_notify_objective) (struct map_session_data *sd, struct quest *qd);
typedef void (*HPMHOOK_pre_clif_quest_show_event) (struct map_session_data **sd, struct block_list **bl, short *state, short *color);
typedef void (*HPMHOOK_post_clif_quest_show_event) (struct map_session_data *sd, struct block_list *bl, short state, short color);
typedef void (*HPMHOOK_pre_clif_mail_window) (int *fd, int *flag);
@@ -2404,6 +2406,10 @@ typedef void (*HPMHOOK_pre_clif_clan_message) (struct clan **c, const char **mes
typedef void (*HPMHOOK_post_clif_clan_message) (struct clan *c, const char *mes, int len);
typedef void (*HPMHOOK_pre_clif_pClanMessage) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pClanMessage) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_hat_effect) (struct block_list **bl, struct block_list **tbl, enum send_target *target);
+typedef void (*HPMHOOK_post_clif_hat_effect) (struct block_list *bl, struct block_list *tbl, enum send_target target);
+typedef void (*HPMHOOK_pre_clif_hat_effect_single) (struct block_list **bl, uint16 *effectId, bool *enable);
+typedef void (*HPMHOOK_post_clif_hat_effect_single) (struct block_list *bl, uint16 effectId, bool enable);
#endif // MAP_CLIF_H
#ifdef COMMON_CORE_H /* cmdline */
typedef void (*HPMHOOK_pre_cmdline_init) (void);
@@ -2668,8 +2674,8 @@ typedef int (*HPMHOOK_pre_guild_check_alliance) (int *guild_id1, int *guild_id2,
typedef int (*HPMHOOK_post_guild_check_alliance) (int retVal___, int guild_id1, int guild_id2, int flag);
typedef int (*HPMHOOK_pre_guild_send_memberinfoshort) (struct map_session_data **sd, int *online);
typedef int (*HPMHOOK_post_guild_send_memberinfoshort) (int retVal___, struct map_session_data *sd, int online);
-typedef int (*HPMHOOK_pre_guild_recv_memberinfoshort) (int *guild_id, int *account_id, int *char_id, int *online, int *lv, int16 *class);
-typedef int (*HPMHOOK_post_guild_recv_memberinfoshort) (int retVal___, int guild_id, int account_id, int char_id, int online, int lv, int16 class);
+typedef int (*HPMHOOK_pre_guild_recv_memberinfoshort) (int *guild_id, int *account_id, int *char_id, int *online, int *lv, int16 *class, uint32 *last_login);
+typedef int (*HPMHOOK_post_guild_recv_memberinfoshort) (int retVal___, int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login);
typedef int (*HPMHOOK_pre_guild_change_memberposition) (int *guild_id, int *account_id, int *char_id, short *idx);
typedef int (*HPMHOOK_post_guild_change_memberposition) (int retVal___, int guild_id, int account_id, int char_id, short idx);
typedef int (*HPMHOOK_pre_guild_memberposition_changed) (struct guild **g, int *idx, int *pos);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 9d531e370..d799b8693 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -1286,6 +1286,8 @@ struct {
struct HPMHookPoint *HP_clif_quest_update_status_post;
struct HPMHookPoint *HP_clif_quest_update_objective_pre;
struct HPMHookPoint *HP_clif_quest_update_objective_post;
+ struct HPMHookPoint *HP_clif_quest_notify_objective_pre;
+ struct HPMHookPoint *HP_clif_quest_notify_objective_post;
struct HPMHookPoint *HP_clif_quest_show_event_pre;
struct HPMHookPoint *HP_clif_quest_show_event_post;
struct HPMHookPoint *HP_clif_mail_window_pre;
@@ -1998,6 +2000,10 @@ struct {
struct HPMHookPoint *HP_clif_clan_message_post;
struct HPMHookPoint *HP_clif_pClanMessage_pre;
struct HPMHookPoint *HP_clif_pClanMessage_post;
+ struct HPMHookPoint *HP_clif_hat_effect_pre;
+ struct HPMHookPoint *HP_clif_hat_effect_post;
+ struct HPMHookPoint *HP_clif_hat_effect_single_pre;
+ struct HPMHookPoint *HP_clif_hat_effect_single_post;
struct HPMHookPoint *HP_cmdline_init_pre;
struct HPMHookPoint *HP_cmdline_init_post;
struct HPMHookPoint *HP_cmdline_final_pre;
@@ -7567,6 +7573,8 @@ struct {
int HP_clif_quest_update_status_post;
int HP_clif_quest_update_objective_pre;
int HP_clif_quest_update_objective_post;
+ int HP_clif_quest_notify_objective_pre;
+ int HP_clif_quest_notify_objective_post;
int HP_clif_quest_show_event_pre;
int HP_clif_quest_show_event_post;
int HP_clif_mail_window_pre;
@@ -8279,6 +8287,10 @@ struct {
int HP_clif_clan_message_post;
int HP_clif_pClanMessage_pre;
int HP_clif_pClanMessage_post;
+ int HP_clif_hat_effect_pre;
+ int HP_clif_hat_effect_post;
+ int HP_clif_hat_effect_single_pre;
+ int HP_clif_hat_effect_single_post;
int HP_cmdline_init_pre;
int HP_cmdline_init_post;
int HP_cmdline_final_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 5551668d2..045c8a087 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -666,6 +666,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->quest_delete, HP_clif_quest_delete) },
{ HP_POP(clif->quest_update_status, HP_clif_quest_update_status) },
{ HP_POP(clif->quest_update_objective, HP_clif_quest_update_objective) },
+ { HP_POP(clif->quest_notify_objective, HP_clif_quest_notify_objective) },
{ HP_POP(clif->quest_show_event, HP_clif_quest_show_event) },
{ HP_POP(clif->mail_window, HP_clif_mail_window) },
{ HP_POP(clif->mail_read, HP_clif_mail_read) },
@@ -1022,6 +1023,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->clan_leave, HP_clif_clan_leave) },
{ HP_POP(clif->clan_message, HP_clif_clan_message) },
{ HP_POP(clif->pClanMessage, HP_clif_pClanMessage) },
+ { HP_POP(clif->hat_effect, HP_clif_hat_effect) },
+ { HP_POP(clif->hat_effect_single, HP_clif_hat_effect_single) },
/* cmdline_interface */
{ HP_POP(cmdline->init, HP_cmdline_init) },
{ HP_POP(cmdline->final, HP_cmdline_final) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 2e20ab157..22129c026 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -16753,6 +16753,32 @@ void HP_clif_quest_update_objective(struct map_session_data *sd, struct quest *q
}
return;
}
+void HP_clif_quest_notify_objective(struct map_session_data *sd, struct quest *qd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_quest_notify_objective_pre > 0) {
+ void (*preHookFunc) (struct map_session_data **sd, struct quest **qd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_quest_notify_objective_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_quest_notify_objective_pre[hIndex].func;
+ preHookFunc(&sd, &qd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.quest_notify_objective(sd, qd);
+ }
+ if (HPMHooks.count.HP_clif_quest_notify_objective_post > 0) {
+ void (*postHookFunc) (struct map_session_data *sd, struct quest *qd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_quest_notify_objective_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_quest_notify_objective_post[hIndex].func;
+ postHookFunc(sd, qd);
+ }
+ }
+ return;
+}
void HP_clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, short state, short color) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_quest_show_event_pre > 0) {
@@ -26018,6 +26044,58 @@ void HP_clif_pClanMessage(int fd, struct map_session_data *sd) {
}
return;
}
+void HP_clif_hat_effect(struct block_list *bl, struct block_list *tbl, enum send_target target) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_hat_effect_pre > 0) {
+ void (*preHookFunc) (struct block_list **bl, struct block_list **tbl, enum send_target *target);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hat_effect_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_hat_effect_pre[hIndex].func;
+ preHookFunc(&bl, &tbl, &target);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.hat_effect(bl, tbl, target);
+ }
+ if (HPMHooks.count.HP_clif_hat_effect_post > 0) {
+ void (*postHookFunc) (struct block_list *bl, struct block_list *tbl, enum send_target target);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hat_effect_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_hat_effect_post[hIndex].func;
+ postHookFunc(bl, tbl, target);
+ }
+ }
+ return;
+}
+void HP_clif_hat_effect_single(struct block_list *bl, uint16 effectId, bool enable) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_hat_effect_single_pre > 0) {
+ void (*preHookFunc) (struct block_list **bl, uint16 *effectId, bool *enable);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hat_effect_single_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_hat_effect_single_pre[hIndex].func;
+ preHookFunc(&bl, &effectId, &enable);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.hat_effect_single(bl, effectId, enable);
+ }
+ if (HPMHooks.count.HP_clif_hat_effect_single_post > 0) {
+ void (*postHookFunc) (struct block_list *bl, uint16 effectId, bool enable);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hat_effect_single_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_hat_effect_single_post[hIndex].func;
+ postHookFunc(bl, effectId, enable);
+ }
+ }
+ return;
+}
/* cmdline_interface */
void HP_cmdline_init(void) {
int hIndex = 0;
@@ -29222,15 +29300,15 @@ int HP_guild_send_memberinfoshort(struct map_session_data *sd, int online) {
}
return retVal___;
}
-int HP_guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int16 class) {
+int HP_guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login) {
int hIndex = 0;
int retVal___ = 0;
if (HPMHooks.count.HP_guild_recv_memberinfoshort_pre > 0) {
- int (*preHookFunc) (int *guild_id, int *account_id, int *char_id, int *online, int *lv, int16 *class);
+ int (*preHookFunc) (int *guild_id, int *account_id, int *char_id, int *online, int *lv, int16 *class, uint32 *last_login);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_guild_recv_memberinfoshort_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_guild_recv_memberinfoshort_pre[hIndex].func;
- retVal___ = preHookFunc(&guild_id, &account_id, &char_id, &online, &lv, &class);
+ retVal___ = preHookFunc(&guild_id, &account_id, &char_id, &online, &lv, &class, &last_login);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -29238,13 +29316,13 @@ int HP_guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int
}
}
{
- retVal___ = HPMHooks.source.guild.recv_memberinfoshort(guild_id, account_id, char_id, online, lv, class);
+ retVal___ = HPMHooks.source.guild.recv_memberinfoshort(guild_id, account_id, char_id, online, lv, class, last_login);
}
if (HPMHooks.count.HP_guild_recv_memberinfoshort_post > 0) {
- int (*postHookFunc) (int retVal___, int guild_id, int account_id, int char_id, int online, int lv, int16 class);
+ int (*postHookFunc) (int retVal___, int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login);
for (hIndex = 0; hIndex < HPMHooks.count.HP_guild_recv_memberinfoshort_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_guild_recv_memberinfoshort_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, guild_id, account_id, char_id, online, lv, class);
+ retVal___ = postHookFunc(retVal___, guild_id, account_id, char_id, online, lv, class, last_login);
}
}
return retVal___;