summaryrefslogtreecommitdiff
path: root/src/map/achievement.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/achievement.c')
-rw-r--r--src/map/achievement.c84
1 files changed, 52 insertions, 32 deletions
diff --git a/src/map/achievement.c b/src/map/achievement.c
index 0369b0fb5..7148acae8 100644
--- a/src/map/achievement.c
+++ b/src/map/achievement.c
@@ -733,7 +733,7 @@ static void achievement_validate_zeny(struct map_session_data *sd, int amount)
achievement->validate_type(sd, ACH_ZENY_GET_ONCE, &criteria, false);
achievement->validate_type(sd, ACH_ZENY_GET_TOTAL, &criteria, true);
} else {
- criteria.goal = amount;
+ criteria.goal = -amount;
achievement->validate_type(sd, ACH_ZENY_SPEND_ONCE, &criteria, false);
achievement->validate_type(sd, ACH_ZENY_SPEND_TOTAL, &criteria, true);
}
@@ -772,6 +772,10 @@ static void achievement_validate_refine(struct map_session_data *sd, unsigned in
criteria.goal = sd->status.inventory[idx].refine;
+ // achievement should not trigger if refine is 0
+ if (criteria.goal == 0)
+ return;
+
/* Universal */
achievement->validate_type(sd,
success ? ACH_EQUIP_REFINE_SUCCESS : ACH_EQUIP_REFINE_FAILURE,
@@ -1016,44 +1020,56 @@ static bool achievement_check_title(struct map_session_data *sd, int title_id) {
return false;
}
-/**
- * Achievement rewards are given to player
- * @param sd session data
- * @param ad achievement data
- */
-static void achievement_get_rewards(struct map_session_data *sd, const struct achievement_data *ad) {
- int i = 0;
- struct achievement *ach = NULL;
-
+static void achievement_get_rewards_buffs(struct map_session_data *sd, const struct achievement_data *ad)
+{
nullpo_retv(sd);
nullpo_retv(ad);
- if ((ach = achievement->ensure(sd, ad)) == NULL)
- return;
-
- /* Buff */
if (ad->rewards.bonus != NULL)
script->run(ad->rewards.bonus, 0, sd->bl.id, 0);
+}
- /* Give Items */
- for (i = 0; i < VECTOR_LENGTH(ad->rewards.item); i++) {
- struct item it = { 0 };
- int total = 0;
+// TODO: kro send items by rodex
+static void achievement_get_rewards_items(struct map_session_data *sd, const struct achievement_data *ad)
+{
+ nullpo_retv(sd);
+ nullpo_retv(ad);
- it.nameid = VECTOR_INDEX(ad->rewards.item, i).id;
- total = VECTOR_INDEX(ad->rewards.item, i).amount;
+ struct item it = { 0 };
+ it.identify = 1;
- it.identify = 1;
+ for (int i = 0; i < VECTOR_LENGTH(ad->rewards.item); i++) {
+ it.nameid = VECTOR_INDEX(ad->rewards.item, i).id;
+ int total = VECTOR_INDEX(ad->rewards.item, i).amount;
//Check if it's stackable.
if (!itemdb->isstackable(it.nameid)) {
- int j = 0;
- for (j = 0; j < total; ++j)
- pc->additem(sd, &it, (it.amount = 1), LOG_TYPE_SCRIPT);
+ it.amount = 1;
+ for (int j = 0; j < total; ++j)
+ pc->additem(sd, &it, 1, LOG_TYPE_SCRIPT);
} else {
- pc->additem(sd, &it, (it.amount = total), LOG_TYPE_SCRIPT);
+ it.amount = total;
+ pc->additem(sd, &it, total, LOG_TYPE_SCRIPT);
}
}
+}
+
+/**
+ * Achievement rewards are given to player
+ * @param sd session data
+ * @param ad achievement data
+ */
+static bool achievement_get_rewards(struct map_session_data *sd, const struct achievement_data *ad)
+{
+ nullpo_retr(false, sd);
+ nullpo_retr(false, ad);
+
+ struct achievement *ach = achievement->ensure(sd, ad);
+ if (ach == NULL)
+ return false;
+
+ /* Buff */
+ achievement->get_rewards_buffs(sd, ad);
ach->rewarded_at = time(NULL);
@@ -1062,9 +1078,14 @@ static void achievement_get_rewards(struct map_session_data *sd, const struct ac
VECTOR_PUSH(sd->title_ids, ad->rewards.title_id);
clif->achievement_send_list(sd->fd, sd);
} else {
- clif->achievement_reward_ack(sd->fd, sd, ad);
clif->achievement_send_update(sd->fd, sd, ad); // send update.
+ clif->achievement_reward_ack(sd->fd, sd, ad);
}
+
+ /* Give Items */
+ achievement->get_rewards_items(sd, ad);
+
+ return true;
}
/**
@@ -1088,7 +1109,7 @@ static void achievement_readdb_ranks(void)
}
while (entry < libconfig->setting_length(ardb) && entry < MAX_ACHIEVEMENT_RANKS) {
- char rank[8];
+ char rank[16];
if (!(conf = libconfig->setting_get_elem(ardb, entry))) {
ShowError("achievement_readdb_ranks: Could not read value for entry %d, skipping...\n", entry+1);
@@ -1378,11 +1399,10 @@ static bool achievement_readdb_validate_criteria_itemtype(const struct config_se
}
} else if ((tt = libconfig->setting_get_member(t, "ItemType")) && config_setting_is_array(tt)) {
int j = 0;
- uint32 it_type = 0;
while (j < libconfig->setting_length(tt)) {
if ((val = libconfig->setting_get_int_elem(tt, j))) {
- if (val < IT_HEALING || val >= IT_MAX) {
+ if (val < IT_HEALING || val > IT_MAX) {
ShowError("achievement_readdb_validate_criteria_itemtype: Invalid ItemType %d provided (Achievement: %d, Objective: %d). Skipping...\n", val, entry_id, obj_idx);
continue;
}
@@ -1405,8 +1425,6 @@ static bool achievement_readdb_validate_criteria_itemtype(const struct config_se
}
j++;
}
-
- obj->item_type = it_type;
} else if (achievement_criteria_itemtype(type)) {
ShowError("achievement_readdb_validate_criteria_itemtype: Criteria requires a ItemType field (Achievement: %d, Objective: %d). Skipping...\n", entry_id, obj_idx);
return false;
@@ -1780,7 +1798,7 @@ static void achievement_readb(void)
if (libconfig->setting_lookup_int(conf, "Id", &t_ad.id) == 0) {
ShowError("achievement_readdb: Id field for entry %d is not provided! Skipping...\n", entry);
continue;
- } else if (t_ad.id <= 0 || t_ad.id > INT32_MAX) {
+ } else if (t_ad.id <= 0) {
ShowError("achievement_readdb: Invalid Id %d for entry %d. Skipping...\n", t_ad.id, entry);
continue;
}
@@ -1980,4 +1998,6 @@ void achievement_defaults(void)
achievement->init_titles = achievement_init_titles;
achievement->check_title = achievement_check_title;
achievement->get_rewards = achievement_get_rewards;
+ achievement->get_rewards_buffs = achievement_get_rewards_buffs;
+ achievement->get_rewards_items = achievement_get_rewards_items;
}