Small achievements cleanup (#7368)

* Move logic into lua engine code.
* Don't let use of limit decrease an achievement's progress.
This commit is contained in:
Pentarctagon 2023-02-09 18:36:45 -06:00 committed by GitHub
parent f238a9e026
commit e61fca0bf4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 29 deletions

View file

@ -1013,12 +1013,7 @@ function wml_actions.remove_trait(cfg)
end
function wml_actions.set_achievement(cfg)
local achievement = wesnoth.achievements.get(cfg.content_for, cfg.id)
-- don't show the achievement popup for an achievement they already have
if not achievement.achieved then
wesnoth.achievements.set(cfg.content_for, cfg.id)
gui.show_popup(achievement.name_completed, achievement.description_completed, achievement.icon_completed)
end
wesnoth.achievements.set(cfg.content_for, cfg.id)
end
function wml_actions.progress_achievement(cfg)
@ -1027,9 +1022,5 @@ function wml_actions.progress_achievement(cfg)
return
end
local pcfg = wesnoth.achievements.progress(cfg.content_for, cfg.id, cfg.amount, tonumber(cfg.limit) or 999999999)
-- if this update completes the achievement, mark it as complete and show the popup
if pcfg.progress ~= -1 and pcfg.max_progress > 0 and pcfg.progress >= pcfg.max_progress then
wml_actions.set_achievement(cfg)
end
wesnoth.achievements.progress(cfg.content_for, cfg.id, cfg.amount, tonumber(cfg.limit) or 999999999)
end

View file

@ -1085,7 +1085,13 @@ int progress_achievement(const std::string& content_for, const std::string& id,
{
if(in_progress["id"].str() == id)
{
in_progress["progress_at"] = std::clamp(in_progress["progress_at"].to_int() + amount, 0, std::min(limit, max_progress));
// don't let using 'limit' decrease the achievement's current progress
int starting_progress = in_progress["progress_at"].to_int();
if(starting_progress >= limit) {
return starting_progress;
}
in_progress["progress_at"] = std::clamp(starting_progress + amount, 0, std::min(limit, max_progress));
return in_progress["progress_at"].to_int();
}
}

View file

@ -3078,6 +3078,10 @@ int game_lua_kernel::intf_set_achievement(lua_State *L)
if(group.content_for_ == content_for) {
for(achievement& achieve : group.achievements_) {
if(achieve.id_ == id) {
// already achieved
if(achieve.achieved_) {
return 0;
}
// found the achievement - mark it as completed
preferences::set_achievement(content_for, id);
achieve.achieved_ = true;
@ -3088,6 +3092,12 @@ int game_lua_kernel::intf_set_achievement(lua_State *L)
if(achieve.sound_path_ != "") {
sound::play_sound(achieve.sound_path_, sound::SOUND_FX);
}
// show the achievement popup
luaW_getglobal(L, "gui", "show_popup");
luaW_pushtstring(L, achieve.name_completed_);
luaW_pushtstring(L, achieve.description_completed_);
lua_pushstring(L, achieve.icon_completed_.c_str());
luaW_pcall(L, 3, 0, 0);
return 0;
}
}
@ -3173,47 +3183,56 @@ int game_lua_kernel::intf_get_achievement(lua_State *L)
* - Arg 2: string - id.
* - Arg 3: int - the amount to progress the achievement.
* - Arg 4: int - the limit the achievement can progress by
* - Ret 1: WML table returned by the function.
* - Ret 1: int - the achievement's current progress after adding amount, -2 if not found, -1 not a progressable achievement (including if it's already achieved)
* - Ret 2: int - the achievement's max progress, -2 if not found, or -1 not a progressable achievement
*/
int game_lua_kernel::intf_progress_achievement(lua_State *L)
{
const char *content_for = luaL_checkstring(L, 1);
const char *id = luaL_checkstring(L, 2);
int amount = luaL_checkinteger(L, 3);
int limit = luaL_checkinteger(L, 4);
config cfg;
cfg["progress"] = 0;
cfg["max_progress"] = 0;
int limit = luaL_optinteger(L, 4, 999999999);
for(achievement_group& group : game_config_manager::get()->get_achievements()) {
if(group.content_for_ == content_for) {
for(achievement& achieve : group.achievements_) {
if(achieve.id_ == id) {
// found the achievement
// check that this is a progressable achievement
if(achieve.max_progress_ == 0) {
ERR_LUA << "Attempted to progress achievement " << id << " for achievement group " << content_for << ", which does not have max_progress set.";
lua_pushinteger(L, -1);
lua_pushinteger(L, -1);
return 2;
}
if(!achieve.achieved_) {
int progress = preferences::progress_achievement(content_for, id, limit, achieve.max_progress_, amount);
cfg["progress"] = progress;
achieve.current_progress_ = progress;
if(progress >= achieve.max_progress_) {
intf_set_achievement(L);
achieve.current_progress_ = -1;
}
lua_pushinteger(L, progress);
} else {
cfg["progress"] = -1;
lua_pushinteger(L, -1);
}
cfg["max_progress"] = achieve.max_progress_;
luaW_pushconfig(L, cfg);
return 1;
lua_pushinteger(L, achieve.max_progress_);
return 2;
}
}
// achievement not found - existing achievement group but non-existing achievement id
ERR_LUA << "Achievement " << id << " not found for achievement group " << content_for;
luaW_pushconfig(L, cfg);
return 1;
lua_pushinteger(L, -2);
lua_pushinteger(L, -2);
return 2;
}
}
// achievement group not found
ERR_LUA << "Achievement group " << content_for << " not found";
luaW_pushconfig(L, cfg);
return 1;
lua_pushinteger(L, -2);
lua_pushinteger(L, -2);
return 2;
}
/**