From ef83d54fd957c01827576dd457502301a98b0a28 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Thu, 14 Mar 2019 10:10:58 +0200 Subject: [PATCH] Reorganized folder structure, removed legacy v1 code --- app/config.vulcanize | 55 --- .../api/parenting}/deleteRemovedDocuments.js | 2 +- .../server/config}/accountsMeldConfig.js | 0 .../server/config/simpleSchemaDebug.js} | 2 +- app/lib/constants/Schemas.js | 1 - app/lib/constants/abilities.js | 19 - app/lib/constants/appName.js | 1 - app/lib/constants/attributes.js | 34 -- app/lib/constants/characterAssetAllowDeny.js | 63 --- app/lib/constants/colorOptions.js | 51 -- app/lib/constants/damageDice.js | 9 - app/lib/constants/damageTypes.js | 31 -- app/lib/constants/saves.js | 8 - app/lib/constants/skills.js | 50 -- app/lib/constants/statOrder.js | 82 --- app/lib/constants/subsManager.js | 6 - app/lib/constants/xpTable.js | 21 - app/lib/dice/roll.js | 21 - app/lib/functions/characterExport.js | 258 ---------- app/lib/functions/characterJSON.js | 17 - app/lib/functions/characterUtility.js | 7 - app/lib/functions/computeCharacter.js | 224 --------- app/lib/functions/permissions.js | 19 - app/lib/functions/pointBuy.js | 66 --- app/lib/functions/preventLoop.js | 35 -- app/lib/functions/shareCharacter.js | 14 - app/lib/functions/updatePolymerInputs.js | 14 - app/lib/functions/vMixExport.js | 9 - app/lib/memoize/memoize.js | 60 --- app/lib/methods/conditions.js | 467 ------------------ app/lib/methods/removeMeFromReaders.js | 11 - app/private/changeLogs/changeLogs.js | 347 ------------- app/server/lib/logRateError.js | 8 - app/server/main.js | 3 + app/server/migrations/migrations.js | 186 ------- .../mocha/server/lib/characterUtility.js | 31 -- .../mocha/server/model/character/character.js | 25 - .../mocha/server/model/character/effects.js | 193 -------- app/tests/mocha/server/sampleServerTest.js | 9 - 39 files changed, 5 insertions(+), 2454 deletions(-) delete mode 100644 app/config.vulcanize rename app/{server/lib/cron => imports/api/parenting}/deleteRemovedDocuments.js (95%) rename app/{server/lib/configuration => imports/server/config}/accountsMeldConfig.js (100%) rename app/{sharedMain.js => imports/server/config/simpleSchemaDebug.js} (79%) delete mode 100644 app/lib/constants/Schemas.js delete mode 100644 app/lib/constants/abilities.js delete mode 100644 app/lib/constants/appName.js delete mode 100644 app/lib/constants/attributes.js delete mode 100644 app/lib/constants/characterAssetAllowDeny.js delete mode 100644 app/lib/constants/colorOptions.js delete mode 100644 app/lib/constants/damageDice.js delete mode 100644 app/lib/constants/damageTypes.js delete mode 100644 app/lib/constants/saves.js delete mode 100644 app/lib/constants/skills.js delete mode 100644 app/lib/constants/statOrder.js delete mode 100644 app/lib/constants/subsManager.js delete mode 100644 app/lib/constants/xpTable.js delete mode 100644 app/lib/dice/roll.js delete mode 100644 app/lib/functions/characterExport.js delete mode 100644 app/lib/functions/characterJSON.js delete mode 100644 app/lib/functions/characterUtility.js delete mode 100644 app/lib/functions/computeCharacter.js delete mode 100644 app/lib/functions/permissions.js delete mode 100644 app/lib/functions/pointBuy.js delete mode 100644 app/lib/functions/preventLoop.js delete mode 100644 app/lib/functions/shareCharacter.js delete mode 100644 app/lib/functions/updatePolymerInputs.js delete mode 100644 app/lib/functions/vMixExport.js delete mode 100644 app/lib/memoize/memoize.js delete mode 100644 app/lib/methods/conditions.js delete mode 100644 app/lib/methods/removeMeFromReaders.js delete mode 100644 app/private/changeLogs/changeLogs.js delete mode 100644 app/server/lib/logRateError.js delete mode 100644 app/server/migrations/migrations.js delete mode 100644 app/tests/mocha/server/lib/characterUtility.js delete mode 100644 app/tests/mocha/server/model/character/character.js delete mode 100644 app/tests/mocha/server/model/character/effects.js delete mode 100644 app/tests/mocha/server/sampleServerTest.js diff --git a/app/config.vulcanize b/app/config.vulcanize deleted file mode 100644 index fbdd8a9c..00000000 --- a/app/config.vulcanize +++ /dev/null @@ -1,55 +0,0 @@ -{ - "polyfill": "/components/webcomponentsjs/webcomponents.min.js", - "useShadowDom": true, - "imports": [ - "/components/app-layout/app-layout.html", - "/components/app-layout/app-layout.html", - "/components/app-layout/app-scroll-effects/effects/waterfall.html", - "/components/app-layout/app-scroll-effects/effects/parallax-background.html", - "/components/app-layout/app-scroll-effects/effects/resize-title.html", - - "/components/iron-collapse/iron-collapse.html", - "/components/iron-icon/iron-icon.html", - "/components/iron-icons/av-icons.html", - "/components/iron-icons/editor-icons.html", - "/components/iron-icons/image-icons.html", - "/components/iron-icons/iron-icons.html", - "/components/iron-icons/social-icons.html", - "/components/iron-image/iron-image.html", - "/components/iron-pages/iron-pages.html", - "/components/iron-selector/iron-selector.html", - - "/components/neon-animation/neon-animation.html", - - "/components/paper-button/paper-button.html", - "/components/paper-swatch-picker/paper-swatch-picker.html", - "/components/paper-dialog/paper-dialog.html", - "/components/paper-dropdown-menu/paper-dropdown-menu.html", - "/components/paper-fab/paper-fab.html", - "/components/paper-icon-button/paper-icon-button.html", - "/components/paper-input/paper-input.html", - "/components/paper-input/paper-textarea.html", - "/components/paper-item/all-imports.html", - "/components/paper-listbox/paper-listbox.html", - "/components/paper-material/paper-material.html", - "/components/paper-menu-button/paper-menu-button.html", - "/components/paper-menu/paper-menu.html", - "/components/paper-radio-button/paper-radio-button.html", - "/components/paper-radio-group/paper-radio-group.html", - "/components/paper-ripple/paper-ripple.html", - "/components/paper-slider/paper-slider.html", - "/components/paper-spinner/paper-spinner.html", - "/components/paper-tabs/paper-tabs.html", - "/components/paper-toast/paper-toast.html", - "/components/paper-toggle-button/paper-toggle-button.html", - "/components/paper-tooltip/paper-tooltip.html", - - "/custom_components/dicecloud-icons/dicecloud-icons.html", - "/custom_components/dicecloud-selector/dicecloud-selector.html", - "/custom_components/dicecloud-wrapper/dicecloud-wrapper.html", - "/custom_components/paper-checkbox/paper-checkbox.html", - "/custom_components/paper-diff-slider/paper-diff-slider.html", - "/custom_components/paper-stepper/paper-stepper.html", - "/custom_components/app-theme.html" - ] -} diff --git a/app/server/lib/cron/deleteRemovedDocuments.js b/app/imports/api/parenting/deleteRemovedDocuments.js similarity index 95% rename from app/server/lib/cron/deleteRemovedDocuments.js rename to app/imports/api/parenting/deleteRemovedDocuments.js index cddd2a0e..31938ec3 100644 --- a/app/server/lib/cron/deleteRemovedDocuments.js +++ b/app/imports/api/parenting/deleteRemovedDocuments.js @@ -1,6 +1,6 @@ import creatureCollections from '/imports/api/creature/creatureCollections.js'; -Meteor.startup(() => { +if (Meteor.isServer) Meteor.startup(() => { /** * Deletes all soft removed documents that were removed more than 30 minutes ago * and were not restored diff --git a/app/server/lib/configuration/accountsMeldConfig.js b/app/imports/server/config/accountsMeldConfig.js similarity index 100% rename from app/server/lib/configuration/accountsMeldConfig.js rename to app/imports/server/config/accountsMeldConfig.js diff --git a/app/sharedMain.js b/app/imports/server/config/simpleSchemaDebug.js similarity index 79% rename from app/sharedMain.js rename to app/imports/server/config/simpleSchemaDebug.js index d8101acb..08f51eb8 100644 --- a/app/sharedMain.js +++ b/app/imports/server/config/simpleSchemaDebug.js @@ -2,5 +2,5 @@ import SimpleSchema from 'simpl-schema'; import schema from '/imports/api/schema.js'; if (Meteor.isDevelopment){ - //SimpleSchema.debug = true + SimpleSchema.debug = true } diff --git a/app/lib/constants/Schemas.js b/app/lib/constants/Schemas.js deleted file mode 100644 index c4599128..00000000 --- a/app/lib/constants/Schemas.js +++ /dev/null @@ -1 +0,0 @@ -Schemas = {}; diff --git a/app/lib/constants/abilities.js b/app/lib/constants/abilities.js deleted file mode 100644 index 085a0f13..00000000 --- a/app/lib/constants/abilities.js +++ /dev/null @@ -1,19 +0,0 @@ -abilities = [ - "strength", - "dexterity", - "constitution", - "intelligence", - "wisdom", - "charisma", -]; - -ABILITIES = abilities; - -ABILITY_MODS = [ - "strengthMod", - "dexterityMod", - "constitutionMod", - "intelligenceMod", - "wisdomMod", - "charismaMod", -]; diff --git a/app/lib/constants/appName.js b/app/lib/constants/appName.js deleted file mode 100644 index 5278dabe..00000000 --- a/app/lib/constants/appName.js +++ /dev/null @@ -1 +0,0 @@ -appName = "DiceCloud"; diff --git a/app/lib/constants/attributes.js b/app/lib/constants/attributes.js deleted file mode 100644 index 115e7f7d..00000000 --- a/app/lib/constants/attributes.js +++ /dev/null @@ -1,34 +0,0 @@ -ATTRIBUTES = [ - "strength", - "dexterity", - "constitution", - "intelligence", - "wisdom", - "charisma", - "hitPoints", - "tempHP", - "experience", - "proficiencyBonus", - "speed", - "armor", - "carryMultiplier", - "level1SpellSlots", - "level2SpellSlots", - "level3SpellSlots", - "level4SpellSlots", - "level5SpellSlots", - "level6SpellSlots", - "level7SpellSlots", - "level8SpellSlots", - "level9SpellSlots", - "ki", - "sorceryPoints", - "rages", - "superiorityDice", - "expertiseDice", - "rageDamage", - "d6HitDice", - "d8HitDice", - "d10HitDice", - "d12HitDice", -]; diff --git a/app/lib/constants/characterAssetAllowDeny.js b/app/lib/constants/characterAssetAllowDeny.js deleted file mode 100644 index 65730cfb..00000000 --- a/app/lib/constants/characterAssetAllowDeny.js +++ /dev/null @@ -1,63 +0,0 @@ -Meteor.methods({ - canWriteCharacter: function(charId) { - var userId = this.userId; - var char = Characters.findOne( - charId, - {fields: {owner: 1, writers: 1}} - ); - if (!char) return true; - return (userId && char.owner === userId || _.contains(char.writers, userId)); - }, -}); - -CHARACTER_SUBSCHEMA_ALLOW = { - // the user must be logged in, and the user must be a writer of the character - insert: function(userId, doc) { - var char = Characters.findOne( - doc.charId, - {fields: {owner: 1, writers: 1}} - ); - return (userId && char.owner === userId || _.contains(char.writers, userId)); - }, - update: function(userId, doc, fields, modifier) { - var char = Characters.findOne( - doc.charId, - {fields: {owner: 1, writers: 1}} - ); - return (userId && char.owner === userId || _.contains(char.writers, userId)); - }, - remove: function(userId, doc) { - var char = Characters.findOne( - doc.charId, - {fields: {owner: 1, writers: 1}} - ); - if (!char) return true; - return userId && char.owner === userId || _.contains(char.writers, userId); - }, - fetch: ["charId"], -}; - -CHARACTER_SUBSCHEMA_DENY = { - update: function(userId, doc, fields, modifier) { - if (modifier && modifier.$set && modifier.$set.charId){ - var id1 = doc.charId; - var char1 = Characters.findOne( - id1, - {fields: {owner: 1, writers: 1}} - ) || {}; - var char1Allowed = ( - userId && char1.owner === userId || _.contains(char1.writers, userId) - ); - var id2 = modifier.$set.charId; - var char2 = Characters.findOne( - id2, - {fields: {owner: 1, writers: 1}} - ) || {}; - var char2Allowed = ( - userId && char1.owner === userId || _.contains(char1.writers, userId) - ); - return (!char1Allowed || !char2Allowed); - } - }, - fetch: ["charId"], -}; diff --git a/app/lib/constants/colorOptions.js b/app/lib/constants/colorOptions.js deleted file mode 100644 index e6937a44..00000000 --- a/app/lib/constants/colorOptions.js +++ /dev/null @@ -1,51 +0,0 @@ -colorOptions = [ - {key: "a", className: "red", whiteText: true, color: "#F44336"}, - {key: "b", className: "pink", whiteText: true, color: "#E91E63"}, - {key: "c", className: "purple", whiteText: true, color: "#9C27B0"}, - {key: "d", className: "deep-purple", whiteText: true, color: "#673AB7"}, - {key: "e", className: "indigo", whiteText: true, color: "#3F51B5"}, - {key: "f", className: "blue", whiteText: true, color: "#2196F3"}, - {key: "g", className: "light-blue", whiteText: true, color: "#03A9F4"}, - {key: "h", className: "cyan", whiteText: true, color: "#00BCD4"}, - {key: "i", className: "teal", whiteText: true, color: "#009688"}, - {key: "j", className: "green", whiteText: true, color: "#4CAF50"}, - {key: "k", className: "light-green", whiteText: true, color: "#8BC34A"}, - {key: "l", className: "lime", whiteText: false, color: "#CDDC39"}, - {key: "m", className: "yellow", whiteText: false, color: "#FFEB3B"}, - {key: "n", className: "amber", whiteText: false, color: "#FFC107"}, - {key: "o", className: "orange", whiteText: false, color: "#FF9800"}, - {key: "p", className: "deep-orange", whiteText: true, color: "#FF5722"}, - {key: "q", className: "grey", whiteText: true, color: "#9E9E9E"}, //spec says no white text - {key: "r", className: "blue-grey", whiteText: true, color: "#607D8B"}, - {key: "s", className: "brown", whiteText: true, color: "#795548"}, - {key: "t", className: "black", whiteText: true, color: "#000000"}, -]; - -var colorOptionMap = _.pluck(colorOptions, "key"); - -getColorClass = function(key){ - if (!key){ - return "grey white-text"; - } - var index = _.indexOf(colorOptionMap, key); - if (index == -1){ - return "grey white-text"; - } - var option = colorOptions[index]; - var colorClass = option.className; - if (option.whiteText){ - colorClass += " white-text"; - } - return colorClass; -}; - -getHexColor = function(key) { - if (!key){ - return "#000"; - } - var index = _.indexOf(colorOptionMap, key); - if (index === -1){ - return "#000"; - } - return colorOptions[index].color; -}; diff --git a/app/lib/constants/damageDice.js b/app/lib/constants/damageDice.js deleted file mode 100644 index b102b369..00000000 --- a/app/lib/constants/damageDice.js +++ /dev/null @@ -1,9 +0,0 @@ -DAMAGE_DICE = [ - "1", - "1d4", - "1d6", - "1d8", - "1d10", - "1d12", - "2d6", -]; diff --git a/app/lib/constants/damageTypes.js b/app/lib/constants/damageTypes.js deleted file mode 100644 index 024fd64d..00000000 --- a/app/lib/constants/damageTypes.js +++ /dev/null @@ -1,31 +0,0 @@ -DAMAGE_TYPES = { - "acid": {name: "Acid"}, - "bludgeoning": {name: "Bludgeoning"}, - "cold": {name: "Cold"}, - "fire": {name: "Fire"}, - "force": {name: "Force"}, - "lightning": {name: "Lightning"}, - "necrotic": {name: "Necrotic"}, - "piercing": {name: "Piercing"}, - "poison": {name: "Poison"}, - "psychic": {name: "Psychic"}, - "radiant": {name: "Radiant"}, - "slashing": {name: "Slashing"}, - "thunder": {name: "Thunder"}, -}; - -DAMAGE_MULTIPLIERS = [ - "acidMultiplier", - "bludgeoningMultiplier", - "coldMultiplier", - "fireMultiplier", - "forceMultiplier", - "lightningMultiplier", - "necroticMultiplier", - "piercingMultiplier", - "poisonMultiplier", - "psychicMultiplier", - "radiantMultiplier", - "slashingMultiplier", - "thunderMultiplier", -]; diff --git a/app/lib/constants/saves.js b/app/lib/constants/saves.js deleted file mode 100644 index ba0d2618..00000000 --- a/app/lib/constants/saves.js +++ /dev/null @@ -1,8 +0,0 @@ -SAVES = [ - "strengthSave", - "dexteritySave", - "constitutionSave", - "intelligenceSave", - "wisdomSave", - "charismaSave", -]; diff --git a/app/lib/constants/skills.js b/app/lib/constants/skills.js deleted file mode 100644 index 0a47069c..00000000 --- a/app/lib/constants/skills.js +++ /dev/null @@ -1,50 +0,0 @@ -SKILLS = [ - "acrobatics", - "animalHandling", - "arcana", - "athletics", - "deception", - "history", - "insight", - "intimidation", - "investigation", - "medicine", - "nature", - "perception", - "performance", - "persuasion", - "religion", - "sleightOfHand", - "stealth", - "survival", - "initiative", -]; - -ALL_SKILLS = [ - "strengthSave", - "dexteritySave", - "constitutionSave", - "intelligenceSave", - "wisdomSave", - "charismaSave", - "acrobatics", - "animalHandling", - "arcana", - "athletics", - "deception", - "history", - "insight", - "intimidation", - "investigation", - "medicine", - "nature", - "perception", - "performance", - "persuasion", - "religion", - "sleightOfHand", - "stealth", - "survival", - "initiative", - "dexterityArmor", -]; diff --git a/app/lib/constants/statOrder.js b/app/lib/constants/statOrder.js deleted file mode 100644 index 06ed2b72..00000000 --- a/app/lib/constants/statOrder.js +++ /dev/null @@ -1,82 +0,0 @@ -var statsInOrder = [ - "strength", - "dexterity", - "constitution", - "intelligence", - "wisdom", - "charisma", - - "strengthSave", - "dexteritySave", - "constitutionSave", - "intelligenceSave", - "wisdomSave", - "charismaSave", - - "acrobatics", - "animalHandling", - "arcana", - "athletics", - "deception", - "history", - "insight", - "intimidation", - "investigation", - "medicine", - "nature", - "perception", - "performance", - "persuasion", - "religion", - "sleightOfHand", - "stealth", - "survival", - "initiative", - - "hitPoints", - "armor", - "dexterityArmor", - "speed", - "proficiencyBonus", - "ki", - "sorceryPoints", - "rages", - "rageDamage", - "expertiseDice", - "superiorityDice", - "carryMultiplier", - - "level1SpellSlots", - "level2SpellSlots", - "level3SpellSlots", - "level4SpellSlots", - "level5SpellSlots", - "level6SpellSlots", - "level7SpellSlots", - "level8SpellSlots", - "level9SpellSlots", - - "d6HitDice", - "d8HitDice", - "d10HitDice", - "d12HitDice", - - "acidMultiplier", - "bludgeoningMultiplier", - "coldMultiplier", - "fireMultiplier", - "forceMultiplier", - "lightningMultiplier", - "necroticMultiplier", - "piercingMultiplier", - "poisonMultiplier", - "psychicMultiplier", - "radiantMultiplier", - "slashingMultiplier", - "thunderMultiplier", -]; - -statOrder = {}; -_.each(statsInOrder, function(element, index){ - statOrder[element] = index; -}); \ No newline at end of file diff --git a/app/lib/constants/subsManager.js b/app/lib/constants/subsManager.js deleted file mode 100644 index c8593307..00000000 --- a/app/lib/constants/subsManager.js +++ /dev/null @@ -1,6 +0,0 @@ -subsManager = new SubsManager({ - // maximum number of cache subscriptions - cacheLimit: 5, - // any subscription will be expire after 1 minute, if it's not subscribed again - expireIn: 1, -}); diff --git a/app/lib/constants/xpTable.js b/app/lib/constants/xpTable.js deleted file mode 100644 index 0375717a..00000000 --- a/app/lib/constants/xpTable.js +++ /dev/null @@ -1,21 +0,0 @@ -XP_TABLE = [0, - 300, - 900, - 2700, - 6500, - 14000, - 23000, - 34000, - 48000, - 64000, - 85000, - 100000, - 120000, - 140000, - 165000, - 195000, - 225000, - 265000, - 305000, - 355000, - ]; diff --git a/app/lib/dice/roll.js b/app/lib/dice/roll.js deleted file mode 100644 index fd233b92..00000000 --- a/app/lib/dice/roll.js +++ /dev/null @@ -1,21 +0,0 @@ -roll = function(n, d){ - var result = []; - if (!isNaN(n)){ - //if only provided 1 argument, it is the dice to roll - if (d === undefined){ - d = n; - n = 1; - } - //hard limit the number of dice rolled - if (n > 500){ - console.warn(n + " > 500, cannot lift that many dice to roll them"); - return; - } - for (var i = 0; i < n; i++){ - var roll = Math.floor(Random.fraction() * d + 1); - result.push(roll); - } - return result; - } - return result; -}; diff --git a/app/lib/functions/characterExport.js b/app/lib/functions/characterExport.js deleted file mode 100644 index fe56c6ae..00000000 --- a/app/lib/functions/characterExport.js +++ /dev/null @@ -1,258 +0,0 @@ -characterExport = function(charId){ - var { - character, classes, effects, proficiencies, - } = getCharacterForComputation(charId); - var char = character; - computedCharacter = computeCharacter({ - character, classes, effects, proficiencies, - }); - if (!char) { - return { - error: charId + " character not found" - }; - } - if (char.settings.viewPermission !== "public" && Meteor.isServer){ - return { - error: charId + " character is not viewable to anyone with link" - }; - } - var baseValue = function(attributeName){ - var attribute = computedCharacter[attributeName]; - return attribute && attribute.value; - }; - var attributeValue = function(attributeName){ - var base = baseValue(attributeName); - var adjustment = char[attributeName] && char[attributeName].adjustment; - return base + adjustment; - }; - var abilityMod = function(attributeName){ - return signedString(getMod(attributeValue(attributeName))); - }; - var skillMod = function(skillName){ - return signedString(baseValue(skillName)); - }; - var proficiency = function(skillName){ - var skill = computedCharacter[skillName]; - return skill && skill.proficiency; - }; - var passiveSkill = function(skillName){ - var attribute = computedCharacter[skillName]; - if (!attribute) return; - return 10 + baseValue(skillName) + attribute.passiveAdd; - }; - var experience = function(){ - var xp = 0; - Experiences.find( - {charId: charId}, - {fields: {value: 1}} - ).forEach(function(e){ - xp += e.value; - }); - return xp; - }; - var getClasses = function(){ - return _.map(classes, c => `${c.name} ${c.level}`).join(", "); - }; - var getHitDiceString = function(){ - var d6 = baseValue("d6HitDice"); - var d8 = baseValue("d8HitDice"); - var d10 = baseValue("d10HitDice"); - var d12 = baseValue("d12HitDice"); - var con = abilityMod("constitution"); - var string = "" + - (d6 ? `${d6}d6 + ` : "") + - (d8 ? `${d8}d8 + ` : "") + - (d10 ? `${d10}d10 + ` : "") + - (d12 ? `${d12}d12 + ` : "") + - con; - return string; - } - var getSkills = function(charId){ - var allSkills = [ - {name: "acrobatics", attribute: "dexterity"}, - {name: "animalHandling", attribute: "wisdom"}, - {name: "arcana", attribute: "intelligence"}, - {name: "athletics", attribute: "strength"}, - {name: "deception", attribute: "charisma"}, - {name: "history", attribute: "intelligence"}, - {name: "insight", attribute: "wisdom"}, - {name: "intimidation", attribute: "charisma"}, - {name: "investigation", attribute: "intelligence"}, - {name: "medicine", attribute: "wisdom"}, - {name: "nature", attribute: "intelligence"}, - {name: "perception", attribute: "wisdom"}, - {name: "performance", attribute: "charisma"}, - {name: "persuasion", attribute: "charisma"}, - {name: "religion", attribute: "intelligence"}, - {name: "sleightOfHand", attribute: "dexterity"}, - {name: "stealth", attribute: "dexterity"}, - {name: "survival", attribute: "wisdom"}, - ]; - var skills = {}; - _.each(allSkills, skill => { - var value = skillMod(skill.name); - var prof = proficiency(skill.name); - var name = skill.name.charAt(0).toUpperCase() + skill.name.slice(1); - skills[name] = value; - skills[name + "Proficiency"] = prof; - }); - return skills; - }; - var character = { - "Id": char._id, - "Name": char.name, - "Source": "DiceCloud", - "Alignment": char.alignment || "", - "Gender": char.gender || "", - "Race": char.race || "", - "Level": _.reduce(classes, (memo, cls) => memo + cls.level, 0), - "Experience": experience(), - "Class": getClasses(charId), - "HPBase": baseValue("hitPoints"), - "HPValue": attributeValue("hitPoints"), - "HitDice": getHitDiceString(charId) || "", - "AC": attributeValue("armor"), - "Initiative": skillMod("initiative"), - "Speed": attributeValue("speed"), - "ProficiencyBonus": attributeValue("proficiencyBonus"), - "passivePerception": passiveSkill("perception"), - - "Languages": getLanguages(charId), - "Description": char.description || "", - "Backstory": char.backstory || "", - "Personality": char.personality || "" , - "Bonds": char.bonds || "", - "Ideals": char.ideals || "", - "Flaws": char.flaws || "", - "PictureURL": char.picture || "", - - "Strength": attributeValue("strength"), - "Dexterity": attributeValue("dexterity"), - "Constitution": attributeValue("constitution"), - "intelligence": attributeValue("intelligence"), - "Wisdom": attributeValue("wisdom"), - "Charisma": attributeValue("charisma"), - - "StrengthMod": abilityMod("strength"), - "DexterityMod": abilityMod("dexterity"), - "ConstitutionMod": abilityMod("constitution"), - "intelligenceMod": abilityMod("intelligence"), - "WisdomMod": abilityMod("wisdom"), - "CharismaMod": abilityMod("charisma"), - - //"DamageVulnerabilities": damageMods.vulnerabilities, - //"DamageResistances": damageMods.resistances, - //"DamageImmunities": damageMods.immunities, - - "StrengthSave": skillMod("strengthSave"), - "StrengthSaveProficiency": proficiency("strengthSave"), - "DexteritySave": skillMod("dexteritySave"), - "DexteritySaveProficiency": proficiency("dexteritySave"), - "ConstitutionSave": skillMod("constitutionSave"), - "ConstitutionSaveProficiency": proficiency("constitutionSave"), - "intelligenceSave": skillMod("intelligenceSave"), - "intelligenceSaveProficiency": proficiency("intelligenceSave"), - "WisdomSave": skillMod("wisdomSave"), - "WisdomSaveProficiency": proficiency("wisdomSave"), - "CharismaSave": skillMod("charismaSave"), - "CharismaSaveProficiency": proficiency("charismaSave"), - - "Level1SpellSlots": attributeValue("level1SpellSlots"), - "Level2SpellSlots": attributeValue("level2SpellSlots"), - "Level3SpellSlots": attributeValue("level3SpellSlots"), - "Level4SpellSlots": attributeValue("level4SpellSlots"), - "Level5SpellSlots": attributeValue("level5SpellSlots"), - "Level6SpellSlots": attributeValue("level6SpellSlots"), - "Level7SpellSlots": attributeValue("level7SpellSlots"), - "Level8SpellSlots": attributeValue("level8SpellSlots"), - "Level9SpellSlots": attributeValue("level9SpellSlots"), - "Ki": attributeValue("ki"), - "Rages": attributeValue("rages"), - "RageDamage": attributeValue("rageDamage"), - "SorceryPoints": attributeValue("sorceryPoints"), - - "DeathSavePasses": char.deathSave.pass, - "DeathSaveFails": char.deathSave.fail, - "DeathSaveStable": char.deathSave.stable, - }; - _.extend(character, getSkills(charId)); - _.extend(character, getAttacks(charId)); - return character; -} - -var getArmorString = function(charId){ - var bases = Effects.find({ - charId: charId, - stat: "armor", - operation: "base", - enabled: true, - }).map(e => ({ - ame: e.name, - value: evaluateEffect(charId, e), - })); - var base = bases.length && _.max(bases, b => b.value).name || ""; - var effects = Effects.find({ - charId: charId, - stat: "armor", - operation: {$ne: "base"}, - enabled: true, - }).map(e => e.name); - var strings = base ? [base] : []; - strings = strings.concat(effects); - return strings.join(", "); -} -/* -var getDamageMods = function(charId){ - // jscs:disable maximumLineLength - var multipliers = [ - {name: "Acid", value: Characters.calculate.attributeValue(charId, "acidMultiplier")}, - {name: "Bludgeoning", value: Characters.calculate.attributeValue(charId, "bludgeoningMultiplier")}, - {name: "Cold", value: Characters.calculate.attributeValue(charId, "coldMultiplier")}, - {name: "Fire", value: Characters.calculate.attributeValue(charId, "fireMultiplier")}, - {name: "Force", value: Characters.calculate.attributeValue(charId, "forceMultiplier")}, - {name: "Lightning", value: Characters.calculate.attributeValue(charId, "lightningMultiplier")}, - {name: "Necrotic", value: Characters.calculate.attributeValue(charId, "necroticMultiplier")}, - {name: "Piercing", value: Characters.calculate.attributeValue(charId, "piercingMultiplier")}, - {name: "Poison", value: Characters.calculate.attributeValue(charId, "poisonMultiplier")}, - {name: "Psychic", value: Characters.calculate.attributeValue(charId, "psychicMultiplier")}, - {name: "Radiant", value: Characters.calculate.attributeValue(charId, "radiantMultiplier")}, - {name: "Slashing", value: Characters.calculate.attributeValue(charId, "slashingMultiplier")}, - {name: "Thunder", value: Characters.calculate.attributeValue(charId, "thunderMultiplier")}, - ]; - // jscs:enable maximumLineLength - multipliers = _.groupBy(multipliers, "value"); - var names = o => o.name; - return { - "immunities": _.map(multipliers["0"], names).join(", "), - "resistances": _.map(multipliers["0.5"], names).join(", "), - "vulnerabilities": _.map(multipliers["2"], names).join(", "), - }; -} -*/ - -var getLanguages = function(charId){ - return Proficiencies.find({ - charId, - enabled: true, - type: "language", - }).map(l => l.name).join(", "); -}; - -var getAttacks = function(charId){ - var attacks = {}; - var i = 1; - Attacks.find( - {charId, enabled: true}, - {sort: {color: 1, name: 1}} - ).forEach(a => { - attacks[`Attack${i++}`] = a.name + - ` +${evaluate(charId, a.attackBonus)} to hit, ` + - `${evaluateString(charId, a.damage)} ${a.damageType} damage, ` + - `${a.details}`; - }); - return attacks; -}; - -var signedString = function(number) { - return number >= 0 ? "+" + number : "" + number; -}; diff --git a/app/lib/functions/characterJSON.js b/app/lib/functions/characterJSON.js deleted file mode 100644 index 861bb796..00000000 --- a/app/lib/functions/characterJSON.js +++ /dev/null @@ -1,17 +0,0 @@ -JSONExport = function(charId) { - var character = { - "attacks": Attacks.find({charId: charId}).fetch(), - "characters": Characters.find({_id: charId}).fetch(), - "classes": Classes.find({charId: charId}).fetch(), - "containers": Containers.find({charId: charId}).fetch(), - "effects": Effects.find({charId: charId}).fetch(), - "experience": Experiences.find({charId: charId}).fetch(), - "features": Features.find({charId: charId}).fetch(), - "items": Items.find({charId: charId}).fetch(), - "notes": Notes.find({charId: charId}).fetch(), - "proficiencies": Proficiencies.find({charId: charId}).fetch(), - "spellLists": SpellLists.find({charId: charId}).fetch(), - "spells": Spells.find({charId: charId}).fetch() - }; - return JSON.stringify(character); -} diff --git a/app/lib/functions/characterUtility.js b/app/lib/functions/characterUtility.js deleted file mode 100644 index 44f4f4c4..00000000 --- a/app/lib/functions/characterUtility.js +++ /dev/null @@ -1,7 +0,0 @@ -getMod = function(score){ - return Math.floor((score - 10) / 2); -}; - -signedString = function(number){ - return number >= 0 ? "+" + number : "" + number; -}; diff --git a/app/lib/functions/computeCharacter.js b/app/lib/functions/computeCharacter.js deleted file mode 100644 index 535ed9cd..00000000 --- a/app/lib/functions/computeCharacter.js +++ /dev/null @@ -1,224 +0,0 @@ -getCharacterForComputation = function(charId){ - const character = Characters.findOne(charId); - const classes = Classes.find({charId}).fetch(); - const effects = Effects.find({charId, enabled: true}).fetch(); - const proficiencies = Proficiencies.find({ - charId, - enabled: true, - type: {$in: ["skill", "save"]}, - }).fetch(); - return {character, classes, effects, proficiencies}; -} - -computeCharacter = function({character, classes, effects, proficiencies}){ - var charId = character._id; - let computedClasses = computeCharacterClasses(charId, classes); - let changed = false; - computedCharacter = {}; - let i; - for (i = 0; i < 15; i++){ - [computedCharacter, changed] = compute({ - classes: computedClasses, - oldChar: computedCharacter, - charId, - character, - effects, - proficiencies, - }); - if (!changed) break; - } - return computedCharacter; -}; - -var ensureCharacterExists = (character) => { - if (!character) { - throw new Meteor.Error("Character doesn't exist", - "You can't recompute a character that doesn't exist"); - } -}; - -var ensureWritePermissions = (character, userId) => { - if ( - userId && - userId !== character.owner && - !_.contains(character.writers, userId) - ){ - throw new Meteor.Error("Character write denied", - "You don't have permission to recompute this character"); - } -}; - -var computeCharacterClasses = function(charId, classes){ - let computedClasses = {}; - _.each(classes, (cls) => { - if (computedClasses[cls.name]){ - computedClasses[cls.name].level += cls.level; - } else { - computedClasses[cls.name] = cls; - } - }); - return computedClasses; -} - -var compute = function({ - charId, oldChar, character, classes, effects, proficiencies, -}){ - let newChar = {}; - _.each(effects, (effect, index) => { - if (!effect.stat || effect.operation === "conditional") return; - if (!newChar[effect.stat]) newChar[effect.stat] = defaultStat(); - let value = effect.calculation ? - computeEffect(effect.calculation, oldChar, classes) : - effect.value || 0; - let stat = newChar[effect.stat]; - if (!_.isNumber(value)) return; - switch (effect.operation) { - case "base": - if (value > stat.base) stat.base = value; - break; - case "proficiency": - if (value > stat.proficiency) stat.proficiency = value; - break; - case "add": - stat.add += value; - break; - case "mul": - stat.mul *= value; - break; - case "min": - if (value > stat.min) stat.min = value; - break; - case "max": - if (value < stat.max) stat.max = value; - break; - case "advantage": - stat.advantage++; - break; - case "disadvantage": - stat.disadvantage++; - break; - case "passiveAdd": - stat.passiveAdd += value; - break; - case "fail": - stat.fail = true; - break; - } - }); - _.each(proficiencies, proficiency => { - if (!proficiency.name) return; - if (!newChar[proficiency.name]) newChar[proficiency.name] = defaultStat(); - let stat = newChar[proficiency.name]; - let value = proficiency.value; - if (value > stat.proficiency) stat.proficiency = value; - }); - let changed = false; - _.each(ATTRIBUTES, function(statName) { - if (!newChar[statName]) newChar[statName] = defaultStat(); - let stat = newChar[statName]; - stat.value = (stat.base + stat.add) * stat.mul; - if (stat.value < stat.min) stat.value = stat.min; - if (stat.value > stat.max) stat.value = stat.max; - if (!_.isEqual(stat.value, oldChar[statName] && oldChar[statName].value)){ - changed = true; - } - }); - _.each(ALL_SKILLS, function(statName) { - if (!newChar[statName]) newChar[statName] = defaultStat(); - let stat = newChar[statName]; - stat.value = characterAbilityMod( - oldChar, character[statName] && character[statName].ability - ); - stat.value += stat.base + stat.add; - stat.value += stat.proficiency * - characterFieldValue(oldChar, "proficiencyBonus"); - stat.value *= stat.mul; - if (stat.value < stat.min) stat.value = stat.min; - if (stat.value > stat.max) stat.value = stat.max; - if (!_.isEqual(stat.value, oldChar[statName] && oldChar[statName].value)){ - changed = true; - } - }); - return [newChar, changed]; -}; - -var defaultStat = function(){ - return { - base: 0, - proficiency: 0, - add: 0, - mul: 1, - min: Number.NEGATIVE_INFINITY, - max: Number.POSITIVE_INFINITY, - advantage: 0, - disadvantage: 0, - passiveAdd: 0, - fail: false, - } -} - -var computeEffect = function(string, character, classes){ - if (!string) return string; - string = string.replace(/\b[a-z][\w]+/gi, function(sub){ - //fields - if (character[sub]){ - return characterFieldValue(character, sub); - } - //ability modifiers - if (_.contains(ABILITY_MODS, sub)){ - var slice = sub.slice(0, -3); - return getMod( - character[slice] ? characterFieldValue(character, slice) : 0 - ); - } - //class levels - if (/\w+levels?\b/gi.test(sub)){ - //strip out "level" - var className = sub.replace(/levels?\b/gi, ""); - return characterClassLevel(classes, className) - } - //character level - if (sub.toUpperCase() === "LEVEL"){ - return characterTotalLevel(classes); - } - // exclude math functions - if (math[sub]){ - return sub; - } - return 0; - }); - try { - var result = math.eval(string); - return result; - } catch (e){ - return string; - } -}; - -var characterFieldValue = function(character, field){ - if (_.isNumber(character[field] && character[field].value)){ - return character[field].value; - } else { - return field; - } -}; - -var characterClassLevel = function(classes, className){ - if (_.isNumber(classes[className] && classes[className].level)){ - return classes[className].level; - } else { - return className; - } -}; - -var characterTotalLevel = function(classes){ - return _.reduce(classes, (memo, cls) => memo + cls.level, 0); -}; - -var characterAbilityMod = function(character, abilityName){ - if (_.isNumber(character[abilityName] && character[abilityName].value)){ - return getMod(character[abilityName].value); - } else { - return 0; - } -}; diff --git a/app/lib/functions/permissions.js b/app/lib/functions/permissions.js deleted file mode 100644 index 8f160297..00000000 --- a/app/lib/functions/permissions.js +++ /dev/null @@ -1,19 +0,0 @@ -canEditCharacter = function(charId, userId){ - userId = userId || Meteor.userId(); - var char = Characters.findOne(charId, {fields: {owner: 1, writers: 1}}); - if (!char) return true; - return (userId === char.owner || _.contains(char.writers, userId)); -}; - -canViewCharacter = function(charId, userId){ - userId = userId || Meteor.userId(); - var char = Characters.findOne( - charId, - {fields: {owner: 1, writers: 1, readers: 1, "settings.viewPermission": 1}} - ); - if (!char) return true; - return userId === char.owner || - char.settings.viewPermission === "public" || - _.contains(char.writers, userId) || - _.contains(char.readers, userId); -}; diff --git a/app/lib/functions/pointBuy.js b/app/lib/functions/pointBuy.js deleted file mode 100644 index 92e26a62..00000000 --- a/app/lib/functions/pointBuy.js +++ /dev/null @@ -1,66 +0,0 @@ -pointBuyCost = { - "8": 0, - "9": 1, - "10": 2, - "11": 3, - "12": 4, - "13": 5, - "14": 7, - "15": 9, -}; - -var getPointBuyEffect = function(stat, value, pointsUsed, charId){ - return { - modifier:{ - charId: charId, - stat: stat, - name: pointsUsed + " Point Buy", - operation: "base", - value: value, - parent: {collection: "Characters", id: charId}, - enabled: true, - }, - selector:{ - charId: charId, - stat: stat, - operation: "base", - }, - }; -}; - -var checkPermission = function(userId, charId){ - var char = Characters.findOne(charId, {fields: {owner: 1, writers: 1}}); - if (!char) - throw new Meteor.Error("Access Denied", - "Character " + charId + " does not exist"); - if (!userId) - throw new Meteor.Error("Access Denied", - "No UserId set when trying to update character asset."); - if (char.owner !== userId && !_.contains(char.writers, userId)) - throw new Meteor.Error("Access Denied", - "Not permitted to update assets of this character."); - return true; -}; - -Meteor.methods({ - pointBuyAbilityScores: function(charId, points){ - check(points, { - strength: Number, - dexterity: Number, - constitution: Number, - intelligence: Number, - wisdom: Number, - charisma: Number, - }); - check(charId, String); - checkPermission(this.userId, charId); - var pointsUsed = 0; - _.each(points, function(value, key){ - pointsUsed += pointBuyCost[value]; - }); - _.each(points, function(value, ability){ - var pbEffect = getPointBuyEffect(ability, value, pointsUsed, charId); - Effects.upsert(pbEffect.selector, pbEffect.modifier); - }); - } -}); diff --git a/app/lib/functions/preventLoop.js b/app/lib/functions/preventLoop.js deleted file mode 100644 index 12deea1f..00000000 --- a/app/lib/functions/preventLoop.js +++ /dev/null @@ -1,35 +0,0 @@ -preventLoop = function(inputFunction){ - var self = this; - if (!_.isFunction(inputFunction)){ - throw new Meteor.Error( - "Not a function", - "preventLoop can only take a function as an argument" - ); - } - //store a private array of arguments we have been given without returning - //if we try to visit the same argument twice before resolving its value - //we are in a dependency loop and need to GTFO - var visitedArgs = []; - return function(){ - var result; - var hash = _.reduce(arguments, function(memo, arg) { - return memo + arg; - }, ""); - //we're still evaluating this attribute, must be in a loop - if (_.contains(visitedArgs, hash)) { - console.warn("dependency loop detected"); - return NaN; - } else { - //push this hash to the list of visited hashes - //we can't visit it again unless it returns first - visitedArgs.push(hash); - } - try { - result = inputFunction.apply(this, arguments); - } finally{ - //this hash returns or fails, pull it from the array - visitedArgs = _.without(visitedArgs, hash); - } - return result; - }; -}; diff --git a/app/lib/functions/shareCharacter.js b/app/lib/functions/shareCharacter.js deleted file mode 100644 index dcf94447..00000000 --- a/app/lib/functions/shareCharacter.js +++ /dev/null @@ -1,14 +0,0 @@ -Meteor.methods({ - "getUserId": function(username){ - if (!username) return; - regex = new RegExp("^" + username + "$", "i") - var user = Meteor.users.findOne( - {$or: [ - {username: username}, - {"emails.address": regex}, - {"services.google.email": regex}, - ]} - ); - return user && user._id; - } -}); diff --git a/app/lib/functions/updatePolymerInputs.js b/app/lib/functions/updatePolymerInputs.js deleted file mode 100644 index dfd44923..00000000 --- a/app/lib/functions/updatePolymerInputs.js +++ /dev/null @@ -1,14 +0,0 @@ -updatePolymerInputs = function(self){ - _.defer(function(){ - //update all autogrows after they've been filled - var pata = self.$("paper-autogrow-textarea"); - pata.each(function(index, el){ - el.update($(el).children().get(0)); - }); - //update all input fields as well - var input = self.$("paper-input"); - input.each(function(index, el){ - el.valueChanged(); - }); - }); -}; diff --git a/app/lib/functions/vMixExport.js b/app/lib/functions/vMixExport.js deleted file mode 100644 index b2a95fd2..00000000 --- a/app/lib/functions/vMixExport.js +++ /dev/null @@ -1,9 +0,0 @@ -vMixCharacter = function(charId){ - return JSON.stringify([characterExport(charId)], null, 2); -}; - -vMixParty = function(partyId){ - var party = Parties.findOne(partyId); - var chars = _.map(party.characters, charId => characterExport(charId)); - return JSON.stringify(chars, null, 2); -}; diff --git a/app/lib/memoize/memoize.js b/app/lib/memoize/memoize.js deleted file mode 100644 index 89947749..00000000 --- a/app/lib/memoize/memoize.js +++ /dev/null @@ -1,60 +0,0 @@ -Tracker.memoize = function(func, hasher){ - var memoize = function(key) { - var cache = memoize.cache; - var address = "" + (hasher ? hasher.apply(this, arguments) : key); - if (!_.has(cache, address)) { - cache[address] = new CacheObject(func, address, arguments, cache, this); - } - return cache[address].get(); - }; - memoize.cache = {}; - return memoize; -}; - -function CacheObject(func, address, args, cache, context){ - var self = this; - self.currentValue = null; - self.dep = new Tracker.Dependency(); - self.numRun = 0; - - //spawn a new autorun that keeps the value up-to-date - Tracker.nonreactive(function() { - Tracker.autorun(function(computation) { - //if this isn't the first run and nobody is listening, - //delete itself from cache and stop the computation - if (!computation.firstRun && !self.dep.hasDependents()){ - computation.stop(); - delete cache[address]; - return; - } - //if we haven't run this before this flush, reset the counter after the flush - if (self.numRun === 0){ - Tracker.afterFlush(function(){ - self.numRun = 0; - }); - } - self.numRun++; - //call the expensive function - //even if we don't use its value, we need to track its dependencies - var newValue = func.apply(context, args); - //prevent dependency loops, the memoized function shouldn't re-run - //more than 10 times per flush - if (self.numRun > 10){ - newValue = NaN; - if (_.isNaN(self.currentValue)) return; - } - //if the value changed, store the new value - if (self.currentValue !== newValue){ - self.currentValue = newValue; - //tell the dependents that we've changed - self.dep.changed(); - } - }); - }); -} - -CacheObject.prototype.get = function() { - //if there is an active computation, track dependents - if (Tracker.active) this.dep.depend(); - return this.currentValue; -}; diff --git a/app/lib/methods/conditions.js b/app/lib/methods/conditions.js deleted file mode 100644 index e3460087..00000000 --- a/app/lib/methods/conditions.js +++ /dev/null @@ -1,467 +0,0 @@ -var checkWritePermission = function(charId) { - if (!Meteor.call("canWriteCharacter", charId)){ - throw new Meteor.Error( - "Access denied", - "You do not have permission to edit the assets of this character" - ); - } -}; - -var getCondition = function(conditionName) { - //get condition from constant - var condition = CONDITIONS[conditionName]; - //check that condition exists - if (!condition) { - throw new Meteor.Error( - "Invalid condition", - conditionName + " is not a known condition" - ); - } - return condition; -}; - -Meteor.methods({ - giveCondition: function(charId, conditionName) { - checkWritePermission(charId); - var condition = getCondition(conditionName); - //create the buff - var buff = _.extend( - { - charId: charId, - }, - condition.buff - ); - - //make sure the character doesn't already have the buff - var existingBuffs = Conditions.find(_.clone(buff)).count(); - if (existingBuffs) return; - //remove exclusive conditions - _.each(condition.exclusiveConditions, function(exCond) { - Meteor.call("removeCondition", charId, exCond); - }); - //insert the buff - var buffId = Conditions.insert(buff); - //extend and insert each effect - _.each(condition.effects, function(effect) { - var newEffect = { - stat: effect.stat, - operation: effect.operation, - calculation: effect.calculation, - value: effect.value, - charId: charId, - parent: { - id: buffId, - collection: "Conditions", - }, - enabled: true, - }; - //we know these effects are right, - //skip after hooks, skip validation - Effects.direct.insert( - newEffect, - { - validate: false, - filter: false, - autoConvert: false, - removeEmptyStrings: false, - } - ); - }); - //recurse for subConditions - _.each(condition.subConditions, function(subCondition) { - Meteor.call("giveCondition", charId, subCondition); - }); - }, - removeCondition: function(charId, conditionName) { - checkWritePermission(charId); - var condition = getCondition(conditionName); - //remove the buff - var buff = _.extend( - {charId: charId}, condition.buff - ); - Conditions.remove(buff); - //dont remove the effects, they get removed automatically through parenting - }, - getConditions: function() { - return Object.keys(CONDITIONS); - }, - getConditionName: function(conditionName) { - //get condition from constant - var condition = CONDITIONS[conditionName]; - //check that condition exists - if (!condition) { - throw new Meteor.Error( - "Invalid condition", - conditionName + " is not a known condition" - ); - } - return condition.buff.name; - }, -}); - -trackEncumbranceConditions = function(charId, templateInstance) { - templateInstance.autorun(function() { - //get weight - var weight = 0; - Containers.find( - {charId: charId, isCarried: true}, - {fields: {weight: 1}} - ).forEach(function(container){ - weight += container.totalWeight(); - }); - Items.find( - {charId: charId, "parent.id": charId}, - {fields: {weight : 1, quantity: 1}} - ).forEach(function(item){ - weight += item.totalWeight(); - }); - var character = Characters.findOne( - charId, - {fields: {"settings": 1}} - ); - var strength = Characters.calculate.attributeValue(charId, "strength"); - var carryMultiplier = Characters.calculate - .attributeValue(charId, "carryMultiplier"); - var give = function(condition) { - Meteor.call("giveCondition", charId, condition); - }; - var remove = function(condition) { - Meteor.call("removeCondition", charId, condition); - }; - //variant encumbrance rules - if (weight > strength * 10 * carryMultiplier && - character.settings.useVariantEncumbrance) { - give("encumbered2"); - remove("encumbered"); - } else if (weight > strength * 5 * carryMultiplier && - character.settings.useVariantEncumbrance){ - give("encumbered"); - remove("encumbered2"); - } else { - remove("encumbered"); - remove("encumbered2"); - } - //normal encumbrance rules - if (weight > strength * 30 * carryMultiplier && - character.settings.useStandardEncumbrance){ - give("encumbered4"); - remove("encumbered3"); - } else if (weight > strength * 15 * carryMultiplier && - character.settings.useStandardEncumbrance) { - give("encumbered3"); - remove("encumbered4"); - } else { - remove("encumbered3"); - remove("encumbered4"); - } - }); -}; - -// jscs:disable maximumLineLength -CONDITIONS = { - //Conditions - blind: { - buff: { - name: "Blind", - description: "A blinded creature can’t see and automatically fails any ability check that requires sight.\n\nAttack rolls against the creature have advantage, and the creature’s attack rolls have disadvantage.", - }, - effects: [ - { - stat: "perception", - operation: "conditional", - calculation: "You fail your Perception check if it requires sight", - } - ], - }, - - deaf: { - buff: { - name: "Deaf", - description: "A deafened creature can’t hear and automatically fails any ability check that requires hearing.", - }, - effects: [ - { - stat: "perception", - operation: "conditional", - calculation: "You fail your Perception check if it requires hearing", - } - ], - }, - - frightened: { - buff: { - name: "Frightened", - description: "A frightened creature has disadvantage on ability checks and attack rolls while the source of its fear is within line of sight.\n\nThe creature can’t willingly move closer to the source of its fear.", - } - }, - - grappled: { - buff:{ - name: "Grappled", - description: "A grappled creature’s speed becomes 0, and it can’t benefit from any bonus to its speed.\n\nThe condition ends if the grappler is incapacitated.\n\nThe condition also ends if an effect removes the grappled creature from the reach of the grappler or grappling effect, such as when a creature is hurled away by the thunder wave spell.", - }, - effects: [ - { - stat: "speed", - operation: "max", - value: 0, - }, - ], - }, - - incapacitated: { - buff: { - name: "Incapacitated", - description: "An incapacitated creature can’t take actions or reactions.", - } - }, - - invisible: { - buff: { - name: "Invisible", - description: "An invisible creature is impossible to see without the aid of magic or a special sense. For the purpose of hiding, the creature is heavily obscured. The creature’s location can be detected by any noise it makes or any tracks it leaves.\n\nAttack rolls against the creature have disadvantage, and the creature’s attack rolls have advantage.", - } - }, - - paralyzed: { - buff: { - name: "Paralyzed", - description: "A paralyzed creature is **incapacitated** and can’t move or speak.\n\nAttack rolls against the creature have advantage.\n\nAny attack that hits the creature is a critical hit if the attacker is within 5 feet of the creature.", - }, - effects: [ - { - stat: "speed", - operation: "mul", - value: 0, - }, - { - stat: "strengthSave", - operation: "fail", - }, - { - stat: "dexteritySave", - operation: "fail", - }, - ], - subConditions: [ - "incapacitated", - ], - }, - - petrified: { - buff: { - name: "Petrified", - description: "A petrified creature is transformed, along with any nonmagical object it is wearing or carrying, into a solid inanimate substance (usually stone). Its weight increases by a factor of ten, and it ceases aging.\n\nA petrified creature is **incapacitated** and can’t move or speak, and is unaware of its surroundings.\n\nAttack rolls against the creature have advantage.\n\nThe creature is immune to poison and disease, although a poison or disease already in its system is suspended, not neutralized.", - }, - effects: (function() { - var effects = [ - {stat: "speed", operation: "max", value: 0}, - {stat: "strengthSave", operation: "fail"}, - {stat: "dexteritySave", operation: "fail"}, - ]; - _.each( - _.without(DAMAGE_MULTIPLIERS, "poisonMultiplier"), - function(multiplier){ - effects.push({stat: multiplier, operation: "mul", value: 0.5}); - } - ); - effects.push({stat: "poisonMultiplier", operation: "mul", value: 0}); - })(), - subConditions: [ - "incapacitated", - ], - }, - - poisoned: { - buff: { - name: "Poisoned", - description: "A poisoned creature has disadvantage on attack rolls and ability checks.", - }, - effects: (function() { - return _.map(SKILLS, function(skill) { - return {stat: skill, operation: "disadvantage", value: 1}; - }); - })(), - }, - - prone: { - buff: { - name: "Prone", - description: "A prone creature’s only movement option is to crawl, unless it stands up and thereby ends the condition.\n\nThe creature has disadvantage on attack rolls.\n\nAn attack roll against the creature has advantage if the attacker is within 5 feet of the creature. Otherwise, the attack roll has disadvantage.", - } - }, - - restrained: { - buff: { - name: "Restrained", - description: "A restrained creature’s speed becomes 0, and it can’t benefit from any bonus to its speed.\n\nAttack rolls against the creature have advantage, and the creature’s attack rolls have disadvantage.\n\nThe creature has disadvantage on Dexterity saving throws.", - }, - effects: [ - { - stat: "speed", - operation: "max", - value: 0, - }, - { - stat: "dexteritySave", - operation: "disadvantage", - value: 1, - }, - ], - }, - - stunned: { - buff: { - name: "Stunned", - description: "A stunned creature is **incapacitated**, can’t move, and can speak only falteringly\n\nThe creature automatically fails Strength and Dexterity saving throws.\n\nAttack rolls against the creature have advantage.", - }, - effects: [ - { - stat: "speed", - operation: "max", - value: 0, - }, - { - stat: "strengthSave", - operation: "fail", - }, - { - stat: "dexteritySave", - operation: "fail", - }, - ], - subConditions: ["incapacitated"], - }, - - unconscious: { - buff: { - name: "Unconscious", - description: "An unconscious creature is **incapacitated**, can’t move or speak, and is unaware of its surroundings.\n\nThe creature drops whatever it’s holding and falls **prone**.\n\nThe creature automatically fails Strength and Dexterity saving throws.\n\nAttack rolls against the creature have advantage.\n\nAny attack that hits the creature is a critical hit if the attacker is within 5 feet of the creature.", - }, - subConditions: ["incapacitated", "prone"], - }, - - exhaustion1: { - buff: { - name: "Exhaustion - 1", - description: "Disadvantage on ability checks\n\nFinishing a long rest reduces a creature’s exhaustion level by 1, provided that the creature has also ingested some food and drink.", - }, - effects: (function() { - return _.map(SKILLS, function(skill) { - return {stat: skill, operation: "disadvantage", value: 1}; - }); - })(), - }, - exhaustion2: { - buff: { - name: "Exhaustion - 2", - description: "Speed halved", - }, - effects: [ - { - stat: "speed", - operation: "mul", - value: 0.5, - } - ], - subConditions: ["exhaustion1"], - }, - exhaustion3: { - buff: { - name: "Exhaustion - 3", - description: "Disadvantage on attack rolls and saving throws", - }, - effects: (function() { - return _.map(SAVES, function(skill) { - return {stat: skill, operation: "disadvantage", value: 1}; - }); - })(), - subConditions: ["exhaustion2"], - }, - exhaustion4: { - buff: { - name: "Exhaustion - 4", - description: "Hit point maximum halved", - }, - effects: [ - { - stat: "hitPoints", - operation: "mul", - value: 0.5, - } - ], - subConditions: ["exhaustion3"], - }, - exhaustion5: { - buff: { - name: "Exhaustion - 5", - description: "Speed reduced to 0", - }, - effects: [ - { - stat: "speed", - operation: "max", - value: 0, - } - ], - subConditions: ["exhaustion4"], - }, - exhaustion6: { - buff: { - name: "Exhaustion - 6", - description: "You have died of exhaustion", - }, - effects: [ - { - stat: "hitPoints", - operation: "max", - value: 0, - } - ], - subConditions: ["exhaustion5"], - }, - encumbered: { - buff: { - name: "Encumbered", - description: "Encumbered characters move 10 feet slower.", - }, - effects: [ - {stat: "speed", operation: "add", value: -10} - ], - }, - encumbered2: { - buff: { - name: "Heavily encumbered", - description: "Heavily encumbered characters move 20 feet slower and have disadvantage on ability checks, attack rolls, and saving thows that use Strength, Dexterity, or Constitution.", - }, - effects: [ - {stat: "speed", operation: "add", value: -20}, - {stat: "strengthSave", operation: "disadvantage", value: 1}, - {stat: "dexteritySave", operation: "disadvantage", value: 1}, - {stat: "constitutionSave", operation: "disadvantage", value: 1}, - {stat: "athletics", operation: "disadvantage", value: 1}, - {stat: "acrobatics", operation: "disadvantage", value: 1}, - {stat: "sleightOfHand", operation: "disadvantage", value: 1}, - {stat: "stealth", operation: "disadvantage", value: 1}, - {stat: "initiative", operation: "disadvantage", value: 1}, - ], - }, - encumbered3: { - buff: { - name: "Over encumbered", - description: "Characters that can only just lift, push or drag their current load move at 5 feet.", - }, - effects: [ - {stat: "speed", operation: "max", value: 5}, - ], - }, - encumbered4: { - buff: { - name: "Can't move load", - description: "Characters attempting to carry more than what they can lift, push, or drag can't move.", - }, - effects: [ - {stat: "speed", operation: "max", value: 0}, - ], - }, -}; diff --git a/app/lib/methods/removeMeFromReaders.js b/app/lib/methods/removeMeFromReaders.js deleted file mode 100644 index 72e8fb63..00000000 --- a/app/lib/methods/removeMeFromReaders.js +++ /dev/null @@ -1,11 +0,0 @@ -Meteor.methods({ - removeMeFromReaders: function(charId) { - var userId = Meteor.userId(); - var character = Characters.findOne(charId); - - if (!character) return; - if (!_.contains(character.readers, userId)) return; - - Characters.update(charId, {$pull: {"readers": userId}}); //we don't check write permission as you should always be able to remove youself from readers - } -}); \ No newline at end of file diff --git a/app/private/changeLogs/changeLogs.js b/app/private/changeLogs/changeLogs.js deleted file mode 100644 index 79a487a1..00000000 --- a/app/private/changeLogs/changeLogs.js +++ /dev/null @@ -1,347 +0,0 @@ -// jscs:disable maximumLineLength - -ChangeLogs.insert({ - version: "0.2.0 - First public release", - changes: [ - "Implemented basic sharing", - "Detail boxes separated into view and edit modes", - "Spell lists now expand horizontally to make better use of wide screens", - "Proficiencies separated from effects and text boxes to be their own assets", - "Added favicons and icons for Android/iOS shortcuts", - "Changed menu icon from hamburger to dots", - ], -}); - -ChangeLogs.insert({ - version: "0.2.1", - changes: [ - "Improved sharing functionality", - "Sliders no longer jump to a point, they need to be dragged", - "Added a list of characters to the side bar", - ], -}); - -ChangeLogs.insert({ - version: "0.2.2", - changes: [ - "Removed a security vulnerability that allowed users to pretend to be other users", - "The character list menu item in the side bar now shows up whether you have characters yet or not", - "Stopped the old proficiency text dialog showing up long after it got depreciated", - ], -}); - -ChangeLogs.insert({ - version: "0.2.3", - changes: [ - "Changed spacing and formatting of the intro text on the front page", - ], -}); - -ChangeLogs.insert({ - version: "0.2.4", - changes: [ - "Fixed typos in the front page", - "Fixed character sheet loading indefinitely if the character does not exist", - "Prevented character sheet crashing and loading forever when a incorectly typed ability modifier variable was used in calculations", - ], -}); - -ChangeLogs.insert({ - version: "0.2.5", - changes: [ - "Moved log-in to its own page and added functionality for forgot passwords, verifying email addresses and general user accounts improvements", - ], -}); - -ChangeLogs.insert({ - version: "0.2.6", - changes: [ - "Re-wrote how item dragging and dropping works to allow items to be dragged to characters in the side bar, and to containers on characters in other tabs and even other windows.", - "Fixed how splitting stacks works. Stacks should now split and merge properly when ctrl-dragged around", - ], -}); - -ChangeLogs.insert({ - version: "0.2.7", - changes: [ - "Added a quick feedback form", - "Improved the formatting of the side-bar's list of characters", - "Added a change log", - "Fixed the styling and rounding of some of the detail boxes", - ], -}); - -ChangeLogs.insert({ - version: "0.3.0", - changes: [ - "Refactored character sheet user interface.", - "Removed a lot of unneeded effects and webcomponents, should result in significantly improved performance on low-powered devices.", - ], -}); - -ChangeLogs.insert({ - version: "0.3.1", - changes: [ - "Re-implemented floating action button menu component to move away from the broken third party implementation.", - ], -}); - -ChangeLogs.insert({ - version: "0.4.0", - changes: [ - "Changed attacks to use arbitrary strings with inline calculations", - "Added item increment and decrement buttons", - "fixed incorrect line breaks and formatting in dialogs", - "Added calculated values for jumping and carrying to the strength detail box", - ], -}); - -ChangeLogs.insert({ - version: "0.4.1", - changes: [ - "Fixed strength jumping calculations not rounding down correctly", - ], -}); - -ChangeLogs.insert({ - version: "0.4.2", - changes: [ - "Fixed attack migrations from 0.3 -> 0.4", - ], -}); - -ChangeLogs.insert({ - version: "0.5", - changes: [ - "Fixed a bug that caused multiple resistances or vulnerabilities to combine incorrectly", - "Added encumbrance effects that automatically apply when carrying too much load", - "Added a bunch of UI elements to make your character's current load clear", - "Floating button menus now close as expected when you click a sub-button", - "Base values in attribute summaries no longer look like added values", - ], -}); - -ChangeLogs.insert({ - version: "0.5.1", - changes: [ - "Characters are now cached and should take much faster to load when swapping between them", - ], -}); - -ChangeLogs.insert({ - version: "0.5.2", - changes: [ - "Opened the beta up to the general public", - "Added performance monitoring", - ], -}); - -ChangeLogs.insert({ - version: "0.5.3", - changes: [ - "Prevented a harmless error caused by effects which have no stat set", - "Added the ability to hide the spells tab", - "Feedback forms now give me push notifications", - "Feedback forms now won't send unless properly filled out", - "Overhauled how effects' stats are chosen", - ], -}); - -ChangeLogs.insert({ - version: "0.5.4", - changes: [ - "Fixed rounding error on net worth calculation", - ], -}); - -ChangeLogs.insert({ - version: "0.5.5", - changes: [ - "Fixed reports from google users not correctly storing the reply-to email address", - ], -}); - -ChangeLogs.insert({ - version: "0.5.6", - changes: [ - "Changed front page", - "Moved to a darker style", - "Added support for letting characters be viewed by \"anyone with the link\"", - ], -}); - -ChangeLogs.insert({ - version: "0.5.7", - changes: [ - "Added proficiencies to backgrounds", - "Added attacks to spells", - "Added a move item dialog to mobile devices, but it can't be accessed yet, because long-presses are broken", - ], -}); - -ChangeLogs.insert({ - version: "0.6.0", - changes: [ - "Big performance improvements: loading characters that you've viewed recently and changing effects on characters should be much faster", - "Spell dialogs no longer show their casting time, range, etc. if those fields aren't filled in", - "The settings dialog now has a done button so it can be closed on small devices", - "Container dialogs now have the weight summaries rounded down properly", - ], -}); - -ChangeLogs.insert({ - version: "0.6.1", - changes: [ - "Experience dialogs should update their edit-mode inputs properly now", - ], -}); - -ChangeLogs.insert({ - version: "0.6.2", - changes: [ - "Fixed a regression which broke min and max effects", - ], -}); - -ChangeLogs.insert({ - version: "0.6.3", - changes: [ - "Fixed a regression that stopped skills and attributes from rounding down correctly", - "Made dependency loops return NaN immediately, rather than looping indefinitely until a page refresh. Adding an effect that adds \"strength\" to Strength, won't cause Strength to constantly increase or freeze the browser, Strength just becomes NaN", - ], -}); - -ChangeLogs.insert({ - version: "0.6.4", - changes: [ - "Hit dice now has a \"+\" between the dice and the constitution modifier", - "Items with multiple attacks should have the damage type editable on all attacks now", - "Spell attacks should now correctly inherit changes to their spell's name", - "Character lists should now be ordered alphabetically", - "Skills should have correct min and max effects applied again", - ], -}); - -ChangeLogs.insert({ - version: "0.6.5", - changes: [ - "Net worth now takes container values into account", - "Added support for character pictures", - "Disabled edit buttons for read-only viewers", - ], -}); - -ChangeLogs.insert({ - version: "0.6.6", - changes: [ - "Text fields now accept github-flavor markdown formatting", - ], -}); - -ChangeLogs.insert({ - version: "0.6.7", - changes: [ - "Fixed effect values not being visible on small screens", - "Added basic analytics", - ], -}); - -ChangeLogs.insert({ - version: "0.6.8", - changes: [ - "Fixed share dialog not finding user names", - "Fixed temporary hitpoint sliders allowing negative values", - "Fixed proficiencies not being disabled with their features", - ], -}); - -ChangeLogs.insert({ - version: "0.7.0", - changes: [ - "Added carry capacity multiplier as a stat with a default value of 1", - "Improved loading times by vulcanizing polymer imports", - ], -}); - -ChangeLogs.insert({ - version: "0.7.1", - changes: [ - "Fixed carry capacity effects not displaying correctly when not editing", - "Changed how columns are presented to fix a display issue introduced in Chrome 44", - ], -}); - -ChangeLogs.insert({ - version: "0.7.2", - changes: [ - "Fixed spell attacks appearing on features page when the spell is not prepared", - ], -}); - -ChangeLogs.insert({ - version: "0.8.0", - changes: [ - "Migrate to a new hosting provider. Server should now respond to interaction in milliseconds, rather than minutes", - "Redirected www.dicecloud.com to dicecloud.com", - "Fixed errors loggin in with Google", - ], -}); - -ChangeLogs.insert({ - version: "0.9.0", - changes: [ - "Added fast render support, direct links to characters should load instantly", - "Added extra indexes to the database to improve performance", - ], -}); - -ChangeLogs.insert({ - version: "0.9.1", - changes: [ - "Fixed rendering issues in Chrome 49+", - "Made character names in the side-bar into regular links", - ], -}); - -ChangeLogs.insert({ - version: "0.9.2", - changes: [ - "New characters now have starting ability scores of 10", - "Coins are incrementable by default", - "Fixed multiplication sign", - "Added \"if\" function to equations", - "Added ritual tag to spells in the spell list", - "Updated dependencies to keep up with Chrome's breaking changes", - ], -}); - -ChangeLogs.insert({ - version: "0.9.3", - changes: [ - "Fixed invisible dropdown boxes in Chrome 52", - ], -}); - -ChangeLogs.insert({ - version: "0.9.4", - changes: [ - "Fixed app not working on iOS 10", - ], -}); - -ChangeLogs.insert({ - version: "1.0.0", - changes: [ - "Migrated app from experimental Polymer impementation to stable implemenation", - "Replaced character cards with portrait cards", - "Replaced old user interface bugs with entirely new bugs", - ], -}); - -ChangeLogs.insert({ - version: "1.0.1", - changes: [ - "Fixed drawer being hidden by character sheet cards and headers", - "Fixed dragging items to characters in the drawer", - ], -}); diff --git a/app/server/lib/logRateError.js b/app/server/lib/logRateError.js deleted file mode 100644 index b261c3eb..00000000 --- a/app/server/lib/logRateError.js +++ /dev/null @@ -1,8 +0,0 @@ -logRateError = function(reply, ruleInput){ - // reply = {allowed, timeToReset, numInvocationsLeft} - // ruleInput = {userId, clientAddress, type, name, connectionId} - console.log( - `Limit hit for ${ruleInput.type} "${ruleInput.name}" ` + - `by user ${ruleInput.userId} from ${ruleInput.clientAddress}` - ); -} diff --git a/app/server/main.js b/app/server/main.js index 9bc3139d..89d78f45 100644 --- a/app/server/main.js +++ b/app/server/main.js @@ -1,2 +1,5 @@ import "/imports/server/publications/index.js"; import "/imports/api/creature/creatureComputation.js"; +import "/imports/api/parenting/deleteRemovedDocuments.js"; +import "/imports/server/config/accountsMeldConfig.js"; +import "/imports/server/config/simpleSchemaDebug.js"; diff --git a/app/server/migrations/migrations.js b/app/server/migrations/migrations.js deleted file mode 100644 index 2115e058..00000000 --- a/app/server/migrations/migrations.js +++ /dev/null @@ -1,186 +0,0 @@ -Meteor.methods({ - getVersion: function() { - return Migrations.getVersion(); - }, - migrateTo: function(versionNumber) { - var user = Meteor.users.findOne(this.userId); - if (!user){ - throw new Meteor.Error( - "logged-out", - "The user must be logged in to migrate the database" - ); - } - if (_.contains(user.roles, "admin")){ - Migrations.migrateTo(versionNumber); - } else { - throw new Meteor.Error( - "not admin", - "The user must be an administrator to migrate the database" - ); - } - }, -}); - -Migrations.add({ - version: 1, - name: "Gives all characters a URL name", - up: function() { - //update characters - Characters.find({}).forEach(function(char){ - if (char.urlName) return; - var urlName = getSlug(char.name, {maintainCase: true}) || "-"; - Characters.update(char._id, {$set: {urlName}}); - }); - }, - down: function(){ - return; - }, -}); - -Migrations.add({ - version: 2, - name: "Adds TempHP as a character attribute", - up: function() { - //update characters - Characters.find({}).forEach(function(char){ - if (char.tempHP) return; - Characters.update(char._id, {$set: { - "tempHP.adjustment": 0, - "tempHP.reset": "longRest", - }}); - }); - }, - down: function(){ - return; - }, -}); - -Migrations.add({ - version: 3, - name: "Moves all character attributes off the character document", - up: function () { - //TODO Temporary hitpoints should become attributes with the hitpoints type - const batchSize = 50; - const stats = [ - // Abilities - "strength", - "dexterity", - "constitution", - "intelligence", - "wisdom", - "charisma", - - // Stats - "hitPoints", - "tempHP", - "experience", - "proficiencyBonus", - "speed", - "weight", - "age", - "ageRate", - "armor", - "carryMultiplier", - - // Resources - "level1SpellSlots", - "level2SpellSlots", - "level3SpellSlots", - "level4SpellSlots", - "level5SpellSlots", - "level6SpellSlots", - "level7SpellSlots", - "level8SpellSlots", - "level9SpellSlots", - "ki", - "sorceryPoints", - "rages", - "superiorityDice", - "expertiseDice", - "rageDamage", - - // Hit Dice - "d6HitDice", - "d8HitDice", - "d10HitDice", - "d12HitDice", - - // Damage Multipliers - "acidMultiplier", - "bludgeoningMultiplier", - "coldMultiplier", - "fireMultiplier", - "forceMultiplier", - "lightningMultiplier", - "necroticMultiplier", - "piercingMultiplier", - "poisonMultiplier", - "psychicMultiplier", - "radiantMultiplier", - "slashingMultiplier", - "thunderMultiplier", - - // Saves - "strengthSave", - "dexteritySave", - "constitutionSave", - "intelligenceSave", - "wisdomSave", - "charismaSave", - - // Skills - "acrobatics", - "animalHandling", - "arcana", - "athletics", - "deception", - "history", - "insight", - "intimidation", - "investigation", - "medicine", - "nature", - "perception", - "performance", - "persuasion", - "religion", - "sleightOfHand", - "stealth", - "survival", - "initiative", - "dexterityArmor", - ]; - let modifier = {$unset: {}}; - _.each(stats, stat => { - modifier.$unset[stat] = 1; - }); - let charIds, defaultDocs; - let migrateBatch = function(){ - // Iterate over a batch of characters at a time - charIds = Characters.find( - {strength: {$exists: true}}, - {fields: {_id: 1}, limit: batchSize}, - ).map(char => char._id); - if (!charIds.length) { - return; - } - _.each(charIds, charId => { - // Add all the stats to their own collections - defaultDocs = getDefaultCharacterDocs(charId); - Attributes.rawCollection().insert(defaultDocs.attributes, {ordered: false}); - Skills.rawCollection().insert(defaultDocs.skills, {ordered: false}); - DamageMultipliers.rawCollection().insert(defaultDocs.damageMultipliers, {ordered: false}); - // Remove the stats on the character document - Characters.update(charId, modifier, {validate: false}, function(error, result){ - if (error) console.log(error); - }); - }); - // Do the next batch - Meteor.defer(migrateBatch); - }; - migrateBatch(); - }, - down: function () { - return; - } -}); diff --git a/app/tests/mocha/server/lib/characterUtility.js b/app/tests/mocha/server/lib/characterUtility.js deleted file mode 100644 index 88ceac20..00000000 --- a/app/tests/mocha/server/lib/characterUtility.js +++ /dev/null @@ -1,31 +0,0 @@ -if (!(typeof MochaWeb === "undefined")){ - MochaWeb.testOnly(function(){ - describe("CharacterUtility", function(){ - describe(("getMod"), function(){ - it("should return a 0 for 10 and 11", function(){ - chai.assert.equal(getMod(10), 0); - chai.assert.equal(getMod(11), 0); - }); - it("should return a 4 for 18 and 19", function(){ - chai.assert.equal(getMod(18), 4); - chai.assert.equal(getMod(19), 4); - }); - it("should return a -3 for 4 and 5", function(){ - chai.assert.equal(getMod(4), -3); - chai.assert.equal(getMod(5), -3); - }); - }); - describe(("signedString"), function(){ - it("should return a +1 for 1", function(){ - chai.assert.equal(signedString(1), "+1"); - }); - it("should return a +0 for 0", function(){ - chai.assert.equal(signedString(0), "+0"); - }); - it("should return a -1 for -1", function(){ - chai.assert.equal(signedString(-1), "-1"); - }); - }); - }); - }); -} diff --git a/app/tests/mocha/server/model/character/character.js b/app/tests/mocha/server/model/character/character.js deleted file mode 100644 index d3c14e2d..00000000 --- a/app/tests/mocha/server/model/character/character.js +++ /dev/null @@ -1,25 +0,0 @@ -if (typeof MochaWeb !== "undefined"){ - MochaWeb.testOnly(function(){ - var charId; - describe("Character", function(){ - describe("insert", function(){ - it("should create a character", function(){ - charId = Characters.insert({owner: "FWeGYyDY5jc4HuTh8"}); - }); - }); - describe("attribute.adjustment", function(){ - Characters.insert({owner: "FWeGYyDY5jc4HuTh8"}); - it("should track attribute adjustments", function(){ - Characters.update(charId, {$set: {"strength.adjustment": -12}}); - }); - it("should report the adjusted attribute correctly", function(){ - var val = Characters.findOne(charId).attributeValue("strength"); - chai.assert.equal(val, -12); - val = Characters.findOne(charId).fieldValue("strength"); - chai.assert.equal(val, -12); - }); - }); - Characters.remove({}); - }); - }); -} diff --git a/app/tests/mocha/server/model/character/effects.js b/app/tests/mocha/server/model/character/effects.js deleted file mode 100644 index 422bdc09..00000000 --- a/app/tests/mocha/server/model/character/effects.js +++ /dev/null @@ -1,193 +0,0 @@ -var getEffect = function(charId, op, value){ - return getAttributeEffect(charId, "constitution", op, value); -}; - -var getAttributeEffect = function(charId, attribute, op, value){ - return { - charId: charId, - stat: attribute, - operation: op, - value: value, - parent: { - id: charId, - collection: "Characters", - group: "inate", - }, - }; -}; - -var getSkillEffect = function(charId, op, value){ - return { - charId: charId, - stat: "athletics", - operation: op, - value: value, - parent: { - id: charId, - collection: "Characters", - group: "inate", - }, - }; -}; - -var getProficiency = function(charId, value){ - return { - charId: charId, - value: value, - type: "skill", - name: "athletics", - parent: { - id: charId, - collection: "Characters", - group: "inate", - }, - }; -}; - -if (typeof MochaWeb !== "undefined"){ - MochaWeb.testOnly(function(){ - describe("Character", function(){ - var charId, char, con, ath, strMod; - - beforeEach(function(){ - Effects.remove({}); - Characters.remove({}); - charId = Characters.insert({owner: "FWeGYyDY5jc4HuTh8"}); - char = Characters.findOne(charId); - con = function(){return char.attributeValue("constitution");}; - ath = function(){return char.skillMod("athletics");}; - strMod = function(){return char.abilityMod("strength");}; - }); - - describe("effects", function(){ - describe("attributeValue", function(){ - beforeEach(function(){ - Effects.remove({}); - }); - - it("should be set to highest base", function(){ - Effects.insert(getEffect(charId, "base", 10)); - Effects.insert(getEffect(charId, "base", 6)); - chai.assert.equal(10, con()); - }); - - it("should add", function(){ - Effects.insert(getEffect(charId, "add", 2)); - Effects.insert(getEffect(charId, "base", 10)); - chai.assert.equal(12, con()); - }); - - it("should multiply after adding", function(){ - Effects.insert(getEffect(charId, "mul", 2)); - Effects.insert(getEffect(charId, "base", 10)); - Effects.insert(getEffect(charId, "add", 2)); - chai.assert.equal(24, con()); - }); - - it("should be at least highest min", function(){ - Effects.insert(getEffect(charId, "min", 22)); - Effects.insert(getEffect(charId, "base", 10)); - Effects.insert(getEffect(charId, "add", 2)); - Effects.insert(getEffect(charId, "mul", 2)); - chai.assert.equal(con(), 24); - Effects.insert(getEffect(charId, "min", 28)); - chai.assert.equal(28, con()); - }); - - it("should be at most lowest max after minning", function(){ - Effects.insert(getEffect(charId, "max", 5)); - Effects.insert(getEffect(charId, "min", 22)); - Effects.insert(getEffect(charId, "base", 10)); - Effects.insert(getEffect(charId, "add", 2)); - Effects.insert(getEffect(charId, "mul", 2)); - chai.assert.equal(5, con()); - Effects.insert(getEffect(charId, "max", 6)); - chai.assert.equal(5, con()); - }); - - it("should respect adjustment", function(){ - Effects.insert(getEffect(charId, "base", 10)); - Effects.insert(getEffect(charId, "add", 2)); - Effects.insert(getEffect(charId, "mul", 2)); - Effects.insert(getEffect(charId, "min", 28)); - Effects.insert(getEffect(charId, "max", 5)); - Characters.update(charId, {$set: {"constitution.adjustment": -2}}); - chai.assert.equal(3, con()); - var conBase = char.attributeBase("constitution"); - chai.assert.equal(5, conBase); - }); - - it("should be removed when the character is deleted", function(){ - Effects.insert(getEffect(charId, "base", 10)); - var count = Effects.find({charId: charId}).count(); - chai.assert.equal(count, 1); - Characters.remove(charId); - count = Effects.find({charId: charId}).count(); - chai.assert.equal(count, 0); - }); - - }); - - describe("skillMod", function(){ - beforeEach(function(){ - Effects.remove({}); - }); - - it("should get its base value from the ability mod", function(){ - Effects.insert(getAttributeEffect(charId, "strength", "base", 16)); - chai.assert.equal(3, strMod()); - chai.assert.equal(3, ath()); - }); - - it("should add a multiple of proficiency bonus", function(){ - Effects.insert(getAttributeEffect(charId, "strength", "base", 16)); - Effects.insert(getAttributeEffect(charId, "proficiencyBonus", "base", 7)); - chai.assert.equal( - 7, - char.attributeValue("proficiencyBonus"), - "the proficiency bonus is calculated correctly" - ); - Proficiencies.insert(getProficiency(charId, 0.5)); - Proficiencies.insert(getProficiency(charId, 2)); - chai.assert.equal(17, ath(), "3 strength + (7 x 2) proficiency bonus"); - }); - - it("should add", function(){ - Effects.insert(getAttributeEffect(charId, "strength", "base", 16)); - Effects.insert(getSkillEffect(charId, "add", 2)); - chai.assert.equal(5, ath()); - }); - - it("should multiply", function(){ - Effects.insert(getAttributeEffect(charId, "strength", "base", 16)); - Effects.insert(getSkillEffect(charId, "mul", 2)); - chai.assert.equal(6, ath()); - }); - - it("should be at least highest min", function(){ - Effects.insert(getAttributeEffect(charId, "strength", "base", 16)); - Effects.insert(getSkillEffect(charId, "min", 1)); - chai.assert.equal(3, ath()); - Effects.insert(getSkillEffect(charId, "min", 5)); - chai.assert.equal(5, ath()); - }); - - it("should be at most lowest max", function(){ - Effects.insert(getAttributeEffect(charId, "strength", "base", 16)); - Effects.insert(getSkillEffect(charId, "max", 5)); - chai.assert.equal(3, ath()); - Effects.insert(getSkillEffect(charId, "max", 2)); - chai.assert.equal(2, ath()); - }); - - it("should be removed when the character is deleted", function(){ - Characters.remove(charId); - var count = Effects.find({charId: charId}).count(); - chai.assert.equal(count, 0); - }); - - }); - }); - }); - }); -} diff --git a/app/tests/mocha/server/sampleServerTest.js b/app/tests/mocha/server/sampleServerTest.js deleted file mode 100644 index bb220ccd..00000000 --- a/app/tests/mocha/server/sampleServerTest.js +++ /dev/null @@ -1,9 +0,0 @@ -if (!(typeof MochaWeb === 'undefined')){ - MochaWeb.testOnly(function(){ - describe("Server initialization", function(){ - it("should have a Meteor version defined", function(){ - chai.assert(Meteor.release); - }); - }); - }); -}