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.c241
1 files changed, 226 insertions, 15 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 3bdea3f7f..aeaf03e43 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -3089,7 +3089,7 @@ void clif_updatestatus(struct map_session_data *sd,int type)
WFIFOL(fd,4)=sd->status.zeny;
len = packet_len(0xb1);
break;
-// [4144] unconfirment exact version can be from 20170405 to 20170913
+// [4144] exact version unknown, between 20170405 to 20170913?
#if PACKETVER >= 20170830
case SP_BASEEXP:
WFIFOW(fd, 0) = 0xacb;
@@ -11081,7 +11081,7 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd) __attribute_
/// 1 = public
void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd)
{
- int len = RFIFOW(fd,2)-15;
+ int len = (int)RFIFOW(fd, 2) - 15;
int limit;
bool pub;
const char *password; //not zero-terminated
@@ -11137,7 +11137,7 @@ void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data* sd) __attr
/// 1 = public
void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data* sd)
{
- int len = RFIFOW(fd,2)-15;
+ int len = (int)RFIFOW(fd, 2) - 15;
int limit;
bool pub;
const char *password; // not zero-terminated
@@ -13148,12 +13148,12 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd) __attribute__((
/// 0 = canceled
/// 1 = open
void clif_parse_OpenVending(int fd, struct map_session_data* sd) {
- short len = (short)RFIFOW(fd,2) - 85;
+ int len = (int)RFIFOW(fd, 2) - 85;
const char *message;
bool flag;
const uint8 *data;
- if (len < 1)
+ if (len < 0)
return;
message = RFIFOP(fd,4);
@@ -20531,32 +20531,43 @@ void clif_parse_open_ui_request(int fd, struct map_session_data *sd)
clif->open_ui(sd, p->UIType);
}
-void clif_open_ui(struct map_session_data *sd, int8 UIType)
+void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType)
{
-#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411
- int claimed = 0;
+#if PACKETVER >= 20150128
struct PACKET_ZC_OPEN_UI p;
nullpo_retv(sd);
- p.PacketType = 0xAE2;
- switch (UIType) {
- case 5: // client will send 5 for the request but requires to receive ATTENDANCE_UI (7) to open the correct ui.
+ p.PacketType = openUiType;
+ switch (uiType) {
+ case CZ_STYLIST_UI:
+ p.UIType = ZC_STYLIST_UI;
+#if PACKETVER >= 20171122
+ p.data = 0;
+#endif
+ break;
+ case CZ_ATTENDANCE_UI:
+ {
+#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411
+ int claimed = 0;
if (clif->attendance_timediff(sd) != true)
++claimed;
else if (sd->status.attendance_count >= VECTOR_LENGTH(clif->attendance_data))
sd->status.attendance_count = 0;
- p.UIType = ATTENDANCE_UI;
+ p.UIType = ZC_ATTENDANCE_UI;
p.data = sd->status.attendance_count * 10 + claimed;
+#else
+ ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411.\n");
+ return;
+#endif
break;
+ }
default:
- ShowWarning("clif_open_ui: Requested UI (%d) is not implemented yet.\n", UIType);
+ ShowWarning("clif_open_ui: Requested UI (%u) is not implemented yet.\n", uiType);
return;
}
clif->send(&p, sizeof(p), &sd->bl, SELF);
-#else
- ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411.\n");
#endif
}
@@ -20672,6 +20683,196 @@ void clif_private_airship_response(struct map_session_data *sd, uint32 flag)
#endif
}
+void clif_stylist_vector_init(void)
+{
+ int i;
+ for (i = 0; i < MAX_STYLIST_TYPE; i++) {
+ VECTOR_INIT(stylist_data[i]);
+ }
+}
+
+void clif_stylist_vector_clear(void)
+{
+ int i;
+ for (i = 0; i < MAX_STYLIST_TYPE; i++) {
+ VECTOR_CLEAR(stylist_data[i]);
+ }
+}
+
+bool clif_stylist_read_db_libconfig(void)
+{
+ struct config_t stylist_conf;
+ struct config_setting_t *stylist = NULL, *it = NULL;
+ const char *config_filename = "db/stylist_db.conf"; // FIXME hardcoded name
+ int i = 0;
+
+ if (!libconfig->load_file(&stylist_conf, config_filename))
+ return false;
+
+ if ((stylist = libconfig->setting_get_member(stylist_conf.root, "stylist_db")) == NULL) {
+ ShowError("can't read %s\n", config_filename);
+ return false;
+ }
+
+ clif->stylist_vector_clear();
+
+ while ((it = libconfig->setting_get_elem(stylist, i++))) {
+ clif->stylist_read_db_libconfig_sub(it, i - 1, config_filename);
+ }
+
+ libconfig->destroy(&stylist_conf);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, config_filename);
+ return true;
+}
+
+bool clif_stylist_read_db_libconfig_sub(struct config_setting_t *it, int idx, const char *source)
+{
+ struct stylist_data_entry entry = { 0 };
+ int i32 = 0, type = 0;
+ int64 i64 = 0;
+
+ nullpo_ret(it);
+ nullpo_ret(source);
+
+ if (!itemdb->lookup_const(it, "Type", &type) || type >= MAX_STYLIST_TYPE || type < 0) {
+ ShowWarning("clif_stylist_read_db_libconfig_sub: Invalid or missing Type (%d) in \"%s\", entry #%d, skipping.\n", type, source, idx);
+ return false;
+ }
+ if (!itemdb->lookup_const(it, "Id", &i32) || i32 <= 0) {
+ ShowWarning("clif_stylist_read_db_libconfig_sub: Invalid or missing Id (%d) in \"%s\", entry #%d, skipping.\n", i32, source, idx);
+ return false;
+ }
+ entry.id = i32;
+
+ if (libconfig->setting_lookup_int64(it, "Zeny", &i64)) {
+ if (i64 > MAX_ZENY) {
+ ShowWarning("clif_stylist_read_db_libconfig_sub: zeny is too big in \"%s\", entry #%d, capping to MAX_ZENY.\n", source, idx);
+ entry.zeny = MAX_ZENY;
+ } else {
+ entry.zeny = (int)i64;
+ }
+ }
+
+ if (itemdb->lookup_const(it, "ItemID", &i32))
+ entry.itemid = i32;
+
+ if (itemdb->lookup_const(it, "BoxItemID", &i32))
+ entry.boxid = i32;
+
+ VECTOR_ENSURE(stylist_data[type], 1, 1);
+ VECTOR_PUSH(stylist_data[type], entry);
+ return true;
+}
+
+bool clif_style_change_validate_requirements(struct map_session_data *sd, int type, int16 idx)
+{
+ struct item it;
+ struct stylist_data_entry *entry;
+
+ nullpo_retr(false, sd);
+ Assert_retr(false, type >= 0 && type < MAX_STYLIST_TYPE);
+ Assert_retr(false, idx >= 0 && idx < VECTOR_LENGTH(stylist_data[type]));
+
+ entry = &VECTOR_INDEX(stylist_data[type], idx);
+
+ if (entry->id != 0) {
+ if (entry->zeny != 0) {
+ if (sd->status.zeny < entry->zeny)
+ return false;
+
+ sd->status.zeny -= entry->zeny;
+ clif->updatestatus(sd, SP_ZENY);
+ } else if (entry->itemid != 0) {
+ it.nameid = entry->itemid;
+ it.amount = 1;
+ return script->buildin_delitem_search(sd, &it, false);
+ } else if (entry->boxid != 0) {
+ it.nameid = entry->boxid;
+ it.amount = 1;
+ return script->buildin_delitem_search(sd, &it, false);
+ }
+ return true;
+ }
+ return false;
+}
+void clif_stylist_send_rodexitem(struct map_session_data *sd, int16 itemid)
+{
+ struct rodex_message msg = { 0 };
+
+ nullpo_retv(sd);
+
+ msg.receiver_id = sd->status.char_id;
+ msg.items[0].item.nameid = itemid;
+ msg.items[0].item.amount = 1;
+ msg.items[0].item.identify = 1;
+ msg.type = MAIL_TYPE_NPC | MAIL_TYPE_ITEM;
+
+ safestrncpy(msg.sender_name, msg_txt(366), NAME_LENGTH);
+ safestrncpy(msg.title, msg_txt(367), RODEX_TITLE_LENGTH);
+ safestrncpy(msg.body, msg_txt(368), MAIL_BODY_LENGTH);
+ msg.send_date = (int)time(NULL);
+ msg.expire_date = (int)time(NULL) + RODEX_EXPIRE;
+
+ intif->rodex_sendmail(&msg);
+}
+
+void clif_parse_cz_req_style_change(int fd, struct map_session_data *sd) __attribute__((nonnull(2)));
+void clif_parse_cz_req_style_change(int fd, struct map_session_data *sd)
+{
+ const struct PACKET_CZ_REQ_STYLE_CHANGE *p = RP2PTR(fd);
+
+ if (p->HeadStyle > 0)
+ clif->cz_req_style_change_sub(sd, LOOK_HAIR, p->HeadStyle, false);
+ if (p->HeadPalette > 0)
+ clif->cz_req_style_change_sub(sd, LOOK_HAIR_COLOR, p->HeadPalette, false);
+ if (p->BodyPalette > 0)
+ clif->cz_req_style_change_sub(sd, LOOK_CLOTHES_COLOR, p->BodyPalette, false);
+ if (p->TopAccessory > 0)
+ clif->cz_req_style_change_sub(sd, LOOK_HEAD_TOP, p->TopAccessory, true);
+ if (p->MidAccessory > 0)
+ clif->cz_req_style_change_sub(sd, LOOK_HEAD_MID, p->MidAccessory, true);
+ if (p->BottomAccessory > 0)
+ clif->cz_req_style_change_sub(sd, LOOK_HEAD_BOTTOM, p->BottomAccessory, true);
+
+ clif->style_change_response(sd, STYLIST_SHOP_SUCCESS);
+ return;
+}
+
+void clif_cz_req_style_change_sub(struct map_session_data *sd, int type, int16 idx, bool isitem)
+{
+ struct stylist_data_entry *entry;
+
+ nullpo_retv(sd);
+ Assert_retv(idx > 0);
+ Assert_retv(type >= 0 && type < MAX_STYLIST_TYPE);
+
+ if ((idx - 1) < VECTOR_LENGTH(stylist_data[type])) {
+ entry = &VECTOR_INDEX(stylist_data[type], idx - 1);
+ if (clif->style_change_validate_requirements(sd, type, idx - 1)) {
+ if (isitem == false)
+ pc->changelook(sd, type, entry->id);
+ else
+ clif->stylist_send_rodexitem(sd, entry->id);
+ }
+ }
+}
+
+void clif_style_change_response(struct map_session_data *sd, enum stylist_shop flag)
+{
+#if PACKETVER >= 20151104
+ struct PACKET_ZC_STYLE_CHANGE_RES p;
+
+ nullpo_retv(sd);
+
+ p.PacketType = 0x0a47;
+ p.flag = flag;
+
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
+#else
+ ShowWarning("clif_style_change_response: unsupported client version is being used.");
+#endif
+}
+
/*==========================================
* Main client packet processing function
*------------------------------------------*/
@@ -21780,4 +21981,14 @@ void clif_defaults(void) {
clif->ui_action = clif_ui_action;
clif->pPrivateAirshipRequest = clif_parse_private_airship_request;
clif->PrivateAirshipResponse = clif_private_airship_response;
+
+ clif->stylist_vector_init = clif_stylist_vector_init;
+ clif->stylist_vector_clear = clif_stylist_vector_clear;
+ clif->stylist_read_db_libconfig = clif_stylist_read_db_libconfig;
+ clif->stylist_read_db_libconfig_sub = clif_stylist_read_db_libconfig_sub;
+ clif->style_change_validate_requirements = clif_style_change_validate_requirements;
+ clif->stylist_send_rodexitem = clif_stylist_send_rodexitem;
+ clif->pReqStyleChange = clif_parse_cz_req_style_change;
+ clif->cz_req_style_change_sub = clif_cz_req_style_change_sub;
+ clif->style_change_response = clif_style_change_response;
}