From 4016476c4db78174fb3f427d0b9065301d9ea33f Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 7 Jan 2015 15:03:32 -0800 Subject: [PATCH] Fixed achievement plugin creation of repeatable achievements. Fixed some bugs in recalculating repeatable achievement exp. Implemented recalculating repeatable achievement gems. Achievement tests pass again. --- server/achievements/EarnedAchievement.coffee | 4 ++-- .../achievements/earned_achievement_handler.coffee | 14 ++++++++++---- test/server/functional/achievement.spec.coffee | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/server/achievements/EarnedAchievement.coffee b/server/achievements/EarnedAchievement.coffee index 8d0fe958f..f182c445c 100644 --- a/server/achievements/EarnedAchievement.coffee +++ b/server/achievements/EarnedAchievement.coffee @@ -52,11 +52,11 @@ EarnedAchievementSchema.statics.createForAchievement = (achievement, doc, origin newAmount = util.getByPath(docObj, proportionalTo) or 0 if previouslyEarnedAchievement originalAmount = previouslyEarnedAchievement.get('achievedAmount') or 0 - else if originalDocObj and not newAmount # This branch could get buggy if unchangedCopy tracking isn't working. + else if originalDocObj # This branch could get buggy if unchangedCopy tracking isn't working. originalAmount = util.getByPath(originalDocObj, proportionalTo) or 0 else originalAmount = 0 - #console.log 'original amount is', originalAmount, 'and new amount is', newAmount, 'for', proportionalTo, 'with doc', docObj, 'and previously earned achievement amount', previouslyEarnedAchievement?.get('achievedAmount') + #console.log 'original amount is', originalAmount, 'and new amount is', newAmount, 'for', proportionalTo, 'with doc', docObj, 'and previously earned achievement amount', previouslyEarnedAchievement?.get('achievedAmount'), 'because we had originalDocObj', originalDocObj if originalAmount isnt newAmount expFunction = achievement.getExpFunction() diff --git a/server/achievements/earned_achievement_handler.coffee b/server/achievements/earned_achievement_handler.coffee index 444600a48..f68c08f68 100644 --- a/server/achievements/earned_achievement_handler.coffee +++ b/server/achievements/earned_achievement_handler.coffee @@ -6,6 +6,7 @@ EarnedAchievement = require './EarnedAchievement' User = require '../users/User' Handler = require '../commons/Handler' LocalMongo = require '../../app/lib/LocalMongo' +util = require '../../app/core/utils' class EarnedAchievementHandler extends Handler modelClass: EarnedAchievement @@ -65,8 +66,8 @@ class EarnedAchievementHandler extends Handler return @sendNotFoundError(res, 'Could not find achievement.') else if not trigger return @sendNotFoundError(res, 'Could not find trigger.') - else if achievement.get('proportionalTo') - EarnedAchievement.createForAchievement(achievement, trigger, trigger.unchangedCopy, earned, (earnedAchievementDoc) => + else if achievement.get('proportionalTo') and earned + EarnedAchievement.createForAchievement(achievement, trigger, null, earned, (earnedAchievementDoc) => @sendCreated(res, (earnedAchievementDoc or earned)?.toObject()) ) else if earned @@ -223,13 +224,15 @@ class EarnedAchievementHandler extends Handler notified: achievement._id in alreadyEarnedIDs if isRepeatable - earned.achievedAmount = something.get(achievement.get 'proportionalTo') + earned.achievedAmount = util.getByPath(something.toObject(), achievement.get 'proportionalTo') or 0 earned.previouslyAchievedAmount = 0 expFunction = achievement.getExpFunction() newPoints = expFunction(earned.achievedAmount) * achievement.get('worth') ? 10 + newGems = expFunction(earned.achievedAmount) * (achievement.get('rewards')?.gems ? 0) else newPoints = achievement.get('worth') ? 10 + newGems = achievement.get('rewards')?.gems ? 0 earned.earnedPoints = newPoints newTotalPoints += newPoints @@ -237,7 +240,10 @@ class EarnedAchievementHandler extends Handler earned.earnedRewards = achievement.get('rewards') for rewardType in ['heroes', 'items', 'levels'] newTotalRewards[rewardType] = newTotalRewards[rewardType].concat(achievement.get('rewards')?[rewardType] ? []) - newTotalRewards.gems += achievement.get('rewards')?.gems ? 0 + if isRepeatable and earned.earnedRewards + earned.earnedRewards = _.clone earned.earnedRewards + earned.earnedRewards.gems = newGems + newTotalRewards.gems += newGems EarnedAchievement.update {achievement:earned.achievement, user:earned.user}, earned, {upsert: true}, (err) -> doneWithAchievement err diff --git a/test/server/functional/achievement.spec.coffee b/test/server/functional/achievement.spec.coffee index cc19553f6..23711330c 100644 --- a/test/server/functional/achievement.spec.coffee +++ b/test/server/functional/achievement.spec.coffee @@ -258,8 +258,8 @@ describe 'Recalculate Achievements', -> unittest.getNormalJoe (joe) -> User.findById joe.get('id'), (err, guy) -> expect(err).toBeNull() - # TODO: fix this to properly handle recalculating proportionalTo recalculation - expect(guy.get 'points').toBe unlockable.worth + 2 * repeatable.worth + (Math.log(.5 * (4 + .5)) + 1) * diminishing.worth + expect(guy.get 'points').toBe unlockable.worth + 4 * repeatable.worth + (Math.log(.5 * (4 + .5)) + 1) * diminishing.worth + expect(guy.get('earned').gems).toBe 4 * repeatable.rewards.gems done() it 'cleaning up test: deleting all Achievements and related', (done) ->