diff options
Diffstat (limited to 'src/map/clif.c')
-rw-r--r-- | src/map/clif.c | 189 |
1 files changed, 162 insertions, 27 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index a4d2f62b1..c085c4fe4 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; @@ -9093,7 +9093,7 @@ void clif_feel_hate_reset(struct map_session_data *sd) /// value: /// 0 = disabled /// 1 = enabled -void clif_zc_config(struct map_session_data* sd, int type, int flag) +void clif_zc_config(struct map_session_data* sd, enum CZ_CONFIG type, int flag) { int fd; nullpo_retv(sd); @@ -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); @@ -13755,6 +13755,115 @@ void clif_parse_ChangePetName(int fd, struct map_session_data *sd) pet->change_name(sd, RFIFOP(fd,2)); } +void clif_parse_pet_evolution(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +/// Request to Evolve the pet (CZ_PET_EVOLUTION) [Dastgir/Hercules] +/// 09fb <Length>.W <EvolvedPetEggID>.W {<index>.W <amount>.W}*items +void clif_parse_pet_evolution(int fd, struct map_session_data *sd) +{ + const struct PACKET_CZ_PET_EVOLUTION *p = RP2PTR(fd); + int i = 0, idx, petIndex; + + Assert_retv(p->PacketLength >= (uint16)sizeof(struct PACKET_CZ_PET_EVOLUTION)); + + if (sd->status.pet_id == 0) { + clif->petEvolutionResult(fd, PET_EVOL_NO_CALLPET); + return; + } + + ARR_FIND(0, MAX_INVENTORY, idx, sd->status.inventory[idx].card[0] == CARD0_PET && + sd->status.pet_id == MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2])); + + if (idx == MAX_INVENTORY) { + clif->petEvolutionResult(fd, PET_EVOL_NO_PETEGG); + return; + } + + // Not Loyal Yet + if (sd->pd == NULL || sd->pd->pet.intimate < 900) { + clif->petEvolutionResult(fd, PET_EVOL_RG_FAMILIAR); + return; + } + + ARR_FIND(0, MAX_PET_DB, petIndex, pet->db[petIndex].class_ == sd->pd->pet.class_); + + if (petIndex == MAX_PET_DB) { + // Which error? + clif->petEvolutionResult(fd, PET_EVOL_UNKNOWN); + return; + } + + // Client side validation is not done as it is insecure. + for (i = 0; i < VECTOR_LENGTH(pet->db[petIndex].evolve_data); i++) { + struct pet_evolve_data *ped = &VECTOR_INDEX(pet->db[petIndex].evolve_data, i); + if (ped->petEggId == p->EvolvedPetEggID) { + int j; + int pet_id; + + if (VECTOR_LENGTH(ped->items) == 0) { + clif->petEvolutionResult(fd, PET_EVOL_NO_RECIPE); + return; + } + for (j = 0; j < VECTOR_LENGTH(ped->items); j++) { + struct itemlist_entry *list = &VECTOR_INDEX(ped->items, j); + int n = pc->search_inventory(sd, list->id); + + if (n == INDEX_NOT_FOUND) { + clif->petEvolutionResult(fd, PET_EVOL_NO_MATERIAL); + return; + } + } + + for (j = 0; j < VECTOR_LENGTH(ped->items); j++) { + struct itemlist_entry *list = &VECTOR_INDEX(ped->items, j); + int n = pc->search_inventory(sd, list->id); + + if (pc->delitem(sd, n, list->amount, 0, DELITEM_NORMAL, LOG_TYPE_EGG) == 1) { + clif->petEvolutionResult(fd, PET_EVOL_NO_MATERIAL); + return; + } + } + + // Return to Egg + pet->return_egg(sd, sd->pd); + + if (pc->delitem(sd, idx, 1, 0, DELITEM_NORMAL, LOG_TYPE_EGG) == 1) { + clif->petEvolutionResult(fd, PET_EVOL_NO_PETEGG); + return; + } + + pet_id = pet->search_petDB_index(ped->petEggId, PET_EGG); + if (pet_id >= 0) { + sd->catch_target_class = pet->db[pet_id].class_; + + intif->create_pet( + sd->status.account_id, sd->status.char_id, + (short)pet->db[pet_id].class_, (short)mob->db(pet->db[pet_id].class_)->lv, + (short)pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate, + 100, 0, 1, pet->db[pet_id].jname); + clif->petEvolutionResult(fd, PET_EVOL_SUCCESS); + } else { + clif->petEvolutionResult(fd, PET_EVOL_UNKNOWN); + } + return; + } + } + + clif->petEvolutionResult(fd, PET_EVOL_UNKNOWN); +} + +/** + * Result of Pet Evolution (ZC_PET_EVOLUTION_RESULT) + * 0x9fc <Result>.L + */ +void clif_pet_evolution_result(int fd, enum pet_evolution_result result) { +#if PACKETVER >= 20140122 + WFIFOHEAD(fd, packet_len(0x9fc)); + WFIFOW(fd, 0) = 0x9fc; + WFIFOL(fd, 2) = result; + WFIFOSET(fd, packet_len(0x9fc)); +#endif +} + void clif_parse_GMKick(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); /// /kill (CZ_DISCONNECT_CHARACTER). /// Request to disconnect a character. @@ -16154,24 +16263,38 @@ void clif_parse_cz_config(int fd, struct map_session_data *sd) __attribute__((no /// 02d8 <type>.L <value>.L /// type: /// 0 = open equip window +/// 2 = pet autofeeding /// 3 = homunculus autofeeding /// value: /// 0 = disabled /// 1 = enabled void clif_parse_cz_config(int fd, struct map_session_data *sd) { - int type = RFIFOL(fd, 2); + enum CZ_CONFIG type = RFIFOL(fd, 2); int flag = RFIFOL(fd, 6); - if (type == CZ_CONFIG_OPEN_EQUIPMENT_WINDOW) { + switch (type) { + case CZ_CONFIG_OPEN_EQUIPMENT_WINDOW: sd->status.show_equip = flag; - } else if (type == CZ_CONFIG_HOMUNCULUS_AUTOFEEDING) { - struct homun_data *hd; - hd = sd->hd; + break; + case CZ_CONFIG_PET_AUTOFEEDING: { + struct pet_data *pd = sd->pd; + nullpo_retv(pd); + if (pd->petDB->autofeed == 0) { + clif->message(fd, "Autofeed is disabled for this pet."); + return; + } + pd->pet.autofeed = flag; + break; + } + case CZ_CONFIG_HOMUNCULUS_AUTOFEEDING: { + struct homun_data *hd = sd->hd; nullpo_retv(hd); hd->homunculus.autofeed = flag; - } else { - ShowWarning("clif_parse_cz_config: Unsupported type has been received (%d).", type); + break; + } + default: + ShowWarning("clif_parse_cz_config: Unsupported type has been received (%u).\n", type); return; } clif->zc_config(sd, type, flag); @@ -20531,36 +20654,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 STYLIST_UI: - p.UIType = STYLIST_UI; + p.PacketType = openUiType; + switch (uiType) { + case CZ_STYLIST_UI: + p.UIType = ZC_STYLIST_UI; +#if PACKETVER >= 20171122 p.data = 0; +#endif break; - case 5: // client will send 5 for the request but requires to receive ATTENDANCE_UI (7) to open the correct ui. + 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 } @@ -20827,7 +20957,7 @@ void clif_parse_cz_req_style_change(int fd, struct map_session_data *sd) if (p->BottomAccessory > 0) clif->cz_req_style_change_sub(sd, LOOK_HEAD_BOTTOM, p->BottomAccessory, true); - clif->style_change_response(sd, true); + clif->style_change_response(sd, STYLIST_SHOP_SUCCESS); return; } @@ -20850,7 +20980,7 @@ void clif_cz_req_style_change_sub(struct map_session_data *sd, int type, int16 i } } -void clif_style_change_response(struct map_session_data *sd, int8 flag) +void clif_style_change_response(struct map_session_data *sd, enum stylist_shop flag) { #if PACKETVER >= 20151104 struct PACKET_ZC_STYLE_CHANGE_RES p; @@ -21984,4 +22114,9 @@ void clif_defaults(void) { 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; + + // -- Pet Evolution + clif->pPetEvolution = clif_parse_pet_evolution; + clif->petEvolutionResult = clif_pet_evolution_result; + } |