summaryrefslogtreecommitdiff
path: root/src/map/pet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/pet.c')
-rw-r--r--src/map/pet.c163
1 files changed, 142 insertions, 21 deletions
diff --git a/src/map/pet.c b/src/map/pet.c
index 4bac79dc8..58c26d1ce 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -85,8 +85,21 @@ void pet_set_intimate(struct pet_data *pd, int value)
sd = pd->msd;
pd->pet.intimate = value;
+
if( (intimate >= battle_config.pet_equip_min_friendly && pd->pet.intimate < battle_config.pet_equip_min_friendly) || (intimate < battle_config.pet_equip_min_friendly && pd->pet.intimate >= battle_config.pet_equip_min_friendly) )
status_calc_pc(sd,SCO_NONE);
+
+ /* Pet is lost, delete the egg */
+ if (value <= 0) {
+ int i;
+
+ ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].card[0] == CARD0_PET &&
+ pd->pet.pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
+
+ if (i != MAX_INVENTORY) {
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_EGG);
+ }
+ }
}
int pet_create_egg(struct map_session_data *sd, int item_id)
@@ -233,6 +246,13 @@ int pet_hungry(int tid, int64 tick, int id, intptr_t data) {
return 1; //You lost the pet already, the rest is irrelevant.
pd->pet.hungry--;
+ /* Pet Autofeed */
+ if (battle_config.feature_enable_homun_autofeed != 0) {
+ if (pd->petDB->autofeed == 1 && pd->pet.autofeed == 1 && pd->pet.hungry <= 25) {
+ pet->food(sd, pd);
+ }
+ }
+
if( pd->pet.hungry < 0 )
{
pet_stop_attack(pd);
@@ -311,23 +331,21 @@ int pet_performance(struct map_session_data *sd, struct pet_data *pd)
int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
{
- struct item tmp_item;
- int flag;
+ int i;
nullpo_retr(1, sd);
nullpo_retr(1, pd);
pet->lootitem_drop(pd,sd);
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.nameid = pd->petDB->EggID;
- tmp_item.identify = 1;
- tmp_item.card[0] = CARD0_PET;
- tmp_item.card[1] = GetWord(pd->pet.pet_id,0);
- tmp_item.card[2] = GetWord(pd->pet.pet_id,1);
- tmp_item.card[3] = pd->pet.rename_flag;
- if((flag = pc->additem(sd,&tmp_item,1,LOG_TYPE_EGG))) {
- clif->additem(sd,0,0,flag);
- map->addflooritem(&sd->bl, &tmp_item, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
+
+ // Pet Evolution
+ ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].card[0] == CARD0_PET &&
+ pd->pet.pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
+
+ if (i != MAX_INVENTORY) {
+ sd->status.inventory[i].identify = 1;
+ sd->status.inventory[i].bound = IBT_NONE;
}
+
pd->pet.incubate = 1;
unit->free(&pd->bl,CLR_OUTSIGHT);
@@ -462,19 +480,23 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag) {
}
if(p->incubate == 1) {
int i;
- //Delete egg from inventory. [Skotlex]
- for (i = 0; i < MAX_INVENTORY; i++) {
- if(sd->status.inventory[i].card[0] == CARD0_PET &&
- p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]))
- break;
- }
- if(i >= MAX_INVENTORY) {
+ // Get Egg Index
+ ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].card[0] == CARD0_PET &&
+ p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
+
+ if(i == MAX_INVENTORY) {
ShowError("pet_recv_petdata: Hatching pet (%d:%s) aborted, couldn't find egg in inventory for removal!\n",p->pet_id, p->name);
sd->status.pet_id = 0;
return 1;
}
- if (!pet->birth_process(sd,p)) //Pet hatched. Delete egg.
- pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_EGG);
+
+
+ if (!pet->birth_process(sd,p)) {
+ // Pet Evolution, Hide the egg by setting identify to 0 [Dastgir/Hercules]
+ sd->status.inventory[i].identify = 0;
+ // bind the egg to the character to avoid moving it via forged packets [Asheraf]
+ sd->status.inventory[i].bound = IBT_CHARACTER;
+ }
} else {
pet->data_init(sd,p);
if(sd->pd && sd->bl.prev != NULL) {
@@ -1359,6 +1381,14 @@ int pet_read_db_sub(struct config_setting_t *it, int n, const char *source)
if (libconfig->setting_lookup_int(it, "ChangeTargetRate", &i32))
pet->db[n].change_target_rate = i32;
+ // Pet Evolution
+ if ((t = libconfig->setting_get_member(it, "Evolve")) && config_setting_is_group(t)) {
+ pet->read_db_sub_evolution(t, n);
+ }
+
+ if ((t = libconfig->setting_get_member(it, "AutoFeed")) && (i32 = libconfig->setting_get_bool(t)))
+ pet->db[n].autofeed = i32;
+
if (libconfig->setting_lookup_string(it, "PetScript", &str))
pet->db[n].pet_script = *str ? script->parse(str, source, -pet->db[n].class_, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
@@ -1368,6 +1398,81 @@ int pet_read_db_sub(struct config_setting_t *it, int n, const char *source)
return pet->db[n].class_;
}
+/**
+ * Read Pet Evolution Database [Dastgir/Hercules]
+ * @param t libconfig setting
+ * @param n Pet DB Index
+ */
+void pet_read_db_sub_evolution(struct config_setting_t *t, int n)
+{
+ struct config_setting_t *pett;
+ int i = 0;
+ const char *str = NULL;
+
+ nullpo_retv(t);
+ Assert_retv(n >= 0 && n < MAX_PET_DB);
+
+ VECTOR_INIT(pet->db[n].evolve_data);
+
+ while ((pett = libconfig->setting_get_elem(t, i))) {
+ if (config_setting_is_group(pett)) {
+ struct pet_evolve_data ped;
+ struct item_data *data;
+ struct config_setting_t *item;
+ int j = 0, i32 = 0;
+
+ str = config_setting_name(pett);
+
+ if (!(data = itemdb->name2id(str))) {
+ ShowWarning("pet_read_evolve_db_sub: Invalid Egg '%s' in Pet #%d, skipping.\n", str, pet->db[n].class_);
+ return;
+ } else {
+ ped.petEggId = data->nameid;
+ }
+
+ VECTOR_INIT(ped.items);
+
+ while ((item = libconfig->setting_get_elem(pett, j))) {
+ struct itemlist_entry list = { 0 };
+ int quantity = 0;
+
+ str = config_setting_name(item);
+ data = itemdb->search_name(str);
+
+ if (!data) {
+ ShowWarning("pet_read_evolve_db_sub: required item %s not found in egg %d\n", str, ped.petEggId);
+ j++;
+ continue;
+ }
+
+ list.id = data->nameid;
+
+ if (mob->get_const(item, &i32) && i32 >= 0) {
+ quantity = i32;
+ }
+
+ if (quantity <= 0) {
+ ShowWarning("pet_read_evolve_db_sub: invalid quantity %d for egg %d\n", quantity, ped.petEggId);
+ j++;
+ continue;
+ }
+
+ list.amount = quantity;
+
+ VECTOR_ENSURE(ped.items, 1, 1);
+ VECTOR_PUSH(ped.items, list);
+
+ j++;
+
+ }
+
+ VECTOR_ENSURE(pet->db[n].evolve_data, 1, 1);
+ VECTOR_PUSH(pet->db[n].evolve_data, ped);
+ }
+ i++;
+ }
+}
+
bool pet_read_db_sub_intimacy(int idx, struct config_setting_t *t)
{
int i32 = 0;
@@ -1396,6 +1501,7 @@ void pet_read_db_clear(void)
// Remove any previous scripts in case reloaddb was invoked.
for (i = 0; i < MAX_PET_DB; i++) {
+ int j;
if (pet->db[i].pet_script) {
script->free_code(pet->db[i].pet_script);
pet->db[i].pet_script = NULL;
@@ -1404,6 +1510,11 @@ void pet_read_db_clear(void)
script->free_code(pet->db[i].equip_script);
pet->db[i].equip_script = NULL;
}
+
+ for (j = 0; j < VECTOR_LENGTH(pet->db[i].evolve_data); j++) {
+ VECTOR_CLEAR(VECTOR_INDEX(pet->db[i].evolve_data, j).items);
+ }
+ VECTOR_CLEAR(pet->db[i].evolve_data);
}
memset(pet->db, 0, sizeof(pet->db));
return;
@@ -1437,6 +1548,7 @@ int do_final_pet(void)
int i;
for( i = 0; i < MAX_PET_DB; i++ )
{
+ int j;
if( pet->db[i].pet_script )
{
script->free_code(pet->db[i].pet_script);
@@ -1447,9 +1559,16 @@ int do_final_pet(void)
script->free_code(pet->db[i].equip_script);
pet->db[i].equip_script = NULL;
}
+
+ /* Pet Evolution [Dastgir/Hercules] */
+ for (j = 0; j < VECTOR_LENGTH(pet->db[i].evolve_data); j++) {
+ VECTOR_CLEAR(VECTOR_INDEX(pet->db[i].evolve_data, j).items);
+ }
+ VECTOR_CLEAR(pet->db[i].evolve_data);
}
ers_destroy(pet->item_drop_ers);
ers_destroy(pet->item_drop_list_ers);
+
return 0;
}
void pet_defaults(void) {
@@ -1503,4 +1622,6 @@ void pet_defaults(void) {
pet->read_db_sub = pet_read_db_sub;
pet->read_db_sub_intimacy = pet_read_db_sub_intimacy;
pet->read_db_clear = pet_read_db_clear;
+
+ pet->read_db_sub_evolution = pet_read_db_sub_evolution;
}