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.c144
1 files changed, 136 insertions, 8 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index aeaf03e43..c085c4fe4 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -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);
@@ -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);
@@ -21991,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;
+
}