From 87f51913d09d6f5b5bace01bad6db6df10166c57 Mon Sep 17 00:00:00 2001 From: Alice Harris Date: Wed, 10 Sep 2014 14:06:01 +1000 Subject: [PATCH] prevent off-class items and free items being lost on death --- dist/habitrpg-shared.js | 1166 ++++++--------------------------------- script/index.coffee | 19 +- 2 files changed, 184 insertions(+), 1001 deletions(-) diff --git a/dist/habitrpg-shared.js b/dist/habitrpg-shared.js index 28cc073d5c..06e50d985b 100644 --- a/dist/habitrpg-shared.js +++ b/dist/habitrpg-shared.js @@ -6855,7 +6855,7 @@ process.chdir = function (dir) { },{}],4:[function(require,module,exports){ (function (global){ //! moment.js -//! version : 2.8.4 +//! version : 2.8.3 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com @@ -6866,7 +6866,7 @@ process.chdir = function (dir) { ************************************/ var moment, - VERSION = '2.8.4', + VERSION = '2.8.3', // the global-scope this is NOT the global object in Node.js globalScope = typeof global !== 'undefined' ? global : this, oldGlobalMoment, @@ -6889,7 +6889,7 @@ process.chdir = function (dir) { momentProperties = [], // check for nodeJS - hasModule = (typeof module !== 'undefined' && module && module.exports), + hasModule = (typeof module !== 'undefined' && module.exports), // ASP.NET json date format regex aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, @@ -6900,8 +6900,8 @@ process.chdir = function (dir) { isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, // format tokens - formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g, - localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, + formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, + localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, // parsing token regexes parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 @@ -6912,8 +6912,8 @@ process.chdir = function (dir) { parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z parseTokenT = /T/i, // T (ISO separator) - parseTokenOffsetMs = /[\+\-]?\d+/, // 1234567890123 parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 + parseTokenOrdinal = /\d{1,2}/, //strict parsing regexes parseTokenOneDigit = /\d/, // 0 - 9 @@ -7128,9 +7128,6 @@ process.chdir = function (dir) { zz : function () { return this.zoneName(); }, - x : function () { - return this.valueOf(); - }, X : function () { return this.unix(); }, @@ -7557,10 +7554,7 @@ process.chdir = function (dir) { overflow = m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : - m._a[HOUR] < 0 || m._a[HOUR] > 24 || - (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 || - m._a[SECOND] !== 0 || - m._a[MILLISECOND] !== 0)) ? HOUR : + m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : @@ -7587,8 +7581,7 @@ process.chdir = function (dir) { if (m._strict) { m._isValid = m._isValid && m._pf.charsLeftOver === 0 && - m._pf.unusedTokens.length === 0 && - m._pf.bigHour === undefined; + m._pf.unusedTokens.length === 0; } } return m._isValid; @@ -7640,18 +7633,8 @@ process.chdir = function (dir) { // Return a moment from input, that is local/utc/zone equivalent to model. function makeAs(input, model) { - var res, diff; - if (model._isUTC) { - res = model.clone(); - diff = (moment.isMoment(input) || isDate(input) ? - +input : +moment(input)) - (+res); - // Use low-level api, because this fn is low-level api. - res._d.setTime(+res._d + diff); - moment.updateOffset(res, false); - return res; - } else { - return moment(input).local(); - } + return model._isUTC ? moment(input).zone(model._offset || 0) : + moment(input).local(); } /************************************ @@ -7671,9 +7654,6 @@ process.chdir = function (dir) { this['_' + i] = prop; } } - // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _ordinalParseLenient. - this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source); }, _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), @@ -7686,32 +7666,22 @@ process.chdir = function (dir) { return this._monthsShort[m.month()]; }, - monthsParse : function (monthName, format, strict) { + monthsParse : function (monthName) { var i, mom, regex; if (!this._monthsParse) { this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; } for (i = 0; i < 12; i++) { // make the regex if we don't have it already - mom = moment.utc([2000, i]); - if (strict && !this._longMonthsParse[i]) { - this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); - this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); - } - if (!strict && !this._monthsParse[i]) { + if (!this._monthsParse[i]) { + mom = moment.utc([2000, i]); regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); } // test the regex - if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { - return i; - } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { - return i; - } else if (!strict && this._monthsParse[i].test(monthName)) { + if (this._monthsParse[i].test(monthName)) { return i; } } @@ -7754,7 +7724,6 @@ process.chdir = function (dir) { }, _longDateFormat : { - LTS : 'h:mm:ss A', LT : 'h:mm A', L : 'MM/DD/YYYY', LL : 'MMMM D, YYYY', @@ -7795,9 +7764,9 @@ process.chdir = function (dir) { lastWeek : '[Last] dddd [at] LT', sameElse : 'L' }, - calendar : function (key, mom, now) { + calendar : function (key, mom) { var output = this._calendar[key]; - return typeof output === 'function' ? output.apply(mom, [now]) : output; + return typeof output === 'function' ? output.apply(mom) : output; }, _relativeTime : { @@ -7832,7 +7801,6 @@ process.chdir = function (dir) { return this._ordinal.replace('%d', number); }, _ordinal : '%d', - _ordinalParse : /\d{1,2}/, preparse : function (string) { return string; @@ -7974,8 +7942,6 @@ process.chdir = function (dir) { case 'a': case 'A': return config._locale._meridiemParse; - case 'x': - return parseTokenOffsetMs; case 'X': return parseTokenTimestampMs; case 'Z': @@ -8010,7 +7976,7 @@ process.chdir = function (dir) { case 'E': return parseTokenOneOrTwoDigits; case 'Do': - return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient; + return parseTokenOrdinal; default : a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i')); return a; @@ -8047,7 +8013,7 @@ process.chdir = function (dir) { break; case 'MMM' : // fall through to MMMM case 'MMMM' : - a = config._locale.monthsParse(input, token, config._strict); + a = config._locale.monthsParse(input); // if we didn't find a month name, mark the date as invalid. if (a != null) { datePartArray[MONTH] = a; @@ -8064,8 +8030,7 @@ process.chdir = function (dir) { break; case 'Do' : if (input != null) { - datePartArray[DATE] = toInt(parseInt( - input.match(/\d{1,2}/)[0], 10)); + datePartArray[DATE] = toInt(parseInt(input, 10)); } break; // DAY OF YEAR @@ -8090,13 +8055,11 @@ process.chdir = function (dir) { case 'A' : config._isPm = config._locale.isPM(input); break; - // HOUR + // 24 HOUR + case 'H' : // fall through to hh + case 'HH' : // fall through to hh case 'h' : // fall through to hh case 'hh' : - config._pf.bigHour = true; - /* falls through */ - case 'H' : // fall through to HH - case 'HH' : datePartArray[HOUR] = toInt(input); break; // MINUTE @@ -8116,10 +8079,6 @@ process.chdir = function (dir) { case 'SSSS' : datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); break; - // UNIX OFFSET (MILLISECONDS) - case 'x': - config._d = new Date(toInt(input)); - break; // UNIX TIMESTAMP WITH MS case 'X': config._d = new Date(parseFloat(input) * 1000); @@ -8256,25 +8215,12 @@ process.chdir = function (dir) { config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } - // Check for 24:00:00.000 - if (config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0) { - config._nextDay = true; - config._a[HOUR] = 0; - } - config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); // Apply timezone offset from input. The actual zone can be changed // with parseZone. if (config._tzm != null) { config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); } - - if (config._nextDay) { - config._a[HOUR] = 24; - } } function dateFromObject(config) { @@ -8288,7 +8234,7 @@ process.chdir = function (dir) { config._a = [ normalizedInput.year, normalizedInput.month, - normalizedInput.day || normalizedInput.date, + normalizedInput.day, normalizedInput.hour, normalizedInput.minute, normalizedInput.second, @@ -8361,10 +8307,6 @@ process.chdir = function (dir) { config._pf.unusedInput.push(string); } - // clear _12h flag if hour is <= 12 - if (config._pf.bigHour === true && config._a[HOUR] <= 12) { - config._pf.bigHour = undefined; - } // handle am pm if (config._isPm && config._a[HOUR] < 12) { config._a[HOUR] += 12; @@ -8373,6 +8315,7 @@ process.chdir = function (dir) { if (config._isPm === false && config._a[HOUR] === 12) { config._a[HOUR] = 0; } + dateFromConfig(config); checkOverflow(config); } @@ -8632,8 +8575,7 @@ process.chdir = function (dir) { function makeMoment(config) { var input = config._i, - format = config._f, - res; + format = config._f; config._locale = config._locale || moment.localeData(config._l); @@ -8657,14 +8599,7 @@ process.chdir = function (dir) { makeDateFromInput(config); } - res = new Moment(config); - if (res._nextDay) { - // Adding is smart enough around DST - res.add(1, 'd'); - res._nextDay = undefined; - } - - return res; + return new Moment(config); } moment = function (input, format, locale, strict) { @@ -8696,7 +8631,7 @@ process.chdir = function (dir) { 'release. Please refer to ' + 'https://github.com/moment/moment/issues/1407 for more info.', function (config) { - config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + config._d = new Date(config._i); } ); @@ -9008,12 +8943,7 @@ process.chdir = function (dir) { toISOString : function () { var m = moment(this).utc(); if (0 < m.year() && m.year() <= 9999) { - if ('function' === typeof Date.prototype.toISOString) { - // native implementation is ~50x faster, use it when we can - return this.toDate().toISOString(); - } else { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); } else { return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); } @@ -9132,7 +9062,7 @@ process.chdir = function (dir) { diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(this.localeData().calendar(format, this, moment(now))); + return this.format(this.localeData().calendar(format, this)); }, isLeapYear : function () { @@ -9201,45 +9131,36 @@ process.chdir = function (dir) { endOf: function (units) { units = normalizeUnits(units); - if (units === undefined || units === 'millisecond') { - return this; - } return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); }, isAfter: function (input, units) { - var inputMs; units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); if (units === 'millisecond') { input = moment.isMoment(input) ? input : moment(input); return +this > +input; } else { - inputMs = moment.isMoment(input) ? +input : +moment(input); - return inputMs < +this.clone().startOf(units); + return +this.clone().startOf(units) > +moment(input).startOf(units); } }, isBefore: function (input, units) { - var inputMs; units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); if (units === 'millisecond') { input = moment.isMoment(input) ? input : moment(input); return +this < +input; } else { - inputMs = moment.isMoment(input) ? +input : +moment(input); - return +this.clone().endOf(units) < inputMs; + return +this.clone().startOf(units) < +moment(input).startOf(units); } }, isSame: function (input, units) { - var inputMs; units = normalizeUnits(units || 'millisecond'); if (units === 'millisecond') { input = moment.isMoment(input) ? input : moment(input); return +this === +input; } else { - inputMs = +moment(input); - return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units)); + return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); } }, @@ -9416,7 +9337,7 @@ process.chdir = function (dir) { }, lang : deprecate( - 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + 'moment().lang() is deprecated. Use moment().localeData() instead.', function (key) { if (key === undefined) { return this.localeData(); @@ -9637,7 +9558,7 @@ process.chdir = function (dir) { return units === 'month' ? months : months / 12; } else { // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + Math.round(yearsToDays(this._months / 12)); + days = this._days + yearsToDays(this._months / 12); switch (units) { case 'week': return days / 7 + this._milliseconds / 6048e5; case 'day': return days + this._milliseconds / 864e5; @@ -9739,7 +9660,6 @@ process.chdir = function (dir) { // Set default locale, other locale will inherit from English. moment.locale('en', { - ordinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal : function (number) { var b = number % 10, output = (toInt(number % 100 / 10) === 1) ? 'th' : @@ -9793,7 +9713,7 @@ process.chdir = function (dir) { }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],5:[function(require,module,exports){ -var api, classes, diminishingReturns, events, gear, gearTypes, i18n, moment, repeat, t, _; +var api, classes, diminishingReturns, events, gear, gearTypes, i18n, moment, mystery, repeat, t, _; _ = require('lodash'); @@ -9827,7 +9747,7 @@ t = function(string, vars) { classes = ['warrior', 'rogue', 'healer', 'wizard']; -gearTypes = ['weapon', 'armor', 'head', 'shield', 'body', 'back', 'headAccessory', 'eyewear']; +gearTypes = ['weapon', 'armor', 'head', 'shield', 'body', 'back', 'headAccessory']; events = { winter: { @@ -9853,78 +9773,45 @@ events = { fall: { start: '2014-09-21', end: '2014-11-01' - }, - winter2015: { - start: '2014-12-21', - end: '2015-01-31' } }; -api.mystery = { +mystery = { 201402: { start: '2014-02-22', - end: '2014-02-28', - text: 'Winged Messenger Set' + end: '2014-02-28' }, 201403: { start: '2014-03-24', - end: '2014-04-02', - text: 'Forest Walker Set' + end: '2014-04-01' }, 201404: { start: '2014-04-24', - end: '2014-05-02', - text: 'Twilight Butterfly Set' + end: '2014-05-01' }, 201405: { start: '2014-05-21', - end: '2014-06-02', - text: 'Flame Wielder Set' + end: '2014-06-01' }, 201406: { start: '2014-06-23', - end: '2014-07-02', - text: 'Octomage Set' + end: '2014-07-01' }, 201407: { start: '2014-07-23', - end: '2014-08-02', - text: 'Undersea Explorer Set' + end: '2014-08-01' }, 201408: { start: '2014-08-23', - end: '2014-09-02', - text: 'Sun Sorcerer Set' + end: '2014-09-01' }, 201409: { start: '2014-09-24', - end: '2014-10-02', - text: 'Autumn Strider Item Set' + end: '2014-10-01' }, 201410: { start: '2014-10-24', - end: '2014-11-02', - text: 'Winged Goblin Set' - }, - 201411: { - start: '2014-11-24', - end: '2014-12-02', - text: 'Feast and Fun Set' - }, - 201412: { - start: '2014-12-25', - end: '2015-01-02', - text: 'Penguin Set' - }, - 301404: { - start: '3014-03-24', - end: '3014-04-02', - text: 'Steampunk Standard Set' - }, - 301405: { - start: '3014-04-24', - end: '3014-05-02', - text: 'Steampunk Accessories Set' + end: '2014-11-01' }, wondercon: { start: '2014-03-24', @@ -9932,10 +9819,6 @@ api.mystery = { } }; -_.each(api.mystery, function(v, k) { - return v.key = k; -}); - gear = { weapon: { base: { @@ -10241,7 +10124,7 @@ gear = { value: 200, canOwn: (function(u) { var _ref; - return (+((_ref = u.backer) != null ? _ref.tier : void 0) >= 300) || (u.items.gear.owned.weapon_special_3 != null); + return +((_ref = u.backer) != null ? _ref.tier : void 0) >= 300; }) }, critical: { @@ -10428,63 +10311,6 @@ gear = { }), value: 90, int: 9 - }, - winter2015Rogue: { - event: events.winter2015, - specialClass: 'rogue', - text: t('weaponSpecialWinter2015RogueText'), - notes: t('weaponSpecialWinter2015RogueNotes', { - str: 8 - }), - value: 80, - str: 8 - }, - winter2015Warrior: { - event: events.winter2015, - specialClass: 'warrior', - text: t('weaponSpecialWinter2015WarriorText'), - notes: t('weaponSpecialWinter2015WarriorNotes', { - str: 15 - }), - value: 90, - str: 15 - }, - winter2015Mage: { - event: events.winter2015, - specialClass: 'wizard', - twoHanded: true, - text: t('weaponSpecialWinter2015MageText'), - notes: t('weaponSpecialWinter2015MageNotes', { - int: 15, - per: 7 - }), - value: 160, - int: 15, - per: 7 - }, - winter2015Healer: { - event: events.winter2015, - specialClass: 'healer', - text: t('weaponSpecialWinter2015HealerText'), - notes: t('weaponSpecialWinter2015HealerNotes', { - int: 9 - }), - value: 90, - int: 9 - } - }, - mystery: { - 201411: { - text: t('weaponMystery201411Text'), - notes: t('weaponMystery201411Notes'), - mystery: '201411', - value: 0 - }, - 301404: { - text: t('weaponMystery301404Text'), - notes: t('weaponMystery301404Notes'), - mystery: '301404', - value: 0 } } }, @@ -10875,46 +10701,6 @@ gear = { value: 90, con: 15 }, - winter2015Rogue: { - event: events.winter2015, - specialClass: 'rogue', - text: t('armorSpecialWinter2015RogueText'), - notes: t('armorSpecialWinter2015RogueNotes', { - per: 15 - }), - value: 90, - per: 15 - }, - winter2015Warrior: { - event: events.winter2015, - specialClass: 'warrior', - text: t('armorSpecialWinter2015WarriorText'), - notes: t('armorSpecialWinter2015WarriorNotes', { - con: 9 - }), - value: 90, - con: 9 - }, - winter2015Mage: { - event: events.winter2015, - specialClass: 'wizard', - text: t('armorSpecialWinter2015MageText'), - notes: t('armorSpecialWinter2015MageNotes', { - int: 9 - }), - value: 90, - int: 9 - }, - winter2015Healer: { - event: events.winter2015, - specialClass: 'healer', - text: t('armorSpecialWinter2015HealerText'), - notes: t('armorSpecialWinter2015HealerNotes', { - con: 15 - }), - value: 90, - con: 15 - }, gaymerx: { event: events.gaymerx, text: t('armorSpecialGaymerxText'), @@ -10926,61 +10712,49 @@ gear = { 201402: { text: t('armorMystery201402Text'), notes: t('armorMystery201402Notes'), - mystery: '201402', + mystery: mystery['201402'], value: 0 }, 201403: { text: t('armorMystery201403Text'), notes: t('armorMystery201403Notes'), - mystery: '201403', + mystery: mystery['201403'], value: 0 }, 201405: { text: t('armorMystery201405Text'), notes: t('armorMystery201405Notes'), - mystery: '201405', + mystery: mystery['201405'], value: 0 }, 201406: { text: t('armorMystery201406Text'), notes: t('armorMystery201406Notes'), - mystery: '201406', + mystery: mystery['201406'], value: 0 }, 201407: { text: t('armorMystery201407Text'), notes: t('armorMystery201407Notes'), - mystery: '201407', + mystery: mystery['201407'], value: 0 }, 201408: { text: t('armorMystery201408Text'), notes: t('armorMystery201408Notes'), - mystery: '201408', + mystery: mystery['201408'], value: 0 }, 201409: { text: t('armorMystery201409Text'), notes: t('armorMystery201409Notes'), - mystery: '201409', + mystery: mystery['201409'], value: 0 }, 201410: { text: t('armorMystery201410Text'), notes: t('armorMystery201410Notes'), - mystery: '201410', - value: 0 - }, - 201412: { - text: t('armorMystery201412Text'), - notes: t('armorMystery201412Notes'), - mystery: '201412', - value: 0 - }, - 301404: { - text: t('armorMystery301404Text'), - notes: t('armorMystery301404Notes'), - mystery: '301404', + mystery: mystery['201410'], value: 0 } } @@ -11372,46 +11146,6 @@ gear = { value: 60, int: 7 }, - winter2015Rogue: { - event: events.winter2015, - specialClass: 'rogue', - text: t('headSpecialWinter2015RogueText'), - notes: t('headSpecialWinter2015RogueNotes', { - per: 9 - }), - value: 60, - per: 9 - }, - winter2015Warrior: { - event: events.winter2015, - specialClass: 'warrior', - text: t('headSpecialWinter2015WarriorText'), - notes: t('headSpecialWinter2015WarriorNotes', { - str: 9 - }), - value: 60, - str: 9 - }, - winter2015Mage: { - event: events.winter2015, - specialClass: 'wizard', - text: t('headSpecialWinter2015MageText'), - notes: t('headSpecialWinter2015MageNotes', { - per: 7 - }), - value: 60, - per: 7 - }, - winter2015Healer: { - event: events.winter2015, - specialClass: 'healer', - text: t('headSpecialWinter2015HealerText'), - notes: t('headSpecialWinter2015HealerNotes', { - int: 7 - }), - value: 60, - int: 7 - }, gaymerx: { event: events.gaymerx, text: t('headSpecialGaymerxText'), @@ -11423,55 +11157,31 @@ gear = { 201402: { text: t('headMystery201402Text'), notes: t('headMystery201402Notes'), - mystery: '201402', + mystery: mystery['201402'], value: 0 }, 201405: { text: t('headMystery201405Text'), notes: t('headMystery201405Notes'), - mystery: '201405', + mystery: mystery['201405'], value: 0 }, 201406: { text: t('headMystery201406Text'), notes: t('headMystery201406Notes'), - mystery: '201406', + mystery: mystery['201406'], value: 0 }, 201407: { text: t('headMystery201407Text'), notes: t('headMystery201407Notes'), - mystery: '201407', + mystery: mystery['201407'], value: 0 }, 201408: { text: t('headMystery201408Text'), notes: t('headMystery201408Notes'), - mystery: '201408', - value: 0 - }, - 201411: { - text: t('headMystery201411Text'), - notes: t('headMystery201411Notes'), - mystery: '201411', - value: 0 - }, - 201412: { - text: t('headMystery201412Text'), - notes: t('headMystery201412Notes'), - mystery: '201412', - value: 0 - }, - 301404: { - text: t('headMystery301404Text'), - notes: t('headMystery301404Notes'), - mystery: '301404', - value: 0 - }, - 301405: { - text: t('headMystery301405Text'), - notes: t('headMystery301405Notes'), - mystery: '301405', + mystery: mystery['201408'], value: 0 } } @@ -11656,18 +11366,6 @@ gear = { return +((_ref = u.contributor) != null ? _ref.level : void 0) >= 5; }) }, - goldenknight: { - text: t('shieldSpecialGoldenknightText'), - notes: t('shieldSpecialGoldenknightNotes', { - attrs: 25 - }), - con: 25, - per: 25, - value: 200, - canOwn: (function(u) { - return u.items.gear.owned.shield_special_goldenknight != null; - }) - }, yeti: { event: events.winter, specialClass: 'warrior', @@ -11787,44 +11485,6 @@ gear = { }), value: 70, con: 9 - }, - winter2015Rogue: { - event: events.winter2015, - specialClass: 'rogue', - text: t('shieldSpecialWinter2015RogueText'), - notes: t('shieldSpecialWinter2015RogueNotes', { - str: 8 - }), - value: 80, - str: 8 - }, - winter2015Warrior: { - event: events.winter2015, - specialClass: 'warrior', - text: t('shieldSpecialWinter2015WarriorText'), - notes: t('shieldSpecialWinter2015WarriorNotes', { - con: 7 - }), - value: 70, - con: 7 - }, - winter2015Healer: { - event: events.winter2015, - specialClass: 'healer', - text: t('shieldSpecialWinter2015HealerText'), - notes: t('shieldSpecialWinter2015HealerNotes', { - con: 9 - }), - value: 70, - con: 9 - } - }, - mystery: { - 301405: { - text: t('shieldMystery301405Text'), - notes: t('shieldMystery301405Notes'), - mystery: '301405', - value: 0 } } }, @@ -11840,19 +11500,19 @@ gear = { 201402: { text: t('backMystery201402Text'), notes: t('backMystery201402Notes'), - mystery: '201402', + mystery: mystery['201402'], value: 0 }, 201404: { text: t('backMystery201404Text'), notes: t('backMystery201404Notes'), - mystery: '201404', + mystery: mystery['201404'], value: 0 }, 201410: { text: t('backMystery201410Text'), notes: t('backMystery201410Notes'), - mystery: '201410', + mystery: mystery['201410'], value: 0 } }, @@ -11861,13 +11521,13 @@ gear = { text: t('backSpecialWonderconRedText'), notes: t('backSpecialWonderconRedNotes'), value: 0, - mystery: 'wondercon' + mystery: mystery.wondercon }, wondercon_black: { text: t('backSpecialWonderconBlackText'), notes: t('backSpecialWonderconBlackNotes'), value: 0, - mystery: 'wondercon' + mystery: mystery.wondercon } } }, @@ -11884,19 +11544,19 @@ gear = { text: t('bodySpecialWonderconRedText'), notes: t('bodySpecialWonderconRedNotes'), value: 0, - mystery: 'wondercon' + mystery: mystery.wondercon }, wondercon_gold: { text: t('bodySpecialWonderconGoldText'), notes: t('bodySpecialWonderconGoldNotes'), value: 0, - mystery: 'wondercon' + mystery: mystery.wondercon }, wondercon_black: { text: t('bodySpecialWonderconBlackText'), notes: t('bodySpecialWonderconBlackNotes'), value: 0, - mystery: 'wondercon' + mystery: mystery.wondercon }, summerHealer: { event: events.summer, @@ -11951,83 +11611,51 @@ gear = { text: t('headAccessorySpecialSpringHealerText'), notes: t('headAccessorySpecialSpringHealerNotes'), value: 20 + }, + wondercon_red: { + text: t('headAccessorySpecialWonderconRedText'), + notes: t('headAccessorySpecialWonderconRedNotes'), + value: 0, + mystery: mystery.wondercon + }, + wondercon_black: { + text: t('headAccessorySpecialWonderconBlackText'), + notes: t('headAccessorySpecialWonderconBlackNotes'), + value: 0, + mystery: mystery.wondercon + }, + summerRogue: { + event: events.summer, + specialClass: 'rogue', + text: t('headAccessorySpecialSummerRogueText'), + notes: t('headAccessorySpecialSummerRogueNotes'), + value: 20 + }, + summerWarrior: { + event: events.summer, + specialClass: 'warrior', + text: t('headAccessorySpecialSummerWarriorText'), + notes: t('headAccessorySpecialSummerWarriorNotes'), + value: 20 } }, mystery: { 201403: { text: t('headAccessoryMystery201403Text'), notes: t('headAccessoryMystery201403Notes'), - mystery: '201403', + mystery: mystery['201403'], value: 0 }, 201404: { text: t('headAccessoryMystery201404Text'), notes: t('headAccessoryMystery201404Notes'), - mystery: '201404', + mystery: mystery['201404'], value: 0 }, 201409: { text: t('headAccessoryMystery201409Text'), notes: t('headAccessoryMystery201409Notes'), - mystery: '201409', - value: 0 - }, - 301405: { - text: t('headAccessoryMystery301405Text'), - notes: t('headAccessoryMystery301405Notes'), - mystery: '301405', - value: 0 - } - } - }, - eyewear: { - base: { - 0: { - text: t('eyewearBase0Text'), - notes: t('eyewearBase0Notes'), - value: 0, - last: true - } - }, - special: { - wondercon_red: { - text: t('eyewearSpecialWonderconRedText'), - notes: t('eyewearSpecialWonderconRedNotes'), - value: 0, - mystery: 'wondercon' - }, - wondercon_black: { - text: t('eyewearSpecialWonderconBlackText'), - notes: t('eyewearSpecialWonderconBlackNotes'), - value: 0, - mystery: 'wondercon' - }, - summerRogue: { - event: events.summer, - specialClass: 'rogue', - text: t('eyewearSpecialSummerRogueText'), - notes: t('eyewearSpecialSummerRogueNotes'), - value: 20 - }, - summerWarrior: { - event: events.summer, - specialClass: 'warrior', - text: t('eyewearSpecialSummerWarriorText'), - notes: t('eyewearSpecialSummerWarriorNotes'), - value: 20 - } - }, - mystery: { - 301404: { - text: t('eyewearMystery301404Text'), - notes: t('eyewearMystery301404Notes'), - mystery: '301404', - value: 0 - }, - 301405: { - text: t('eyewearMystery301405Text'), - notes: t('eyewearMystery301405Notes'), - mystery: '301405', + mystery: mystery['201409'], value: 0 } } @@ -12079,29 +11707,6 @@ _.each(gearTypes, function(type) { }); -/* - Time Traveler Store, mystery sets need their items mapped in - */ - -_.each(api.mystery, function(v, k) { - return v.items = _.where(api.gear.flat, { - mystery: k - }); -}); - -api.timeTravelerStore = function(owned) { - var ownedKeys; - ownedKeys = _.keys((typeof owned.toObject === "function" ? owned.toObject() : void 0) || owned); - return _.reduce(api.mystery, function(m, v, k) { - if (k === 'wondercon' || ~ownedKeys.indexOf(v.items[0].key)) { - return m; - } - m[k] = v; - return m; - }, {}); -}; - - /* --------------------------------------------------------------- Potion @@ -12593,16 +12198,6 @@ api.questEggs = { text: t('questEggSpiderText'), adjective: t('questEggSpiderAdjective'), canBuy: false - }, - Owl: { - text: t('questEggOwlText'), - adjective: t('questEggOwlAdjective'), - canBuy: false - }, - Penguin: { - text: t('questEggPenguinText'), - adjective: t('questEggPenguinAdjective'), - canBuy: false } }; @@ -12634,8 +12229,7 @@ api.specialPets = { api.specialMounts = { 'BearCub-Polar': 'polarBear', 'LionCub-Ethereal': 'etherealLion', - 'MantisShrimp-Base': 'mantisShrimp', - 'Turkey-Base': 'turkey' + 'MantisShrimp-Base': 'mantisShrimp' }; api.hatchingPotions = { @@ -12706,70 +12300,70 @@ api.questPets = _.transform(api.questEggs, function(m, egg) { api.food = { Meat: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodMeat'), target: 'Base', article: '' }, Milk: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodMilk'), target: 'White', article: '' }, Potatoe: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodPotatoe'), target: 'Desert', article: 'a ' }, Strawberry: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodStrawberry'), target: 'Red', article: 'a ' }, Chocolate: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodChocolate'), target: 'Shade', article: '' }, Fish: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodFish'), target: 'Skeleton', article: 'a ' }, RottenMeat: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodRottenMeat'), target: 'Zombie', article: '' }, CottonCandyPink: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodCottonCandyPink'), target: 'CottonCandyPink', article: '' }, CottonCandyBlue: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodCottonCandyBlue'), target: 'CottonCandyBlue', article: '' }, Honey: { canBuy: true, - canDrop: true, + canDrop: false, text: t('foodHoney'), target: 'Golden', article: '' @@ -12852,71 +12446,71 @@ api.food = { article: '' }, Candy_Skeleton: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandySkeleton'), target: 'Skeleton', article: '' }, Candy_Base: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyBase'), target: 'Base', article: '' }, Candy_CottonCandyBlue: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyCottonCandyBlue'), target: 'CottonCandyBlue', article: '' }, Candy_CottonCandyPink: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyCottonCandyPink'), target: 'CottonCandyPink', article: '' }, Candy_Shade: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyShade'), target: 'Shade', article: '' }, Candy_White: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyWhite'), target: 'White', article: '' }, Candy_Golden: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyGolden'), target: 'Golden', article: '' }, Candy_Zombie: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyZombie'), target: 'Zombie', article: '' }, Candy_Desert: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyDesert'), target: 'Desert', article: '' }, Candy_Red: { - canBuy: false, - canDrop: false, + canBuy: true, + canDrop: true, text: t('foodCandyRed'), target: 'Red', article: '' @@ -13655,172 +13249,6 @@ api.quests = { gp: 900, exp: 1500 } - }, - goldenknight1: { - text: t('questGoldenknight1Text'), - notes: t('questGoldenknight1Notes'), - value: 4, - lvl: 40, - collect: { - testimony: { - text: t('questGoldenknight1CollectTestimony'), - count: 300 - } - }, - drop: { - items: [ - { - type: 'quests', - key: "goldenknight2", - text: t('questGoldenknight1DropGoldenknight2Quest') - } - ], - gp: 15, - exp: 120 - } - }, - goldenknight2: { - text: t('questGoldenknight2Text'), - notes: t('questGoldenknight2Notes'), - value: 4, - previous: 'goldenknight1', - lvl: 45, - boss: { - name: t('questGoldenknight2Boss'), - hp: 1000, - str: 3 - }, - drop: { - items: [ - { - type: 'quests', - key: 'goldenknight3', - text: t('questGoldenknight2DropGoldenknight3Quest') - } - ], - gp: 75, - exp: 750 - } - }, - goldenknight3: { - text: t('questGoldenknight3Text'), - notes: t('questGoldenknight3Notes'), - completion: t('questGoldenknight3Completion'), - previous: 'goldenknight2', - value: 4, - lvl: 50, - boss: { - name: t('questGoldenknight3Boss'), - hp: 1700, - str: 3.5 - }, - drop: { - items: [ - { - type: 'food', - key: 'Honey', - text: t('questGoldenknight3DropHoney') - }, { - type: 'food', - key: 'Honey', - text: t('questGoldenknight3DropHoney') - }, { - type: 'food', - key: 'Honey', - text: t('questGoldenknight3DropHoney') - }, { - type: 'hatchingPotions', - key: 'Golden', - text: t('questGoldenknight3DropGoldenPotion') - }, { - type: 'hatchingPotions', - key: 'Golden', - text: t('questGoldenknight3DropGoldenPotion') - }, { - type: 'gear', - key: 'shield_special_goldenknight', - text: t('questGoldenknight3DropWeapon') - } - ], - gp: 900, - exp: 1500 - } - }, - basilist: { - text: t('questBasilistText'), - notes: t('questBasilistNotes'), - completion: t('questBasilistCompletion'), - canBuy: false, - value: 4, - boss: { - name: t('questBasilistBoss'), - hp: 100, - str: 0.5 - }, - drop: { - gp: 8, - exp: 42 - } - }, - owl: { - text: t('questOwlText'), - notes: t('questOwlNotes'), - completion: t('questOwlCompletion'), - value: 4, - boss: { - name: t('questOwlBoss'), - hp: 500, - str: 1.5 - }, - drop: { - items: [ - { - type: 'eggs', - key: 'Owl', - text: t('questOwlDropOwlEgg') - }, { - type: 'eggs', - key: 'Owl', - text: t('questOwlDropOwlEgg') - }, { - type: 'eggs', - key: 'Owl', - text: t('questOwlDropOwlEgg') - } - ], - gp: 37, - exp: 275 - } - }, - penguin: { - text: t('questPenguinText'), - notes: t('questPenguinNotes'), - completion: t('questPenguinCompletion'), - value: 4, - boss: { - name: t('questPenguinBoss'), - hp: 400, - str: 1.5 - }, - drop: { - items: [ - { - type: 'eggs', - key: 'Penguin', - text: t('questPenguinDropPenguinEgg') - }, { - type: 'eggs', - key: 'Penguin', - text: t('questPenguinDropPenguinEgg') - }, { - type: 'eggs', - key: 'Penguin', - text: t('questPenguinDropPenguinEgg') - } - ], - gp: 31, - exp: 200 - } } }; @@ -13915,57 +13343,6 @@ api.backgrounds = { text: t('backgroundPumpkinPatchText'), notes: t('backgroundPumpkinPatchNotes') } - }, - backgrounds112014: { - harvest_feast: { - text: t('backgroundHarvestFeastText'), - notes: t('backgroundHarvestFeastNotes') - }, - sunset_meadow: { - text: t('backgroundSunsetMeadowText'), - notes: t('backgroundSunsetMeadowNotes') - }, - starry_skies: { - text: t('backgroundStarrySkiesText'), - notes: t('backgroundStarrySkiesNotes') - } - }, - backgrounds122014: { - iceberg: { - text: t('backgroundIcebergText'), - notes: t('backgroundIcebergNotes') - }, - twinkly_lights: { - text: t('backgroundTwinklyLightsText'), - notes: t('backgroundTwinklyLightsNotes') - }, - south_pole: { - text: t('backgroundSouthPoleText'), - notes: t('backgroundSouthPoleNotes') - } - } -}; - -api.subscriptionBlocks = { - "1": { - months: 1, - price: 5, - key: 'basic_earned' - }, - "3": { - months: 3, - price: 15, - key: 'basic_3mo' - }, - "6": { - months: 6, - price: 30, - key: 'basic_6mo' - }, - "12": { - months: 12, - price: 48, - key: 'basic_12mo' } }; @@ -14187,29 +13564,6 @@ api.dotGet = function(obj, path) { }; -/* - Reflists are arrays, but stored as objects. Mongoose has a helluvatime working with arrays (the main problem for our - syncing issues) - so the goal is to move away from arrays to objects, since mongoose can reference elements by ID - no problem. To maintain sorting, we use these helper functions: - */ - -api.refPush = function(reflist, item, prune) { - if (prune == null) { - prune = 0; - } - item.sort = _.isEmpty(reflist) ? 0 : _.max(reflist, 'sort').sort + 1; - if (!(item.id && !reflist[item.id])) { - item.id = api.uuid(); - } - return reflist[item.id] = item; -}; - -api.planGemLimits = { - convRate: 20, - convCap: 25 -}; - - /* ------------------------------------------------------ Time / Day @@ -14636,9 +13990,6 @@ api.taskClasses = function(task, filters, dayStart, lastCron, showCompleted, mai if (task.down && task.up) { classes += ' habit-wide'; } - if (!task.down && !task.up) { - classes += ' habit-narrow'; - } } if (value < -20) { classes += ' color-worst'; @@ -14796,13 +14147,7 @@ api.wrap = function(user, main) { return typeof cb === "function" ? cb(null, {}) : void 0; }, revive: function(req, cb) { - var item, lostItem, lostStat; - if (!(user.stats.hp <= 0)) { - return typeof cb === "function" ? cb({ - code: 400, - message: "Cannot revive if not dead" - }) : void 0; - } + var cl, item, lostItem, lostStat; _.merge(user.stats, { hp: 50, exp: 0, @@ -14820,9 +14165,16 @@ api.wrap = function(user, main) { if (lostStat) { user.stats[lostStat]--; } + cl = user.stats["class"]; lostItem = user.fns.randomVal(_.reduce(user.items.gear.owned, (function(m, v, k) { - if (v) { - m['' + k] = '' + k; + var itm; + if (v && k !== 'toObject') { + itm = content.gear.flat['' + k]; + if (itm) { + if (itm.value > 0 && (itm.klass === cl || (itm.klass === 'special' && (!itm.specialClass || itm.specialClass === cl)))) { + m['' + k] = '' + k; + } + } } return m; }), {})); @@ -15133,60 +14485,6 @@ api.wrap = function(user, main) { }); return typeof cb === "function" ? cb(null, user.tags) : void 0; }, - addWebhook: function(req, cb) { - var wh; - wh = user.preferences.webhooks; - api.refPush(wh, { - url: req.body.url, - enabled: req.body.enabled || true, - id: req.body.id - }); - if (typeof user.markModified === "function") { - user.markModified('preferences.webhooks'); - } - return typeof cb === "function" ? cb(null, user.preferences.webhooks) : void 0; - }, - updateWebhook: function(req, cb) { - _.merge(user.preferences.webhooks[req.params.id], req.body); - if (typeof user.markModified === "function") { - user.markModified('preferences.webhooks'); - } - return typeof cb === "function" ? cb(null, user.preferences.webhooks) : void 0; - }, - deleteWebhook: function(req, cb) { - delete user.preferences.webhooks[req.params.id]; - if (typeof user.markModified === "function") { - user.markModified('preferences.webhooks'); - } - return typeof cb === "function" ? cb(null, user.preferences.webhooks) : void 0; - }, - clearPMs: function(req, cb) { - user.inbox.messages = {}; - if (typeof user.markModified === "function") { - user.markModified('inbox.messages'); - } - return typeof cb === "function" ? cb(null, user.inbox.messages) : void 0; - }, - deletePM: function(req, cb) { - delete user.inbox.messages[req.params.id]; - if (typeof user.markModified === "function") { - user.markModified('inbox.messages.' + req.params.id); - } - return typeof cb === "function" ? cb(null, user.inbox.messages) : void 0; - }, - blockUser: function(req, cb) { - var i; - i = user.inbox.blocks.indexOf(req.params.uuid); - if (~i) { - user.inbox.blocks.splice(i, 1); - } else { - user.inbox.blocks.push(req.params.uuid); - } - if (typeof user.markModified === "function") { - user.markModified('inbox.blocks'); - } - return typeof cb === "function" ? cb(null, user.inbox.blocks) : void 0; - }, feed: function(req, cb) { var egg, evolve, food, message, pet, potion, userPets, _ref, _ref1, _ref2; _ref = req.params, pet = _ref.pet, food = _ref.food; @@ -15274,77 +14572,32 @@ api.wrap = function(user, main) { return typeof cb === "function" ? cb(null, _.pick(user, $w('items stats'))) : void 0; }, purchase: function(req, cb, ga) { - var convCap, convRate, item, key, price, type, _ref, _ref1, _ref2, _ref3; + var item, key, type, _ref; _ref = req.params, type = _ref.type, key = _ref.key; - if (type === 'gems' && key === 'gem') { - _ref1 = api.planGemLimits, convRate = _ref1.convRate, convCap = _ref1.convCap; - convCap += user.purchased.plan.consecutive.gemCapExtra; - if (!((_ref2 = user.purchased) != null ? (_ref3 = _ref2.plan) != null ? _ref3.customerId : void 0 : void 0)) { - return typeof cb === "function" ? cb({ - code: 401, - message: "Must subscribe to purchase gems with GP" - }, req) : void 0; - } - if (!(user.stats.gp >= convRate)) { - return typeof cb === "function" ? cb({ - code: 401, - message: "Not enough Gold" - }) : void 0; - } - if (user.purchased.plan.gemsBought >= convCap) { - return typeof cb === "function" ? cb({ - code: 401, - message: "You've reached the Gold=>Gem conversion cap (" + convCap + ") for this month. We have this to prevent abuse / farming. The cap will reset within the first three days of next month." - }) : void 0; - } - user.balance += .25; - user.purchased.plan.gemsBought++; - user.stats.gp -= convRate; - return typeof cb === "function" ? cb({ - code: 200, - message: "+1 Gems" - }, _.pick(user, $w('stats balance'))) : void 0; - } - if (type !== 'eggs' && type !== 'hatchingPotions' && type !== 'food' && type !== 'quests' && type !== 'gear') { + if (type !== 'eggs' && type !== 'hatchingPotions' && type !== 'food' && type !== 'quests' && type !== 'special') { return typeof cb === "function" ? cb({ code: 404, - message: ":type must be in [eggs,hatchingPotions,food,quests,gear]" + message: ":type must be in [hatchingPotions,eggs,food,quests,special]" }, req) : void 0; } - if (type === 'gear') { - item = content.gear.flat[key]; - if (user.items.gear.owned[key]) { - return typeof cb === "function" ? cb({ - code: 401, - message: i18n.t('alreadyHave', req.language) - }) : void 0; - } - price = (item.twoHanded ? 2 : 1) / 4; - } else { - item = content[type][key]; - price = item.value / 4; - } + item = content[type][key]; if (!item) { return typeof cb === "function" ? cb({ code: 404, message: ":key not found for Content." + type }, req) : void 0; } - if (user.balance < price) { + if (user.balance < (item.value / 4)) { return typeof cb === "function" ? cb({ code: 401, message: i18n.t('notEnoughGems', req.language) }) : void 0; } - user.balance -= price; - if (type === 'gear') { - user.items.gear.owned[key] = true; - } else { - if (!(user.items[type][key] > 0)) { - user.items[type][key] = 0; - } - user.items[type][key]++; + if (!(user.items[type][key] > 0)) { + user.items[type][key] = 0; } + user.items[type][key]++; + user.balance -= item.value / 4; if (typeof cb === "function") { cb(null, _.pick(user, $w('items balance'))); } @@ -15438,32 +14691,6 @@ api.wrap = function(user, main) { message: message }, _.pick(user, $w('items achievements stats'))) : void 0; }, - buyMysterySet: function(req, cb) { - var mysterySet, _ref; - if (!(user.purchased.plan.consecutive.trinkets > 0)) { - return typeof cb === "function" ? cb({ - code: 401, - message: "You don't have enough Mystic Hourglasses" - }) : void 0; - } - mysterySet = (_ref = content.timeTravelerStore(user.items.gear.owned)) != null ? _ref[req.params.key] : void 0; - if ((typeof window !== "undefined" && window !== null ? window.confirm : void 0) != null) { - if (!window.confirm("Buy this full set of items for 1 Mystic Hourglass?")) { - return; - } - } - if (!mysterySet) { - return typeof cb === "function" ? cb({ - code: 404, - message: "Mystery set not found, or set already owned" - }) : void 0; - } - _.each(mysterySet.items, function(i) { - return user.items.gear.owned[i.key] = true; - }); - user.purchased.plan.consecutive.trinkets--; - return typeof cb === "function" ? cb(null, _.pick(user, $w('items purchased.plan.consecutive'))) : void 0; - }, sell: function(req, cb) { var key, type, _ref; _ref = req.params, key = _ref.key, type = _ref.type; @@ -15676,28 +14903,6 @@ api.wrap = function(user, main) { } return typeof cb === "function" ? cb(null, 'items.special') : void 0; }, - openMysteryItem: function(req, cb, ga) { - var item, _ref, _ref1; - item = (_ref = user.purchased.plan) != null ? (_ref1 = _ref.mysteryItems) != null ? _ref1.shift() : void 0 : void 0; - if (!item) { - return typeof cb === "function" ? cb({ - code: 400, - message: "Empty" - }) : void 0; - } - item = content.gear.flat[item]; - user.items.gear.owned[item.key] = true; - if (typeof user.markModified === "function") { - user.markModified('purchased.plan.mysteryItems'); - } - if (typeof window !== 'undefined') { - (user._tmp != null ? user._tmp : user._tmp = {}).drop = { - type: 'gear', - dialog: "" + (item.text(req.language)) + " inside!" - }; - } - return typeof cb === "function" ? cb(null, user.items.gear.owned) : void 0; - }, score: function(req, cb) { var addPoints, calculateDelta, calculateReverseDelta, changeTaskValue, delta, direction, id, mpDelta, multiplier, num, options, stats, subtractPoints, task, th, _ref; _ref = req.params, id = _ref.id, direction = _ref.direction; @@ -15999,7 +15204,7 @@ api.wrap = function(user, main) { return api.dotGet(user, path); }, randomDrop: function(modifiers, req) { - var acceptableDrops, chance, drop, dropK, dropMultiplier, quest, rarity, task, _base, _base1, _base2, _name, _name1, _name2, _ref, _ref1, _ref2, _ref3; + var acceptableDrops, chance, drop, dropK, quest, rarity, task, _base, _base1, _base2, _name, _name1, _name2, _ref, _ref1; task = modifiers.task; chance = _.min([Math.abs(task.value - 21.27), 37.5]) / 150 + .02; chance *= task.priority * (1 + (task.streak / 100 || 0)) * (1 + (user._statsComputed.per / 100)) * (1 + (user.contributor.level / 40 || 0)) * (1 + (user.achievements.rebirths / 20 || 0)) * (1 + (user.achievements.streak / 200 || 0)) * (user._tmp.crit || 1) * (1 + .5 * (_.reduce(task.checklist, (function(m, i) { @@ -16016,11 +15221,10 @@ api.wrap = function(user, main) { user.markModified('party.quest.progress'); } } - dropMultiplier = ((_ref1 = user.purchased) != null ? (_ref2 = _ref1.plan) != null ? _ref2.customerId : void 0 : void 0) ? 2 : 1; - if ((api.daysSince(user.items.lastDrop.date, user.preferences) === 0) && (user.items.lastDrop.count >= dropMultiplier * (5 + Math.floor(user._statsComputed.per / 25) + (user.contributor.level || 0)))) { + if ((api.daysSince(user.items.lastDrop.date, user.preferences) === 0) && (user.items.lastDrop.count >= 5 + Math.floor(user._statsComputed.per / 25) + (user.contributor.level || 0))) { return; } - if (((_ref3 = user.flags) != null ? _ref3.dropsEnabled : void 0) && user.fns.predictableRandom(user.stats.exp) < chance) { + if (((_ref1 = user.flags) != null ? _ref1.dropsEnabled : void 0) && user.fns.predictableRandom(user.stats.exp) < chance) { rarity = user.fns.predictableRandom(user.stats.gp); if (rarity > .6) { drop = user.fns.randomVal(_.where(content.food, { @@ -16170,8 +15374,7 @@ api.wrap = function(user, main) { _.each({ vice1: 30, atom1: 15, - moonstone1: 60, - goldenknight1: 40 + moonstone1: 60 }, function(lvl, k) { var _base, _base1, _ref; if (!((_ref = user.flags.levelDrops) != null ? _ref[k] : void 0) && user.stats.lvl >= lvl) { @@ -16213,7 +15416,7 @@ api.wrap = function(user, main) { {user} */ cron: function(options) { - var clearBuffs, daysMissed, expTally, lvl, lvlDiv2, now, perfect, plan, progress, todoTally, _base, _base1, _base2, _base3, _progress, _ref, _ref1, _ref2; + var clearBuffs, daysMissed, expTally, lvl, lvlDiv2, now, perfect, plan, progress, todoTally, _base, _base1, _base2, _base3, _progress, _ref; if (options == null) { options = {}; } @@ -16238,44 +15441,6 @@ api.wrap = function(user, main) { stealth: 0, streaks: false }; - plan = (_ref = user.purchased) != null ? _ref.plan : void 0; - if (plan != null ? plan.customerId : void 0) { - if (moment(plan.dateUpdated).format('MMYYYY') !== moment().format('MMYYYY')) { - plan.gemsBought = 0; - plan.dateUpdated = new Date(); - _.defaults(plan.consecutive, { - count: 0, - offset: 0, - trinkets: 0, - gemCapExtra: 0 - }); - plan.consecutive.count++; - if (plan.consecutive.offset > 0) { - plan.consecutive.offset--; - } else if (plan.consecutive.count % 3 === 0) { - plan.consecutive.trinkets++; - plan.consecutive.gemCapExtra += 5; - if (plan.consecutive.gemCapExtra > 25) { - plan.consecutive.gemCapExtra = 25; - } - } - } - if (plan.dateTerminated && moment(plan.dateTerminated).isBefore(+(new Date))) { - _.merge(plan, { - planId: null, - customerId: null, - paymentMethod: null - }); - _.merge(plan.consecutive, { - count: 0, - offset: 0, - gemCapExtra: 0 - }); - if (typeof user.markModified === "function") { - user.markModified('purchased.plan'); - } - } - } if (user.preferences.sleep === true) { user.stats.buffs = clearBuffs; return; @@ -16365,14 +15530,12 @@ api.wrap = function(user, main) { date: now, value: expTally }); - if (!((_ref1 = user.purchased) != null ? (_ref2 = _ref1.plan) != null ? _ref2.customerId : void 0 : void 0)) { - user.fns.preenUserHistory(); - if (typeof user.markModified === "function") { - user.markModified('history'); - } - if (typeof user.markModified === "function") { - user.markModified('dailys'); - } + user.fns.preenUserHistory(); + if (typeof user.markModified === "function") { + user.markModified('history'); + } + if (typeof user.markModified === "function") { + user.markModified('dailys'); } user.stats.buffs = perfect ? ((_base3 = user.achievements).perfect != null ? _base3.perfect : _base3.perfect = 0, user.achievements.perfect++, user.stats.lvl < 100 ? lvlDiv2 = Math.ceil(user.stats.lvl / 2) : lvlDiv2 = 50, { str: lvlDiv2, @@ -16386,6 +15549,15 @@ api.wrap = function(user, main) { if (user.stats.mp > user._statsComputed.maxMP) { user.stats.mp = user._statsComputed.maxMP; } + plan = (_ref = user.purchased) != null ? _ref.plan : void 0; + if (plan && plan.customerId && plan.dateTerminated && moment(plan.dateTerminated).isBefore(+(new Date))) { + _.merge(user.purchased.plan, { + planId: null, + customerId: null, + paymentMethod: null + }); + user.markModified('purchased.plan'); + } progress = user.party.quest.progress; _progress = _.cloneDeep(progress); _.merge(progress, { @@ -16484,5 +15656,5 @@ api.wrap = function(user, main) { }; -}).call(this,require("/home/sabrecat/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js")) -},{"./content.coffee":5,"./i18n.coffee":6,"/home/sabrecat/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":2,"lodash":3,"moment":4}]},{},[1]) \ No newline at end of file +}).call(this,require("/Users/lefnire/Dropbox/Sites/habitrpg/modules/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js")) +},{"./content.coffee":5,"./i18n.coffee":6,"/Users/lefnire/Dropbox/Sites/habitrpg/modules/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":2,"lodash":3,"moment":4}]},{},[1]) \ No newline at end of file diff --git a/script/index.coffee b/script/index.coffee index b2ff70a6a8..97e32a4631 100644 --- a/script/index.coffee +++ b/script/index.coffee @@ -401,7 +401,7 @@ api.wrap = (user, main=true) -> revive: (req, cb) -> return cb?({code:400, message: "Cannot revive if not dead"}) unless user.stats.hp <= 0 - # Reset stats + # Reset stats after death _.merge user.stats, {hp:50, exp:0, gp:0} user.stats.lvl-- if user.stats.lvl > 1 @@ -410,9 +410,20 @@ api.wrap = (user, main=true) -> user.stats[lostStat]-- if lostStat # Lose a gear piece - # Note, they can actually lose item weapon_*_0 - it's 0 to buy back, no big deal + # Free items (value:0) cannot be lost to avoid "pay to win". Subscribers have more free (Mystery) items and so would have a higher chance of loosing a free one. # Note ""+k string-casting. Without this, when run on the server Mongoose returns funny objects - lostItem = user.fns.randomVal _.reduce(user.items.gear.owned, ((m,v,k)->m[''+k]=''+k if v;m), {}) + cl = user.stats.class + lostItem = user.fns.randomVal _.reduce(user.items.gear.owned, ((m,v,k)-> + if v && k != 'toObject' + # 'toObject' appears as first key when run on server. No idea why. + itm = content.gear.flat[''+k] + if itm + if itm.value > 0 && ( itm.klass == cl || ( itm.klass == 'special' && (! itm.specialClass || itm.specialClass == cl) ) ) + m[''+k]=''+k + # else + # console.log "Can't get item for " + k + # # in case other wierd things like 'toObject' turn up + m), {}) if item = content.gear.flat[lostItem] user.items.gear.owned[lostItem] = false @@ -1306,7 +1317,7 @@ api.wrap = (user, main=true) -> )()]++ updateStats: (stats, req) -> - # Game Over + # Game Over (death) return user.stats.hp=0 if stats.hp <= 0 user.stats.hp = stats.hp