mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
wip(shared): adapt to v3
This commit is contained in:
5
common/script/.eslintrc
Normal file
5
common/script/.eslintrc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"globals": {
|
||||||
|
"window": true,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import t from './translation';
|
import t from './translation';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { NotAuthorized } from '../api-v3/errors';
|
import { NotAuthorized } from '../libs/errors';
|
||||||
/*
|
/*
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
Spells
|
Spells
|
||||||
|
|||||||
@@ -1,94 +1,110 @@
|
|||||||
import moment from 'moment';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import {
|
// When using a common module from the website or the server NEVER import the module directly
|
||||||
daysSince,
|
// but access it through `api` (the main common) module, otherwise you would require the non transpiled version of the file in production.
|
||||||
shouldDo,
|
let api = module.exports = {};
|
||||||
} from './cron';
|
|
||||||
|
import content from './content/index';
|
||||||
|
api.content = content;
|
||||||
|
|
||||||
|
import * as errors from './libs/errors';
|
||||||
|
api.errors = errors;
|
||||||
|
import i18n from './i18n';
|
||||||
|
api.i18n = i18n;
|
||||||
|
|
||||||
|
// TODO under api.libs.cron?
|
||||||
|
import { shouldDo, daysSince } from './cron';
|
||||||
|
api.shouldDo = shouldDo;
|
||||||
|
api.daysSince = daysSince;
|
||||||
|
|
||||||
|
// TODO under api.constants?
|
||||||
import {
|
import {
|
||||||
MAX_HEALTH,
|
MAX_HEALTH,
|
||||||
MAX_LEVEL,
|
MAX_LEVEL,
|
||||||
MAX_STAT_POINTS,
|
MAX_STAT_POINTS,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import * as statHelpers from './statHelpers';
|
|
||||||
|
|
||||||
import importedLibs from './libs';
|
|
||||||
|
|
||||||
var $w, preenHistory, sortOrder,
|
|
||||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
|
||||||
|
|
||||||
import content from './content/index';
|
|
||||||
import i18n from './i18n';
|
|
||||||
|
|
||||||
import * as errors from './api-v3/errors';
|
|
||||||
import scoreTask from './api-v3/scoreTask';
|
|
||||||
|
|
||||||
let api = module.exports = {};
|
|
||||||
|
|
||||||
// Temporary location of API v3 files (soon to be removed)
|
|
||||||
api.v3 = {
|
|
||||||
scoreTask,
|
|
||||||
errors,
|
|
||||||
};
|
|
||||||
|
|
||||||
api.i18n = i18n;
|
|
||||||
api.shouldDo = shouldDo;
|
|
||||||
|
|
||||||
api.maxLevel = MAX_LEVEL;
|
api.maxLevel = MAX_LEVEL;
|
||||||
api.capByLevel = statHelpers.capByLevel;
|
|
||||||
api.maxHealth = MAX_HEALTH;
|
api.maxHealth = MAX_HEALTH;
|
||||||
|
api.maxStatPoints = MAX_STAT_POINTS;
|
||||||
|
|
||||||
|
// TODO under api.libs.statHelpers?
|
||||||
|
import * as statHelpers from './statHelpers';
|
||||||
|
api.capByLevel = statHelpers.capByLevel;
|
||||||
api.tnl = statHelpers.toNextLevel;
|
api.tnl = statHelpers.toNextLevel;
|
||||||
api.diminishingReturns = statHelpers.diminishingReturns;
|
api.diminishingReturns = statHelpers.diminishingReturns;
|
||||||
|
|
||||||
$w = api.$w = importedLibs.splitWhitespace;
|
// TODO under api.libs?
|
||||||
api.dotSet = importedLibs.dotSet;
|
import splitWhitespace from './libs/splitWhitespace';
|
||||||
api.dotGet = importedLibs.dotGet;
|
const $w = api.$w = splitWhitespace;
|
||||||
api.refPush = importedLibs.refPush;
|
|
||||||
api.planGemLimits = importedLibs.planGemLimits;
|
|
||||||
|
|
||||||
preenHistory = importedLibs.preenHistory;
|
import dotSet from './libs/dotSet';
|
||||||
|
api.dotSet = dotSet;
|
||||||
|
|
||||||
api.preenTodos = importedLibs.preenTodos;
|
import dotGet from './libs/dotGet';
|
||||||
api.updateStore = importedLibs.updateStore;
|
api.dotGet = dotGet;
|
||||||
|
|
||||||
|
import refPush from './libs/refPush';
|
||||||
|
api.refPush = refPush;
|
||||||
|
|
||||||
/*
|
import planGemLimits from './libs/planGemLimits';
|
||||||
------------------------------------------------------
|
api.planGemLimits = planGemLimits;
|
||||||
Content
|
|
||||||
------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
api.content = content;
|
import preenTodos from './libs/preenTodos';
|
||||||
|
api.preenTodos = preenTodos;
|
||||||
|
|
||||||
|
import updateStore from './libs/updateStore';
|
||||||
|
api.updateStore = updateStore;
|
||||||
|
|
||||||
/*
|
import uuid from './libs/uuid';
|
||||||
------------------------------------------------------
|
api.uuid = uuid;
|
||||||
Misc Helpers
|
|
||||||
------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
api.uuid = importedLibs.uuid;
|
import countExists from './libs/countExists';
|
||||||
api.countExists = importedLibs.countExists;
|
api.countExists = countExists;
|
||||||
api.taskDefaults = importedLibs.taskDefaults;
|
|
||||||
api.percent = importedLibs.percent;
|
|
||||||
api.removeWhitespace = importedLibs.removeWhitespace;
|
|
||||||
api.encodeiCalLink = importedLibs.encodeiCalLink;
|
|
||||||
api.gold = importedLibs.gold;
|
|
||||||
api.silver = importedLibs.silver;
|
|
||||||
api.taskClasses = importedLibs.taskClasses;
|
|
||||||
api.friendlyTimestamp = importedLibs.friendlyTimestamp;
|
|
||||||
api.newChatMessages = importedLibs.newChatMessages;
|
|
||||||
api.noTags = importedLibs.appliedTags;
|
|
||||||
api.appliedTags = importedLibs.appliedTags;
|
|
||||||
|
|
||||||
|
import taskDefaults from './libs/taskDefaults';
|
||||||
|
api.taskDefaults = taskDefaults;
|
||||||
|
|
||||||
/*
|
import percent from './libs/percent';
|
||||||
Various counting functions
|
api.percent = percent;
|
||||||
*/
|
|
||||||
|
import removeWhitespace from './libs/removeWhitespace';
|
||||||
|
api.removeWhitespace = removeWhitespace;
|
||||||
|
|
||||||
|
import encodeiCalLink from './libs/encodeiCalLink';
|
||||||
|
api.encodeiCalLink = encodeiCalLink;
|
||||||
|
|
||||||
|
import gold from './libs/gold';
|
||||||
|
api.gold = gold;
|
||||||
|
|
||||||
|
import silver from './libs/silver';
|
||||||
|
api.silver = silver;
|
||||||
|
|
||||||
|
import taskClasses from './libs/taskClasses';
|
||||||
|
api.taskClasses = taskClasses;
|
||||||
|
|
||||||
|
import friendlyTimestamp from './libs/friendlyTimestamp';
|
||||||
|
api.friendlyTimestamp = friendlyTimestamp;
|
||||||
|
|
||||||
|
import newChatMessages from './libs/newChatMessages';
|
||||||
|
api.newChatMessages = newChatMessages;
|
||||||
|
|
||||||
|
import noTags from './libs/noTags';
|
||||||
|
api.noTags = noTags;
|
||||||
|
|
||||||
|
import appliedTags from './libs/appliedTags';
|
||||||
|
api.appliedTags = appliedTags;
|
||||||
|
|
||||||
import count from './count';
|
import count from './count';
|
||||||
api.count = count;
|
api.count = count;
|
||||||
|
|
||||||
|
// TODO As ops and fns are ported, exported them through the api object
|
||||||
|
import scoreTask from './ops/scoreTask';
|
||||||
|
|
||||||
|
api.ops = {
|
||||||
|
scoreTask,
|
||||||
|
};
|
||||||
|
api.fns = {};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
@@ -130,14 +146,11 @@ TODO
|
|||||||
import importedOps from './ops';
|
import importedOps from './ops';
|
||||||
import importedFns from './fns';
|
import importedFns from './fns';
|
||||||
|
|
||||||
api.wrap = function(user, main) {
|
// TODO redo
|
||||||
if (main == null) {
|
api.wrap = function wrapUser (user, main = true) {
|
||||||
main = true;
|
if (user._wrapped) return;
|
||||||
}
|
|
||||||
if (user._wrapped) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
user._wrapped = true;
|
user._wrapped = true;
|
||||||
|
|
||||||
if (main) {
|
if (main) {
|
||||||
user.ops = {
|
user.ops = {
|
||||||
update: _.partial(importedOps.update, user),
|
update: _.partial(importedOps.update, user),
|
||||||
@@ -184,9 +197,10 @@ api.wrap = function(user, main) {
|
|||||||
allocate: _.partial(importedOps.allocate, user),
|
allocate: _.partial(importedOps.allocate, user),
|
||||||
readCard: _.partial(importedOps.readCard, user),
|
readCard: _.partial(importedOps.readCard, user),
|
||||||
openMysteryItem: _.partial(importedOps.openMysteryItem, user),
|
openMysteryItem: _.partial(importedOps.openMysteryItem, user),
|
||||||
score: _.partial(importedOps.score, user),
|
scoreTask: _.partial(importedOps.scoreTask, user),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
user.fns = {
|
user.fns = {
|
||||||
getItem: _.partial(importedFns.getItem, user),
|
getItem: _.partial(importedFns.getItem, user),
|
||||||
handleTwoHanded: _.partial(importedFns.handleTwoHanded, user),
|
handleTwoHanded: _.partial(importedFns.handleTwoHanded, user),
|
||||||
@@ -203,32 +217,30 @@ api.wrap = function(user, main) {
|
|||||||
ultimateGear: _.partial(importedFns.ultimateGear, user),
|
ultimateGear: _.partial(importedFns.ultimateGear, user),
|
||||||
nullify: _.partial(importedFns.nullify, user),
|
nullify: _.partial(importedFns.nullify, user),
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.defineProperty(user, '_statsComputed', {
|
Object.defineProperty(user, '_statsComputed', {
|
||||||
get: function() {
|
get () {
|
||||||
var computed;
|
let computed = _.reduce(['per', 'con', 'str', 'int'], (m, stat) => {
|
||||||
computed = _.reduce(['per', 'con', 'str', 'int'], (function(_this) {
|
m[stat] = _.reduce($w('stats stats.buffs items.gear.equipped.weapon items.gear.equipped.armor items.gear.equipped.head items.gear.equipped.shield'), (m2, path) => {
|
||||||
return function(m, stat) {
|
let val = user.fns.dotGet(path);
|
||||||
m[stat] = _.reduce($w('stats stats.buffs items.gear.equipped.weapon items.gear.equipped.armor items.gear.equipped.head items.gear.equipped.shield'), function(m2, path) {
|
let item;
|
||||||
var item, val;
|
return m2 + (path.indexOf('items.gear') !== -1 ? (item = content.gear.flat[val], (Number(!item ? item[stat] : undefined) || 0) * ((!item ? item.klass : undefined) === user.stats.class || (!item ? item.specialClass : undefined) === user.stats.class ? 1.5 : 1)) : Number(val[stat]) || 0);
|
||||||
val = user.fns.dotGet(path);
|
|
||||||
return m2 + (~path.indexOf('items.gear') ? (item = content.gear.flat[val], (+(item != null ? item[stat] : void 0) || 0) * ((item != null ? item.klass : void 0) === user.stats["class"] || (item != null ? item.specialClass : void 0) === user.stats["class"] ? 1.5 : 1)) : +val[stat] || 0);
|
|
||||||
}, 0);
|
}, 0);
|
||||||
m[stat] += Math.floor(api.capByLevel(user.stats.lvl) / 2);
|
m[stat] += Math.floor(api.capByLevel(user.stats.lvl) / 2);
|
||||||
return m;
|
return m;
|
||||||
};
|
});
|
||||||
})(this), {});
|
|
||||||
computed.maxMP = computed.int * 2 + 30;
|
computed.maxMP = computed.int * 2 + 30;
|
||||||
return computed;
|
return computed;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
Object.defineProperty(user, 'tasks', {
|
Object.defineProperty(user, 'tasks', {
|
||||||
get: function() {
|
get () {
|
||||||
var tasks;
|
let tasks = user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards);
|
||||||
tasks = user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards);
|
return _.object(_.pluck(tasks, 'id'), tasks);
|
||||||
return _.object(_.pluck(tasks, "id"), tasks);
|
},
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import extendableBuiltin from './libs/extendableBuiltin';
|
import extendableBuiltin from './extendableBuiltin';
|
||||||
|
|
||||||
// Base class for custom application errors
|
// Base class for custom application errors
|
||||||
// It extends Error and capture the stack trace
|
// It extends Error and capture the stack trace
|
||||||
@@ -42,7 +42,7 @@ import disableClasses from './disableClasses';
|
|||||||
import allocate from './allocate';
|
import allocate from './allocate';
|
||||||
import readCard from './readCard';
|
import readCard from './readCard';
|
||||||
import openMysteryItem from './openMysteryItem';
|
import openMysteryItem from './openMysteryItem';
|
||||||
import score from './score';
|
import scoreTask from './scoreTask';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
update,
|
update,
|
||||||
@@ -89,5 +89,5 @@ module.exports = {
|
|||||||
allocate,
|
allocate,
|
||||||
readCard,
|
readCard,
|
||||||
openMysteryItem,
|
openMysteryItem,
|
||||||
score,
|
scoreTask,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
import moment from 'moment';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import i18n from '../i18n';
|
|
||||||
|
|
||||||
module.exports = function(user, req, cb) {
|
|
||||||
var addPoints, calculateDelta, calculateReverseDelta, changeTaskValue, delta, direction, gainMP, id, multiplier, num, options, ref, stats, subtractPoints, task, th;
|
|
||||||
ref = req.params, id = ref.id, direction = ref.direction;
|
|
||||||
task = user.tasks[id];
|
|
||||||
options = req.query || {};
|
|
||||||
_.defaults(options, {
|
|
||||||
times: 1,
|
|
||||||
cron: false
|
|
||||||
});
|
|
||||||
user._tmp = {};
|
|
||||||
stats = {
|
|
||||||
gp: +user.stats.gp,
|
|
||||||
hp: +user.stats.hp,
|
|
||||||
exp: +user.stats.exp
|
|
||||||
};
|
|
||||||
task.value = +task.value;
|
|
||||||
task.streak = ~~task.streak;
|
|
||||||
if (task.priority == null) {
|
|
||||||
task.priority = 1;
|
|
||||||
}
|
|
||||||
if (task.value > stats.gp && task.type === 'reward') {
|
|
||||||
return typeof cb === "function" ? cb({
|
|
||||||
code: 401,
|
|
||||||
message: i18n.t('messageNotEnoughGold', req.language)
|
|
||||||
}) : void 0;
|
|
||||||
}
|
|
||||||
delta = 0;
|
|
||||||
calculateDelta = function() {
|
|
||||||
var currVal, nextDelta, ref1;
|
|
||||||
currVal = task.value < -47.27 ? -47.27 : task.value > 21.27 ? 21.27 : task.value;
|
|
||||||
nextDelta = Math.pow(0.9747, currVal) * (direction === 'down' ? -1 : 1);
|
|
||||||
if (((ref1 = task.checklist) != null ? ref1.length : void 0) > 0) {
|
|
||||||
if (direction === 'down' && task.type === 'daily' && options.cron) {
|
|
||||||
nextDelta *= 1 - _.reduce(task.checklist, (function(m, i) {
|
|
||||||
return m + (i.completed ? 1 : 0);
|
|
||||||
}), 0) / task.checklist.length;
|
|
||||||
}
|
|
||||||
if (task.type === 'todo') {
|
|
||||||
nextDelta *= 1 + _.reduce(task.checklist, (function(m, i) {
|
|
||||||
return m + (i.completed ? 1 : 0);
|
|
||||||
}), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nextDelta;
|
|
||||||
};
|
|
||||||
calculateReverseDelta = function() {
|
|
||||||
var calc, closeEnough, currVal, diff, nextDelta, ref1, testVal;
|
|
||||||
currVal = task.value < -47.27 ? -47.27 : task.value > 21.27 ? 21.27 : task.value;
|
|
||||||
testVal = currVal + Math.pow(0.9747, currVal) * (direction === 'down' ? -1 : 1);
|
|
||||||
closeEnough = 0.00001;
|
|
||||||
while (true) {
|
|
||||||
calc = testVal + Math.pow(0.9747, testVal);
|
|
||||||
diff = currVal - calc;
|
|
||||||
if (Math.abs(diff) < closeEnough) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (diff > 0) {
|
|
||||||
testVal -= diff;
|
|
||||||
} else {
|
|
||||||
testVal += diff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nextDelta = testVal - currVal;
|
|
||||||
if (((ref1 = task.checklist) != null ? ref1.length : void 0) > 0) {
|
|
||||||
if (task.type === 'todo') {
|
|
||||||
nextDelta *= 1 + _.reduce(task.checklist, (function(m, i) {
|
|
||||||
return m + (i.completed ? 1 : 0);
|
|
||||||
}), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nextDelta;
|
|
||||||
};
|
|
||||||
changeTaskValue = function() {
|
|
||||||
return _.times(options.times, function() {
|
|
||||||
var nextDelta, ref1;
|
|
||||||
nextDelta = !options.cron && direction === 'down' ? calculateReverseDelta() : calculateDelta();
|
|
||||||
if (task.type !== 'reward') {
|
|
||||||
if (user.preferences.automaticAllocation === true && user.preferences.allocationMode === 'taskbased' && !(task.type === 'todo' && direction === 'down')) {
|
|
||||||
user.stats.training[task.attribute] += nextDelta;
|
|
||||||
}
|
|
||||||
if (direction === 'up') {
|
|
||||||
user.party.quest.progress.up = user.party.quest.progress.up || 0;
|
|
||||||
if ((ref1 = task.type) === 'daily' || ref1 === 'todo') {
|
|
||||||
user.party.quest.progress.up += nextDelta * (1 + (user._statsComputed.str / 200));
|
|
||||||
}
|
|
||||||
if (task.type === 'habit') {
|
|
||||||
user.party.quest.progress.up += nextDelta * (0.5 + (user._statsComputed.str / 400));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
task.value += nextDelta;
|
|
||||||
}
|
|
||||||
return delta += nextDelta;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
addPoints = function() {
|
|
||||||
var _crit, afterStreak, currStreak, gpMod, intBonus, perBonus, streakBonus;
|
|
||||||
_crit = (delta > 0 ? user.fns.crit() : 1);
|
|
||||||
if (_crit > 1) {
|
|
||||||
user._tmp.crit = _crit;
|
|
||||||
}
|
|
||||||
intBonus = 1 + (user._statsComputed.int * .025);
|
|
||||||
stats.exp += Math.round(delta * intBonus * task.priority * _crit * 6);
|
|
||||||
perBonus = 1 + user._statsComputed.per * .02;
|
|
||||||
gpMod = delta * task.priority * _crit * perBonus;
|
|
||||||
return stats.gp += task.streak ? (currStreak = direction === 'down' ? task.streak - 1 : task.streak, streakBonus = currStreak / 100 + 1, afterStreak = gpMod * streakBonus, currStreak > 0 ? gpMod > 0 ? user._tmp.streakBonus = afterStreak - gpMod : void 0 : void 0, afterStreak) : gpMod;
|
|
||||||
};
|
|
||||||
subtractPoints = function() {
|
|
||||||
var conBonus, hpMod;
|
|
||||||
conBonus = 1 - (user._statsComputed.con / 250);
|
|
||||||
if (conBonus < .1) {
|
|
||||||
conBonus = 0.1;
|
|
||||||
}
|
|
||||||
hpMod = delta * conBonus * task.priority * 2;
|
|
||||||
return stats.hp += Math.round(hpMod * 10) / 10;
|
|
||||||
};
|
|
||||||
gainMP = function(delta) {
|
|
||||||
delta *= user._tmp.crit || 1;
|
|
||||||
user.stats.mp += delta;
|
|
||||||
if (user.stats.mp >= user._statsComputed.maxMP) {
|
|
||||||
user.stats.mp = user._statsComputed.maxMP;
|
|
||||||
}
|
|
||||||
if (user.stats.mp < 0) {
|
|
||||||
return user.stats.mp = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
switch (task.type) {
|
|
||||||
case 'habit':
|
|
||||||
changeTaskValue();
|
|
||||||
if (delta > 0) {
|
|
||||||
addPoints();
|
|
||||||
} else {
|
|
||||||
subtractPoints();
|
|
||||||
}
|
|
||||||
gainMP(_.max([0.25, .0025 * user._statsComputed.maxMP]) * (direction === 'down' ? -1 : 1));
|
|
||||||
th = (task.history != null ? task.history : task.history = []);
|
|
||||||
if (th[th.length - 1] && moment(th[th.length - 1].date).isSame(new Date, 'day')) {
|
|
||||||
th[th.length - 1].value = task.value;
|
|
||||||
} else {
|
|
||||||
th.push({
|
|
||||||
date: +(new Date),
|
|
||||||
value: task.value
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (typeof user.markModified === "function") {
|
|
||||||
user.markModified("habits." + (_.findIndex(user.habits, {
|
|
||||||
id: task.id
|
|
||||||
})) + ".history");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'daily':
|
|
||||||
if (options.cron) {
|
|
||||||
changeTaskValue();
|
|
||||||
subtractPoints();
|
|
||||||
if (!user.stats.buffs.streaks) {
|
|
||||||
task.streak = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
changeTaskValue();
|
|
||||||
if (direction === 'down') {
|
|
||||||
delta = calculateDelta();
|
|
||||||
}
|
|
||||||
addPoints();
|
|
||||||
gainMP(_.max([1, .01 * user._statsComputed.maxMP]) * (direction === 'down' ? -1 : 1));
|
|
||||||
if (direction === 'up') {
|
|
||||||
task.streak = task.streak ? task.streak + 1 : 1;
|
|
||||||
if ((task.streak % 21) === 0) {
|
|
||||||
user.achievements.streak = user.achievements.streak ? user.achievements.streak + 1 : 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((task.streak % 21) === 0) {
|
|
||||||
user.achievements.streak = user.achievements.streak ? user.achievements.streak - 1 : 0;
|
|
||||||
}
|
|
||||||
task.streak = task.streak ? task.streak - 1 : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'todo':
|
|
||||||
if (options.cron) {
|
|
||||||
changeTaskValue();
|
|
||||||
} else {
|
|
||||||
task.dateCompleted = direction === 'up' ? new Date : void 0;
|
|
||||||
changeTaskValue();
|
|
||||||
if (direction === 'down') {
|
|
||||||
delta = calculateDelta();
|
|
||||||
}
|
|
||||||
addPoints();
|
|
||||||
multiplier = _.max([
|
|
||||||
_.reduce(task.checklist, (function(m, i) {
|
|
||||||
return m + (i.completed ? 1 : 0);
|
|
||||||
}), 1), 1
|
|
||||||
]);
|
|
||||||
gainMP(_.max([multiplier, .01 * user._statsComputed.maxMP * multiplier]) * (direction === 'down' ? -1 : 1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'reward':
|
|
||||||
changeTaskValue();
|
|
||||||
stats.gp -= Math.abs(task.value);
|
|
||||||
num = parseFloat(task.value).toFixed(2);
|
|
||||||
if (stats.gp < 0) {
|
|
||||||
stats.hp += stats.gp;
|
|
||||||
stats.gp = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
user.fns.updateStats(stats, req);
|
|
||||||
if (typeof window === 'undefined') {
|
|
||||||
if (direction === 'up') {
|
|
||||||
user.fns.randomDrop({
|
|
||||||
task: task,
|
|
||||||
delta: delta
|
|
||||||
}, req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof cb === "function") {
|
|
||||||
cb(null, user);
|
|
||||||
}
|
|
||||||
return delta;
|
|
||||||
};
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import {
|
import {
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from './errors';
|
} from '../libs/errors';
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
|
|
||||||
const MAX_TASK_VALUE = 21.27;
|
const MAX_TASK_VALUE = 21.27;
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
"npm": "^3.3.10"
|
"npm": "^3.3.10"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "gulp test:api-v3",
|
"test": "gulp test",
|
||||||
"test:api-v2:unit": "mocha test/server_side",
|
"test:api-v2:unit": "mocha test/server_side",
|
||||||
"test:api-v2:integration": "mocha test/api/v2 --recursive",
|
"test:api-v2:integration": "mocha test/api/v2 --recursive",
|
||||||
"test:api-v3": "gulp test:api-v3",
|
"test:api-v3": "gulp test:api-v3",
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ const SERVER_FILES = [
|
|||||||
const COMMON_FILES = [
|
const COMMON_FILES = [
|
||||||
'./common/script/**/*.js',
|
'./common/script/**/*.js',
|
||||||
// @TODO remove these negations as the files are converted over.
|
// @TODO remove these negations as the files are converted over.
|
||||||
'!./common/script/index.js',
|
|
||||||
'!./common/script/content/index.js',
|
'!./common/script/content/index.js',
|
||||||
'!./common/script/ops/**/*.js',
|
'!./common/script/ops/**/*.js',
|
||||||
'!./common/script/fns/**/*.js',
|
'!./common/script/fns/**/*.js',
|
||||||
@@ -25,7 +24,7 @@ const TEST_FILES = [
|
|||||||
'./test/**/*.js',
|
'./test/**/*.js',
|
||||||
// @TODO remove these negations as the test files are cleaned up.
|
// @TODO remove these negations as the test files are cleaned up.
|
||||||
'!./test/api-legacy/**/*',
|
'!./test/api-legacy/**/*',
|
||||||
'!./test/common/simulations/**/*',
|
'!./test/common_old/simulations/**/*',
|
||||||
'!./test/content/**/*',
|
'!./test/content/**/*',
|
||||||
'!./test/server_side/**/*',
|
'!./test/server_side/**/*',
|
||||||
'!./test/spec/**/*',
|
'!./test/spec/**/*',
|
||||||
|
|||||||
@@ -373,6 +373,16 @@ gulp.task('test:api-v3:integration:separate-server', (done) => {
|
|||||||
pipe(runner);
|
pipe(runner);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task('test', (done) => {
|
||||||
|
runSequence(
|
||||||
|
'lint',
|
||||||
|
'test:common',
|
||||||
|
'test:api-v3:unit',
|
||||||
|
'test:api-v3:integration',
|
||||||
|
done
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task('test:api-v3', (done) => {
|
gulp.task('test:api-v3', (done) => {
|
||||||
runSequence(
|
runSequence(
|
||||||
'lint',
|
'lint',
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ import {
|
|||||||
import { v4 as generateUUID } from 'uuid';
|
import { v4 as generateUUID } from 'uuid';
|
||||||
|
|
||||||
describe('DELETE /challenges/:challengeId', () => {
|
describe('DELETE /challenges/:challengeId', () => {
|
||||||
it('returns error when challengeId is not a valid UUID', async () => {
|
it.only('returns error when challengeId is not a valid UUID', async () => {
|
||||||
let user = await generateUser();
|
let user = await generateUser();
|
||||||
|
|
||||||
await expect(user.del(`/challenges/test`)).to.eventually.be.rejected.and.eql({
|
await expect(user.del(`/challenges/test`)).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// TODO move to shared tests
|
// TODO move to shared tests
|
||||||
import { CustomError } from '../../../../../common/script/api-v3/errors';
|
|
||||||
import {
|
import {
|
||||||
|
CustomError,
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
BadRequest,
|
BadRequest,
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import _ from 'lodash';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { preenHistory } from '../../libs/api-v3/preening';
|
import { preenHistory } from '../../libs/api-v3/preening';
|
||||||
|
|
||||||
const scoreTask = common.v3.scoreTask;
|
const scoreTask = common.ops.scoreTask;
|
||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import common from '../../../../common/script';
|
import common from '../../../../common/script';
|
||||||
|
|
||||||
export const CustomError = common.v3.errors.CustomError;
|
export const CustomError = common.errors.CustomError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine NotAuthorized
|
* @apiDefine NotAuthorized
|
||||||
@@ -13,7 +13,7 @@ export const CustomError = common.v3.errors.CustomError;
|
|||||||
* "message": "Not authorized."
|
* "message": "Not authorized."
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
export const NotAuthorized = common.v3.errors.NotAuthorized;
|
export const NotAuthorized = common.errors.NotAuthorized;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine BadRequest
|
* @apiDefine BadRequest
|
||||||
@@ -26,7 +26,7 @@ export const NotAuthorized = common.v3.errors.NotAuthorized;
|
|||||||
* "message": "Bad request."
|
* "message": "Bad request."
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
export const BadRequest = common.v3.errors.BadRequest;
|
export const BadRequest = common.errors.BadRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine NotFound
|
* @apiDefine NotFound
|
||||||
@@ -39,7 +39,7 @@ export const BadRequest = common.v3.errors.BadRequest;
|
|||||||
* "message": "Not found."
|
* "message": "Not found."
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
export const NotFound = common.v3.errors.NotFound;
|
export const NotFound = common.errors.NotFound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine InternalServerError
|
* @apiDefine InternalServerError
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import Group from '../../models/group';
|
|||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import { preenUserHistory } from '../../libs/api-v3/preening';
|
import { preenUserHistory } from '../../libs/api-v3/preening';
|
||||||
|
|
||||||
const scoreTask = common.v3.scoreTask;
|
const scoreTask = common.ops.scoreTask;
|
||||||
|
|
||||||
let clearBuffs = {
|
let clearBuffs = {
|
||||||
str: 0,
|
str: 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user