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.c131
1 files changed, 91 insertions, 40 deletions
diff --git a/src/map/pet.c b/src/map/pet.c
index 2a9831ed6..f10c55f57 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -94,8 +94,41 @@ static int pet_hungry_val(struct pet_data *pd)
static void pet_set_hunger(struct pet_data *pd, int value)
{
nullpo_retv(pd);
+ nullpo_retv(pd->msd);
pd->pet.hungry = cap_value(value, PET_HUNGER_STARVING, PET_HUNGER_STUFFED);
+
+ clif->send_petdata(pd->msd, pd, 2, pd->pet.hungry);
+}
+
+/**
+ * Calculates the value to store in a pet egg's 4th card slot
+ * based on the passed rename flag and intimacy value.
+ *
+ * @param rename_flag The pet's rename flag.
+ * @param intimacy The pet's intimacy value.
+ * @return The value to store in the pet egg's 4th card slot. (Defaults to 0 in case of error.)
+ *
+ **/
+static int pet_get_card4_value(int rename_flag, int intimacy)
+{
+ Assert_ret(rename_flag == 0 || rename_flag == 1);
+ Assert_ret(intimacy >= PET_INTIMACY_NONE && intimacy <= PET_INTIMACY_MAX);
+
+ int card4 = rename_flag;
+
+ if (intimacy <= PET_INTIMACY_SHY)
+ card4 |= (1 << 1);
+ else if (intimacy <= PET_INTIMACY_NEUTRAL)
+ card4 |= (2 << 1);
+ else if (intimacy <= PET_INTIMACY_CORDIAL)
+ card4 |= (3 << 1);
+ else if (intimacy <= PET_INTIMACY_LOYAL)
+ card4 |= (4 << 1);
+ else
+ card4 |= (5 << 1);
+
+ return card4;
}
/**
@@ -115,18 +148,24 @@ static void pet_set_intimate(struct pet_data *pd, int value)
struct map_session_data *sd = pd->msd;
- status_calc_pc(sd, SCO_NONE);
-
- if (pd->pet.intimate == PET_INTIMACY_NONE) { /// Pet is lost. Delete the egg.
+ if (pd->pet.intimate == PET_INTIMACY_NONE) { // Pet is lost, delete it.
int i;
ARR_FIND(0, sd->status.inventorySize, 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]));
+ && pd->pet.pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
if (i != sd->status.inventorySize)
pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_EGG);
+
+ if (battle_config.pet_remove_immediately != 0) {
+ pet_stop_attack(pd);
+ unit->remove_map(&pd->bl, CLR_OUTSIGHT, ALC_MARK);
+ }
+ } else {
+ clif->send_petdata(sd, pd, 1, pd->pet.intimate);
}
+
+ status_calc_pc(sd, SCO_NONE);
}
/**
@@ -312,17 +351,15 @@ static int pet_hungry(int tid, int64 tick, int id, intptr_t data)
pet_stop_attack(pd);
pet->set_intimate(pd, pd->pet.intimate - pd->petDB->starving_decrement);
- if (pd->pet.intimate == PET_INTIMACY_NONE)
- pd->status.speed = pd->db->status.speed;
+ if (sd->pd == NULL)
+ return 0;
status_calc_pet(pd, SCO_NONE);
- clif->send_petdata(sd, pd, 1, pd->pet.intimate);
if (pd->petDB->starving_delay > 0)
interval = pd->petDB->starving_delay;
}
- clif->send_petdata(sd, pd, 2, pd->pet.hungry);
interval = interval * battle_config.pet_hungry_delay_rate / 100;
pd->pet_hungry_timer = timer->add(tick + max(interval, 1), pet->hungry, sd->bl.id, 0);
@@ -404,7 +441,8 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
if (i != sd->status.inventorySize) {
sd->status.inventory[i].attribute &= ~ATTR_BROKEN;
sd->status.inventory[i].bound = IBT_NONE;
- sd->status.inventory[i].card[3] = pd->pet.rename_flag;
+ sd->status.inventory[i].card[3] = pet->get_card4_value(pd->pet.rename_flag, pd->pet.intimate);
+ clif->inventoryList(sd);
} else {
// The pet egg wasn't found: it was probably hatched with the old system that deleted the egg.
struct item tmp_item = {0};
@@ -415,14 +453,13 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
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;
+ tmp_item.card[3] = pet->get_card4_value(pd->pet.rename_flag, pd->pet.intimate);
if ((flag = pc->additem(sd, &tmp_item, 1, LOG_TYPE_EGG)) != 0) {
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);
}
}
#if PACKETVER >= 20180704
- clif->inventoryList(sd);
clif->send_petdata(sd, pd, 6, 0);
#endif
pd->pet.incubate = 1;
@@ -511,6 +548,35 @@ static int pet_data_init(struct map_session_data *sd, struct s_pet *petinfo)
return 0;
}
+/**
+ * Spawns a pet.
+ *
+ * @param sd The pet's master.
+ * @param birth_process Whether the pet is spawned during birth process.
+ * @return 1 on failure, 0 on success.
+ *
+ **/
+static int pet_spawn(struct map_session_data *sd, bool birth_process)
+{
+ nullpo_retr(1, sd);
+ nullpo_retr(1, sd->pd);
+
+ if (map->addblock(&sd->pd->bl) != 0 || !clif->spawn(&sd->pd->bl))
+ return 1;
+
+ clif->send_petdata(sd, sd->pd, 0, 0);
+ clif->send_petdata(sd, sd->pd, 5, battle_config.pet_hair_style);
+
+#if PACKETVER >= 20180704
+ if (birth_process)
+ clif->send_petdata(sd, sd->pd, 6, 1);
+#endif
+
+ clif->send_petstatus(sd);
+
+ return 0;
+}
+
static int pet_birth_process(struct map_session_data *sd, struct s_pet *petinfo)
{
nullpo_retr(1, sd);
@@ -535,17 +601,11 @@ static int pet_birth_process(struct map_session_data *sd, struct s_pet *petinfo)
if (map->save_settings&8)
chrif->save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex]
- if(sd->bl.prev != NULL) {
- map->addblock(&sd->pd->bl);
- clif->spawn(&sd->pd->bl);
- clif->send_petdata(sd,sd->pd, 0,0);
- clif->send_petdata(sd,sd->pd, 5,battle_config.pet_hair_style);
-#if PACKETVER >= 20180704
- clif->send_petdata(sd, sd->pd, 6, 1);
-#endif
- clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
- clif->send_petstatus(sd);
+ if (sd->pd != NULL && sd->bl.prev != NULL) {
+ if (pet->spawn(sd, true) != 0)
+ return 1;
}
+
Assert_retr(1, sd->status.pet_id == 0 || sd->pd == 0 || sd->pd->msd == sd);
return 0;
@@ -584,13 +644,9 @@ static int pet_recv_petdata(int account_id, struct s_pet *p, int flag)
}
} else {
pet->data_init(sd,p);
- if(sd->pd && sd->bl.prev != NULL) {
- map->addblock(&sd->pd->bl);
- clif->spawn(&sd->pd->bl);
- clif->send_petdata(sd,sd->pd,0,0);
- clif->send_petdata(sd,sd->pd,5,battle_config.pet_hair_style);
- clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
- clif->send_petstatus(sd);
+ if (sd->pd != NULL && sd->bl.prev != NULL) {
+ if (pet->spawn(sd, false) != 0)
+ return 1;
}
}
@@ -644,8 +700,6 @@ static int pet_catch_process2(struct map_session_data *sd, int target_id)
return 1;
}
- //FIXME: Delete taming item here, if this was an item-invoked capture and the item was flagged as delay-consume. [ultramage]
-
// catch_target_class == 0 is used for universal lures (except bosses for now). [Skotlex]
if (sd->catch_target_class == 0 && (md->status.mode & MD_BOSS) == 0)
sd->catch_target_class = md->class_;
@@ -729,7 +783,7 @@ static bool pet_get_egg(int account_id, int pet_class, int pet_id)
tmp_item.card[0] = CARD0_PET;
tmp_item.card[1] = GetWord(pet_id,0);
tmp_item.card[2] = GetWord(pet_id,1);
- tmp_item.card[3] = 0; //New pets are not named.
+ tmp_item.card[3] = pet->get_card4_value(0, pet->db[i].intimate);
if((ret = pc->additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER))) {
clif->additem(sd,0,0,ret);
map->addflooritem(&sd->bl, &tmp_item, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
@@ -828,8 +882,6 @@ static int pet_change_name_ack(struct map_session_data *sd, const char *name, in
aFree(newname);
clif->blname_ack(0,&pd->bl);
pd->pet.rename_flag = 1;
- clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
- clif->send_petstatus(sd);
return 1;
}
@@ -920,6 +972,7 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
{
nullpo_retr(1, sd);
nullpo_retr(1, pd);
+ Assert_retr(1, sd->status.pet_id == pd->pet.pet_id);
int i = pc->search_inventory(sd, pd->petDB->FoodID);
@@ -948,15 +1001,11 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
intimacy = intimacy * battle_config.pet_friendly_rate / 100;
pet->set_intimate(pd, pd->pet.intimate + intimacy);
- if (pd->pet.intimate == PET_INTIMACY_NONE) {
- pet_stop_attack(pd);
- pd->status.speed = pd->db->status.speed;
- }
+ if (sd->pd == NULL)
+ return 0;
status_calc_pet(pd, SCO_NONE);
pet->set_hunger(pd, pd->pet.hungry + pd->petDB->fullness);
- clif->send_petdata(sd, pd, 2, pd->pet.hungry);
- clif->send_petdata(sd, pd, 1, pd->pet.intimate);
clif->pet_food(sd, pd->petDB->FoodID, 1);
return 0;
@@ -1799,6 +1848,7 @@ void pet_defaults(void)
pet->hungry_val = pet_hungry_val;
pet->set_hunger = pet_set_hunger;
+ pet->get_card4_value = pet_get_card4_value;
pet->set_intimate = pet_set_intimate;
pet->create_egg = pet_create_egg;
pet->unlocktarget = pet_unlocktarget;
@@ -1811,6 +1861,7 @@ void pet_defaults(void)
pet->performance = pet_performance;
pet->return_egg = pet_return_egg;
pet->data_init = pet_data_init;
+ pet->spawn = pet_spawn;
pet->birth_process = pet_birth_process;
pet->recv_petdata = pet_recv_petdata;
pet->select_egg = pet_select_egg;