diff --git a/common/locales/en/generic.json b/common/locales/en/generic.json
index 8b097dcb3f..1ea2f1da5a 100644
--- a/common/locales/en/generic.json
+++ b/common/locales/en/generic.json
@@ -69,8 +69,9 @@
"habiticaDayPluralText": "Celebrated <%= number %> Naming Days! Thanks for being a fantastic user.",
"achievementDilatory": "Savior of Dilatory",
"achievementDilatoryText": "Helped defeat the Dread Drag'on of Dilatory during the 2014 Summer Splash Event!",
- "costumeContest": "2014 Costume Contest",
- "costumeContestText": "Participated in the 2014 Halloween Costume Contest. See some of the entries at blog.habitica.com/tagged/cosplay!",
+ "costumeContest": "Costume Contest",
+ "costumeContestText": "Participated in the Habitoween Costume Contest. See some of the entries on the Habitica blog!",
+ "costumeContestPluralText": "Participated in <%= number %> Habitoween Costume Contests. See some of the entries on the Habitica blog!",
"memberSince": "- Member since",
"lastLoggedIn": "- Last logged in",
"notPorted": "This feature is not yet ported from the original site.",
diff --git a/migrations/20151116_costume_contest.js b/migrations/20151116_costume_contest_award.js
similarity index 95%
rename from migrations/20151116_costume_contest.js
rename to migrations/20151116_costume_contest_award.js
index a74a9c28a7..25891f9215 100644
--- a/migrations/20151116_costume_contest.js
+++ b/migrations/20151116_costume_contest_award.js
@@ -73,9 +73,11 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
count++;
// specify user data to change:
- var set = {'migration':migrationName, 'achievements.costumeContest':true};
+ var set = {'migration':migrationName};
+ var inc = {'achievements.costumeContests':1};
dbUsers.update({_id:user._id}, {$set:set});
+ dbUsers.update({_id:user._id}, {$inc:inc});
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
diff --git a/migrations/20151116_costume_contest_to_number.js b/migrations/20151116_costume_contest_to_number.js
new file mode 100644
index 0000000000..7121e9bc31
--- /dev/null
+++ b/migrations/20151116_costume_contest_to_number.js
@@ -0,0 +1,64 @@
+var migrationName = '20151116_costume_contest_to_number.js';
+var authorName = 'Sabe'; // in case script author needs to know when their ...
+var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
+
+/*
+ * Change Costume Contest achievement from Boolean to Number, so people can win repeatedly
+ */
+
+var dbserver = 'localhost:27017'; // FOR TEST DATABASE
+// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379'; // FOR PRODUCTION DATABASE
+var dbname = 'habitrpg';
+
+var mongo = require('mongoskin');
+var _ = require('lodash');
+
+var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
+
+// specify a query to limit the affected users (empty for all users):
+var query = {
+ 'achievements.costumeContest':true
+};
+
+// specify fields we are interested in to limit retrieved data (empty if we're not reading data):
+var fields = {
+ 'achievements.costumeContest':1
+};
+
+console.warn('Updating users...');
+var progressCount = 1000;
+var count = 0;
+dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
+ if (err) { return exiting(1, 'ERROR! ' + err); }
+ if (!user) {
+ console.warn('All appropriate users found and modified.');
+ return displayData();
+ }
+ count++;
+
+ // specify user data to change:
+ var set = {'achievements.costumeContests':1};
+
+ dbUsers.update({_id:user._id}, {$set:set});
+
+ if (count%progressCount == 0) console.warn(count + ' ' + user._id);
+ if (user._id == authorUuid) console.warn(authorName + ' processed');
+});
+
+
+function displayData() {
+ console.warn('\n' + count + ' users processed\n');
+ return exiting(0);
+}
+
+
+function exiting(code, msg) {
+ code = code || 0; // 0 = success
+ if (code && !msg) { msg = 'ERROR!'; }
+ if (msg) {
+ if (code) { console.error(msg); }
+ else { console.log( msg); }
+ }
+ process.exit(code);
+}
+
diff --git a/website/src/models/user.js b/website/src/models/user.js
index 323fd50d34..dd8ebe67ce 100644
--- a/website/src/models/user.js
+++ b/website/src/models/user.js
@@ -53,11 +53,12 @@ var UserSchema = new Schema({
perfect: Number,
habitBirthdays: Number,
valentine: Number,
- costumeContest: Boolean,
+ costumeContest: Boolean, // Superseded by costumeContests
nye: Number,
habiticaDays: Number,
greeting: Number,
- thankyou: Number
+ thankyou: Number,
+ costumeContests: Number
},
auth: {
blocked: Boolean,
diff --git a/website/views/shared/profiles/achievements.jade b/website/views/shared/profiles/achievements.jade
index 8504eaf754..8820d3f33f 100644
--- a/website/views/shared/profiles/achievements.jade
+++ b/website/views/shared/profiles/achievements.jade
@@ -229,11 +229,13 @@ div(ng-if='::profile.achievements.quests.burnout')
=env.t('achievementBurnoutText')
hr
-div(ng-if='::profile.achievements.costumeContest')
+div(ng-if='::profile.achievements.costumeContests')
.achievement.achievement-costumeContest
h5=env.t('costumeContest')
- small
- =env.t('costumeContestText')
+ small(ng-if='::profile.achievements.costumeContests === 1')
+ !=env.t('costumeContestText')
+ small(ng-if='::profile.achievements.costumeContests > 1')
+ !=env.t('costumeContestPluralText', {number: "{{::profile.achievements.costumeContests}}"})
hr
each card in ['greeting', 'thankyou', 'nye', 'valentine']