diff options
Diffstat (limited to 'src/map/achievement.c')
-rw-r--r-- | src/map/achievement.c | 84 |
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; } |