X-Git-Url: http://nitlanguage.org diff --git a/contrib/nitrpg/src/achievements.nit b/contrib/nitrpg/src/achievements.nit index 9b18a6b..2097ec3 100644 --- a/contrib/nitrpg/src/achievements.nit +++ b/contrib/nitrpg/src/achievements.nit @@ -32,22 +32,28 @@ redef class GameEntity # # TODO should update the achievement? fun add_achievement(achievement: Achievement) do - var key = self.key / achievement.key - if game.store.has_key(key) then return stats.inc("achievements") - achievement.save_in(self.key) - save + achievement.owner = self + achievement.save end + # Is `a` unlocked for this `Player`? + fun has_achievement(a: Achievement): Bool do return load_achievement(a.id) != null + # Load the event from its `id`. # # Looks for the event save file in game data. # Returns `null` if the event cannot be found. fun load_achievement(id: String): nullable Achievement do - var key = self.key / "achievements" / id - if not game.store.has_key(key) then return null - var json = game.store.load_object(key) - return new Achievement.from_json(game, json) + var req = new JsonObject + req["id"] = id + req["game"] = game.key + req["owner"] = key + var obj = game.db.collection("achievements").find(req) + if obj isa JsonObject then + return new Achievement.from_json(game, obj) + end + return null end # List all events registered in this entity. @@ -56,12 +62,13 @@ redef class GameEntity # # To add events see `add_event`. fun load_achievements: MapRead[String, Achievement] do + var req = new JsonObject + req["game"] = game.key + req["owner"] = key var res = new HashMap[String, Achievement] - var key = self.key / "achievements" - if not game.store.has_collection(key) then return res - var coll = game.store.list_collection(key) - for id in coll do - res[id.to_s] = load_achievement(id.to_s).as(not null) + for obj in game.db.collection("achievements").find_all(req) do + var achievement = new Achievement.from_json(game, obj) + res[achievement.id] = achievement end return res end @@ -74,10 +81,16 @@ end class Achievement super GameEntity - redef var key is lazy do return "achievements" / id + redef var collection_name = "achievements" redef var game + redef fun key do + var owner = self.owner + if owner == null then return id + return "{owner.key}-{id}" + end + # Uniq ID for this achievement. var id: String @@ -93,30 +106,34 @@ class Achievement # Is this achievement unlocked by somebody? var is_unlocked: Bool is lazy do return not load_events.is_empty + # Game entity this achievement is about. + var owner: nullable GameEntity = null + # Init `self` from a `json` object. # # Used to load achievements from storage. init from_json(game: Game, json: JsonObject) do - init(game, json["id"].to_s, json["name"].to_s, json["desc"].to_s, json["reward"].as(Int)) + init(game, + json["id"].as(String), + json["name"].as(String), + json["desc"].as(String), + json["reward"].as(Int)) end - redef fun to_json do + redef fun to_json_object do var json = super json["id"] = id json["name"] = name json["desc"] = desc json["reward"] = reward + json["game"] = game.key + var owner = self.owner + if owner != null then json["owner"] = owner.key return json end end redef class Player - - # Is `a` unlocked for this `Player`? - fun has_achievement(a: Achievement): Bool do - return load_achievement(a.id) != null - end - # Unlocks an achievement for this Player based on a GithubEvent. # # Register the achievement and adds the achievement reward to the player @@ -130,6 +147,7 @@ redef class Player nitcoins += a.reward add_achievement(a) trigger_unlock_event(a, event) + save end # Create a new event that marks the achievement unlocking. @@ -138,7 +156,7 @@ redef class Player obj["player"] = name obj["reward"] = achievement.reward obj["achievement"] = achievement.id - obj["github_event"] = event.json + obj["github_event"] = event var ge = new GameEvent(game, "achievement_unlocked", obj) add_event(ge) game.add_event(ge) @@ -346,7 +364,7 @@ abstract class PlayerXCommits if not event.action == "closed" then return if not event.pull.merged then return var player = event.pull.user.player(game) - if player.stats["commits"] == threshold then + if player.stats["commits"] >= threshold then var a = new_achievement(game) player.unlock_achievement(a, event) end @@ -447,7 +465,7 @@ end class Player1KComments super PlayerXComments - redef var id = "player_1000__comments" + redef var id = "player_1000_comments" redef var name = "You sir, talk a lot!" redef var desc = "Comment 1000 times on issues." redef var reward = 1000