diff --git a/rpg-docs/.meteor/packages b/rpg-docs/.meteor/packages index 0928a7e4..89495d83 100644 --- a/rpg-docs/.meteor/packages +++ b/rpg-docs/.meteor/packages @@ -48,3 +48,4 @@ es5-shim@4.6.15 differential:vulcanize reactive-dict percolate:synced-cron +ongoworks:speakingurl diff --git a/rpg-docs/.meteor/versions b/rpg-docs/.meteor/versions index 04f53178..c2254df9 100644 --- a/rpg-docs/.meteor/versions +++ b/rpg-docs/.meteor/versions @@ -85,6 +85,7 @@ npm-mongo@2.2.16_1 oauth@1.1.12 oauth2@1.1.11 observe-sequence@1.0.14 +ongoworks:speakingurl@9.0.0 ordered-dict@1.0.9 percolate:migrations@0.9.8 percolate:synced-cron@1.3.2 diff --git a/rpg-docs/Model/Character/Actions.js b/rpg-docs/Model/Character/Actions.js index a4e2e236..31caa805 100644 --- a/rpg-docs/Model/Character/Actions.js +++ b/rpg-docs/Model/Character/Actions.js @@ -11,10 +11,12 @@ Schemas.Action = new SimpleSchema({ }, name: { type: String, + optional: true, trim: false, }, description: { type: String, + optional: true, trim: false, }, type: { diff --git a/rpg-docs/Model/Character/Attacks.js b/rpg-docs/Model/Character/Attacks.js index 2450439a..4a2dcc72 100644 --- a/rpg-docs/Model/Character/Attacks.js +++ b/rpg-docs/Model/Character/Attacks.js @@ -12,6 +12,7 @@ Schemas.Attack = new SimpleSchema({ name: { type: String, defaultValue: "New Attack", + optional: true, trim: false, }, details: { diff --git a/rpg-docs/Model/Character/Buffs.js b/rpg-docs/Model/Character/Buffs.js index 3d8c41c5..b2a367c2 100644 --- a/rpg-docs/Model/Character/Buffs.js +++ b/rpg-docs/Model/Character/Buffs.js @@ -8,6 +8,7 @@ Schemas.Buff = new SimpleSchema({ }, name: { type: String, + optional: true, trim: false, }, description: { diff --git a/rpg-docs/Model/Character/Characters.js b/rpg-docs/Model/Character/Characters.js index 0b807d34..b16e3324 100644 --- a/rpg-docs/Model/Character/Characters.js +++ b/rpg-docs/Model/Character/Characters.js @@ -4,6 +4,7 @@ Characters = new Mongo.Collection("characters"); Schemas.Character = new SimpleSchema({ //strings name: {type: String, defaultValue: "", trim: false, optional: true}, + urlName: {type: String, defaultValue: "", trim: false, optional: true}, alignment: {type: String, defaultValue: "", trim: false, optional: true}, gender: {type: String, defaultValue: "", trim: false, optional: true}, race: {type: String, defaultValue: "", trim: false, optional: true}, @@ -257,7 +258,10 @@ var attributeBase = preventLoop(function(charId, statName){ var result = (base + add) * mul; if (result < min) result = min; if (result > max) result = max; - + // Don't round carry multiplier + if (statName === "carryMultiplier"){ + return result; + } return Math.floor(result); }); @@ -537,6 +541,12 @@ if (Meteor.isServer){ Items .remove({charId: character._id}); Containers .remove({charId: character._id}); }); + Characters.after.update(function(userId, doc, fieldNames, modifier, options) { + if (_.contains(fieldNames, "name")){ + var urlName = getSlug(doc.name, {maintainCase: true}); + Characters.update(doc._id, {$set: {urlName}}); + } + }); } Characters.allow({ diff --git a/rpg-docs/Model/Character/Classes.js b/rpg-docs/Model/Character/Classes.js index ac036230..52e4df9e 100644 --- a/rpg-docs/Model/Character/Classes.js +++ b/rpg-docs/Model/Character/Classes.js @@ -2,7 +2,7 @@ Classes = new Mongo.Collection("classes"); Schemas.Class = new SimpleSchema({ charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1}, - name: {type: String, trim: false}, + name: {type: String, optional: true, trim: false}, level: {type: Number}, createdAt: { type: Date, diff --git a/rpg-docs/Model/Character/Experience.js b/rpg-docs/Model/Character/Experience.js index ff6d5932..4dc22b2a 100644 --- a/rpg-docs/Model/Character/Experience.js +++ b/rpg-docs/Model/Character/Experience.js @@ -2,7 +2,7 @@ Experiences = new Mongo.Collection("experience"); Schemas.Experience = new SimpleSchema({ charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1}, - name: {type: String, defaultValue: "New Experience", trim: false}, + name: {type: String, optional: true, trim: false, defaultValue: "New Experience"}, description: {type: String, optional: true, trim: false}, value: {type: Number, defaultValue: 0}, dateAdded: { diff --git a/rpg-docs/Model/Character/Features.js b/rpg-docs/Model/Character/Features.js index 29b8c7d5..468d6fe3 100644 --- a/rpg-docs/Model/Character/Features.js +++ b/rpg-docs/Model/Character/Features.js @@ -2,7 +2,7 @@ Features = new Mongo.Collection("features"); Schemas.Feature = new SimpleSchema({ charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1}, - name: {type: String, trim: false}, + name: {type: String, optional: true, trim: false}, description: {type: String, optional: true, trim: false}, uses: {type: String, optional: true, trim: false}, used: {type: Number, defaultValue: 0}, diff --git a/rpg-docs/Model/Character/Notes.js b/rpg-docs/Model/Character/Notes.js index 8d1afdf5..f1ce7aa4 100644 --- a/rpg-docs/Model/Character/Notes.js +++ b/rpg-docs/Model/Character/Notes.js @@ -2,7 +2,7 @@ Notes = new Mongo.Collection("notes"); Schemas.Note = new SimpleSchema({ charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1}, - name: {type: String, trim: false}, + name: {type: String, optional: true, trim: false}, description: {type: String, optional: true, trim: false}, color: { type: String, diff --git a/rpg-docs/Model/Character/SpellLists.js b/rpg-docs/Model/Character/SpellLists.js index 16aa2dab..982be871 100644 --- a/rpg-docs/Model/Character/SpellLists.js +++ b/rpg-docs/Model/Character/SpellLists.js @@ -2,7 +2,7 @@ SpellLists = new Mongo.Collection("spellLists"); Schemas.SpellLists = new SimpleSchema({ charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1}, - name: {type: String, trim: false}, + name: {type: String, optional: true, trim: false}, description: {type: String, optional: true, trim: false}, saveDC: {type: String, optional: true, trim: false}, attackBonus: {type: String, optional: true, trim: false}, diff --git a/rpg-docs/Model/Character/Spells.js b/rpg-docs/Model/Character/Spells.js index f04e2fa7..58f21cd2 100644 --- a/rpg-docs/Model/Character/Spells.js +++ b/rpg-docs/Model/Character/Spells.js @@ -9,6 +9,7 @@ Schemas.Spell = new SimpleSchema({ }, name: { type: String, + optional: true, trim: false, defaultValue: "New Spell", }, diff --git a/rpg-docs/Model/Inventory/Containers.js b/rpg-docs/Model/Inventory/Containers.js index 94761c58..2318c930 100644 --- a/rpg-docs/Model/Inventory/Containers.js +++ b/rpg-docs/Model/Inventory/Containers.js @@ -2,7 +2,7 @@ Containers = new Mongo.Collection("containers"); Schemas.Container = new SimpleSchema({ - name: {type: String, trim: false}, + name: {type: String, optional: true, trim: false}, charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1}, isCarried: {type: Boolean}, weight: {type: Number, min: 0, defaultValue: 0, decimal: true}, diff --git a/rpg-docs/Model/Inventory/Items.js b/rpg-docs/Model/Inventory/Items.js index c626c16f..6c5c00e1 100644 --- a/rpg-docs/Model/Inventory/Items.js +++ b/rpg-docs/Model/Inventory/Items.js @@ -1,7 +1,7 @@ Items = new Mongo.Collection("items"); Schemas.Item = new SimpleSchema({ - name: {type: String, defaultValue: "New Item", trim: false}, + name: {type: String, optional: true, trim: false, defaultValue: "New Item"}, plural: {type: String, optional: true, trim: false}, description:{type: String, optional: true, trim: false}, charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1}, //id of owner diff --git a/rpg-docs/Routes/Routes.js b/rpg-docs/Routes/Routes.js index 5f2906c2..14ac42ff 100644 --- a/rpg-docs/Routes/Routes.js +++ b/rpg-docs/Routes/Routes.js @@ -24,7 +24,7 @@ Router.map(function() { this.route("characterList", { path: "/characterList", waitOn: function(){ - return subsManager.subscribe("characterList", Meteor.userId()); + return subsManager.subscribe("characterList"); }, onAfterAction: function() { document.title = appName + " - Characters"; @@ -32,11 +32,27 @@ Router.map(function() { fastRender: true, }); - this.route("characterSheet", { - path: "/character/:_id", + this.route("characterSheetNaked", { + path: "/character/:_id/", waitOn: function(){ return [ - subsManager.subscribe("singleCharacter", this.params._id, Meteor.userId()), + subsManager.subscribe("singleCharacter", this.params._id), + ]; + }, + action: function(){ + var _id = this.params._id + var character = Characters.findOne(_id); + var urlName = character && character.urlName; + var path = `\/character\/${_id}\/${urlName}`; + Router.go(path,{},{replaceState:true}); + }, + }); + + this.route("characterSheet", { + path: "/character/:_id/:urlName", + waitOn: function(){ + return [ + subsManager.subscribe("singleCharacter", this.params._id), ]; }, data: function() { diff --git a/rpg-docs/client/globalHelpers/evaluate.js b/rpg-docs/client/globalHelpers/evaluate.js index d986b1f0..65ad0240 100644 --- a/rpg-docs/client/globalHelpers/evaluate.js +++ b/rpg-docs/client/globalHelpers/evaluate.js @@ -24,6 +24,10 @@ Template.registerHelper("evaluateString", function(charId, string) { return evaluateString(charId, string); }); +Template.registerHelper("evaluateSpellString", function(charId, spellListId, string) { + return evaluateSpellString(charId, spellListId, string); +}); + Template.registerHelper("evaluateShortString", function(charId, string) { if (_.isString(string)){ return evaluateString( diff --git a/rpg-docs/client/lib/requestAnimationFramePolyfill.js b/rpg-docs/client/lib/requestAnimationFramePolyfill.js new file mode 100644 index 00000000..0fb801e6 --- /dev/null +++ b/rpg-docs/client/lib/requestAnimationFramePolyfill.js @@ -0,0 +1,28 @@ +// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + +// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel + +// MIT license +var lastTime = 0; +var vendors = ["ms", "moz", "webkit", "o"]; +for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"]; + window.cancelAnimationFrame = window[vendors[x] + "CancelAnimationFrame"] || + window[vendors[x] + "CancelRequestAnimationFrame"]; +} + +if (!window.requestAnimationFrame) +window.requestAnimationFrame = function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function() { callback(currTime + timeToCall); }, + timeToCall); + lastTime = currTime + timeToCall; + return id; +}; + +if (!window.cancelAnimationFrame) +window.cancelAnimationFrame = function(id) { + clearTimeout(id); +}; diff --git a/rpg-docs/client/views/character/effects/effectEdit/effectEdit.html b/rpg-docs/client/views/character/effects/effectEdit/effectEdit.html index 3ae51b94..078cd946 100644 --- a/rpg-docs/client/views/character/effects/effectEdit/effectEdit.html +++ b/rpg-docs/client/views/character/effects/effectEdit/effectEdit.html @@ -20,26 +20,28 @@
{{#each statGroups}} -
+
{{this}}
- {{#each stats}} - {{name}} - {{/each}} + + {{#each stats}} + {{name}} + {{/each}} + {{/each}} {{#if operations}} {{#each operations}} - {{name}} + {{name}} {{/each}} {{else}} {{#if showMultiplierOperations}} - Resistance - Vulnerability - Immunity + Resistance + Vulnerability + Immunity {{else}}
diff --git a/rpg-docs/client/views/character/effects/effectEdit/effectEdit.js b/rpg-docs/client/views/character/effects/effectEdit/effectEdit.js index d18538fa..b47f7219 100644 --- a/rpg-docs/client/views/character/effects/effectEdit/effectEdit.js +++ b/rpg-docs/client/views/character/effects/effectEdit/effectEdit.js @@ -149,47 +149,71 @@ Template.effectEdit.helpers({ effectValue: function(){ return this.calculation || this.value; }, + isGroupSelected: function(groupName, statName){ + var stat = statsDict[statName] + return stat && (stat.group === groupName); + }, }); +var setStat = function(statName, effectId){ + var setter = {stat: statName}; + var effect = Effects.findOne(this._id); + var group = statsDict[statName].group; + if (group === "Saving Throws" || group === "Skills"){ + // Skills must have a valid skill operation + if (!_.contains( + _.map(skillOperations, ao => ao.operation), + effect.operation + )){ + setter.operation = "add"; + } + } else if (group !== "Weakness/Resistance"){ + // Attributes must have a valid attribute operation + if (!_.contains( + _.map(attributeOperations, ao => ao.operation), + effect.operation + )){ + setter.operation = "base"; + } + } else { + // Weakness/Resistance must have a mul operation and value + if (effect.operation !== "mul"){ + setter.operation = "mul"; + } + if (!_.contains([0, 0.5, 2], effect.value)){ + setter.value = 0.5; + } + } + Effects.update(effectId, {$set: setter}); +}; + +var scrollAnimationId; +var scrollElementToView = element => { + var scrollFunction = function(){ + element.scrollIntoView(); + scrollAnimationId = requestAnimationFrame(scrollFunction); + }; + return scrollFunction; +} + Template.effectEdit.events({ "click #deleteButton": function(event, instance){ Effects.softRemoveNode(instance.data.id); GlobalUI.deletedToast(instance.data.id, "Effects", "Effect"); popDialogStack(); }, + "click .statGroupTitle": function(event, instance){ + var groupName = this.toString(); + var firstStat = statGroups[groupName][0].stat; + setStat(firstStat, instance.data.id); + scrollAnimationId = requestAnimationFrame(scrollElementToView(event.target)); + _.delay(() => cancelAnimationFrame(scrollAnimationId), 300); + }, "iron-select .statMenu": function(event){ var detail = event.originalEvent.detail; var statName = detail.item.getAttribute("name"); if (statName == this.stat) return; - var setter = {stat: statName}; - var group = Blaze.getData(detail.item).group; - var effect = Effects.findOne(this._id); - if (group === "Saving Throws" || group === "Skills"){ - // Skills must have a valid skill operation - if (!_.contains( - _.map(skillOperations, ao => ao.operation), - effect.operation - )){ - setter.operation = "add"; - } - } else if (group !== "Weakness/Resistance"){ - // Attributes must have a valid attribute operation - if (!_.contains( - _.map(attributeOperations, ao => ao.operation), - effect.operation - )){ - setter.operation = "base"; - } - } else { - // Weakness/Resistance must have a mul operation and value - if (effect.operation !== "mul"){ - setter.operation = "mul"; - } - if (!_.contains([0, 0.5, 2], effect.value)){ - setter.value = 0.5; - } - } - Effects.update(this._id, {$set: setter}); + setStat(statName, this._id); }, "iron-select .operationMenu": function(event){ var detail = event.originalEvent.detail; diff --git a/rpg-docs/client/views/character/effects/effectsEditList/effectsEditList.js b/rpg-docs/client/views/character/effects/effectsEditList/effectsEditList.js index 0732431b..0a8646d4 100644 --- a/rpg-docs/client/views/character/effects/effectsEditList/effectsEditList.js +++ b/rpg-docs/client/views/character/effects/effectsEditList/effectsEditList.js @@ -33,7 +33,7 @@ Template.effectsEditList.events({ template: "effectEdit", data: {id: effectId}, element: event.currentTarget, - returnElement: instance.find(`tr.effect[data-id='${effectId}']`), + returnElement: () => instance.find(`tr.effect[data-id='${effectId}']`), }); }, "tap .edit-effect": function(event, template){ diff --git a/rpg-docs/client/views/character/spells/spellDialog/spellDialog.html b/rpg-docs/client/views/character/spells/spellDialog/spellDialog.html index 07d9faa7..7de0fdd8 100644 --- a/rpg-docs/client/views/character/spells/spellDialog/spellDialog.html +++ b/rpg-docs/client/views/character/spells/spellDialog/spellDialog.html @@ -36,7 +36,7 @@
{{/if}}
-
{{#markdown}}{{evaluateString charId description}}{{/markdown}}
+
{{#markdown}}{{evaluateSpellString charId parent.id description}}{{/markdown}}
{{> attacksViewList charId=charId parentId=_id}} diff --git a/rpg-docs/client/views/character/stats/skillDialog/skillDialog.html b/rpg-docs/client/views/character/stats/skillDialog/skillDialog.html index 8edf4caa..a0918755 100644 --- a/rpg-docs/client/views/character/stats/skillDialog/skillDialog.html +++ b/rpg-docs/client/views/character/stats/skillDialog/skillDialog.html @@ -61,6 +61,18 @@ Total {{characterCalculate "skillMod" charId skillName}} + {{#each passiveEffects}} + + {{sourceName}} + Passive Bonus: {{statValue}} + + {{/each}} + {{#if showPassiveTotal}} + + Passive Score + {{characterCalculate "passiveSkill" charId skillName}} + + {{/if}} diff --git a/rpg-docs/client/views/character/stats/skillDialog/skillDialog.js b/rpg-docs/client/views/character/stats/skillDialog/skillDialog.js index 759c1f11..d3b5f6cd 100644 --- a/rpg-docs/client/views/character/stats/skillDialog/skillDialog.js +++ b/rpg-docs/client/views/character/stats/skillDialog/skillDialog.js @@ -122,7 +122,7 @@ Template.skillDialogView.helpers({ var char = Characters.findOne(this.charId); if (!char) return; var prof = Characters.calculate.proficiency(this.charId, this.skillName); - var proficiencyBonus = + var proficiencyBonus = Characters.calculate.attributeValue(this.charId, "proficiencyBonus"); return prof * proficiencyBonus; }, @@ -189,6 +189,23 @@ Template.skillDialogView.helpers({ enabled: true, }); }, + passiveEffects: function(){ + return Effects.find({ + charId: this.charId, + stat: this.skillName, + operation: "passiveAdd", + enabled: true, + }); + }, + showPassiveTotal: function(){ + if (this.skillName === "perception") return true; + return Effects.find({ + charId: this.charId, + stat: this.skillName, + operation: "passiveAdd", + enabled: true, + }).count(); + }, ability: function(){ var opts = {fields: {}}; opts.fields[this.skillName] = 1; diff --git a/rpg-docs/client/views/character/stats/skillRow/skillRow.html b/rpg-docs/client/views/character/stats/skillRow/skillRow.html index 0b01f919..207dbac2 100644 --- a/rpg-docs/client/views/character/stats/skillRow/skillRow.html +++ b/rpg-docs/client/views/character/stats/skillRow/skillRow.html @@ -14,7 +14,7 @@ {{#if conditionalCount}} * {{/if}} - {{#if showPassive}} + {{#if isPassiveShown}} ({{characterCalculate "passiveSkill" ../_id skill}}) {{/if}} diff --git a/rpg-docs/client/views/character/stats/skillRow/skillRow.js b/rpg-docs/client/views/character/stats/skillRow/skillRow.js index 20915294..25a15d6c 100644 --- a/rpg-docs/client/views/character/stats/skillRow/skillRow.js +++ b/rpg-docs/client/views/character/stats/skillRow/skillRow.js @@ -38,4 +38,16 @@ Template.skillRow.helpers({ operation: "conditional", }).count(); }, + isPassiveShown: function(){ + if (this.showPassive === "forced") return true; + if (this.showPassive === "ifNeeded"){ + var charId = Template.parentData()._id; + return Effects.find({ + charId, + stat: this.skill, + operation: "passiveAdd", + enabled: true, + }).count(); + } + }, }); diff --git a/rpg-docs/client/views/character/stats/stats.html b/rpg-docs/client/views/character/stats/stats.html index 3a5ce782..3cde018b 100644 --- a/rpg-docs/client/views/character/stats/stats.html +++ b/rpg-docs/client/views/character/stats/stats.html @@ -49,24 +49,24 @@ Skills
- {{> skillRow name="Acrobatics" skill="acrobatics"}} - {{> skillRow name="Animal Handling" skill="animalHandling"}} - {{> skillRow name="Arcana" skill="arcana"}} - {{> skillRow name="Athletics" skill="athletics"}} - {{> skillRow name="Deception" skill="deception"}} - {{> skillRow name="History" skill="history"}} - {{> skillRow name="Insight" skill="insight"}} - {{> skillRow name="Intimidation" skill="intimidation"}} - {{> skillRow name="Investigation" skill="investigation"}} - {{> skillRow name="Medicine" skill="medicine"}} - {{> skillRow name="Nature" skill="nature"}} - {{> skillRow name="Perception" skill="perception" showPassive="true"}} - {{> skillRow name="Performance" skill="performance"}} - {{> skillRow name="Persuasion" skill="persuasion"}} - {{> skillRow name="Religion" skill="religion"}} - {{> skillRow name="Sleight of Hand" skill="sleightOfHand"}} - {{> skillRow name="Stealth" skill="stealth"}} - {{> skillRow name="Survival" skill="survival"}} + {{> skillRow name="Acrobatics" skill="acrobatics" showPassive="ifNeeded"}} + {{> skillRow name="Animal Handling" skill="animalHandling" showPassive="ifNeeded"}} + {{> skillRow name="Arcana" skill="arcana" showPassive="ifNeeded"}} + {{> skillRow name="Athletics" skill="athletics" showPassive="ifNeeded"}} + {{> skillRow name="Deception" skill="deception" showPassive="ifNeeded"}} + {{> skillRow name="History" skill="history" showPassive="ifNeeded"}} + {{> skillRow name="Insight" skill="insight" showPassive="ifNeeded"}} + {{> skillRow name="Intimidation" skill="intimidation" showPassive="ifNeeded"}} + {{> skillRow name="Investigation" skill="investigation" showPassive="ifNeeded"}} + {{> skillRow name="Medicine" skill="medicine" showPassive="ifNeeded"}} + {{> skillRow name="Nature" skill="nature" showPassive="ifNeeded"}} + {{> skillRow name="Perception" skill="perception" showPassive="forced"}} + {{> skillRow name="Performance" skill="performance" showPassive="ifNeeded"}} + {{> skillRow name="Persuasion" skill="persuasion" showPassive="ifNeeded"}} + {{> skillRow name="Religion" skill="religion" showPassive="ifNeeded"}} + {{> skillRow name="Sleight of Hand" skill="sleightOfHand" showPassive="ifNeeded"}} + {{> skillRow name="Stealth" skill="stealth" showPassive="ifNeeded"}} + {{> skillRow name="Survival" skill="survival" showPassive="ifNeeded"}}
diff --git a/rpg-docs/client/views/characterList/characterList.html b/rpg-docs/client/views/characterList/characterList.html index 1603eaa5..82e12b92 100644 --- a/rpg-docs/client/views/characterList/characterList.html +++ b/rpg-docs/client/views/characterList/characterList.html @@ -11,7 +11,7 @@ {{#if characters.count}}
{{# each characters}} - + diff --git a/rpg-docs/client/views/characterList/characterList.js b/rpg-docs/client/views/characterList/characterList.js index c5971a03..254b2854 100644 --- a/rpg-docs/client/views/characterList/characterList.js +++ b/rpg-docs/client/views/characterList/characterList.js @@ -10,7 +10,15 @@ Template.characterList.helpers({ ] }, { - fields: {name: 1, picture: 1, color: 1, race: 1, alignment: 1, gender: 1}, + fields: { + name: 1, + urlName: 1, + picture: 1, + color: 1, + race: 1, + alignment: 1, + gender: 1, + }, sort: {name: 1}, } ); diff --git a/rpg-docs/client/views/characterList/characterSideList.js b/rpg-docs/client/views/characterList/characterSideList.js index 915bf87a..010905c2 100644 --- a/rpg-docs/client/views/characterList/characterSideList.js +++ b/rpg-docs/client/views/characterList/characterSideList.js @@ -14,7 +14,7 @@ Template.characterSideList.helpers({ ] }, { - fields: {name: 1}, + fields: {name: 1, urlName: 1}, sort: {name: 1}, } ); diff --git a/rpg-docs/lib/functions/evaluate.js b/rpg-docs/lib/functions/evaluate.js index 9fce8c79..a66eed27 100644 --- a/rpg-docs/lib/functions/evaluate.js +++ b/rpg-docs/lib/functions/evaluate.js @@ -8,9 +8,10 @@ })(); //evaluates a calculation string -evaluate = function(charId, string){ +evaluate = function(charId, string, opts){ + var spellListId = opts && opts.spellListId; if (!string) return string; - string = string.replace(/\b[a-z]+\b/gi, function(sub){ + string = string.replace(/\b[a-z,1-9]+\b/gi, function(sub){ //fields if (Schemas.Character.schema(sub)){ return Characters.calculate.fieldValue(charId, sub); @@ -43,6 +44,12 @@ evaluate = function(charId, string){ if (sub.toUpperCase() === "LEVEL"){ return Characters.calculate.level(charId); } + if (spellListId && sub.toUpperCase() === "DC") { + var list = SpellLists.findOne(spellListId); + if (list && list.saveDC){ + return evaluate(charId, list.saveDC); + } + } return sub; }); try { @@ -66,6 +73,17 @@ evaluateString = function(charId, string){ return result; }; +evaluateSpellString = function (charId, spellListId, string) { + //define brackets as curly brackets around anything that isn't a curly bracket + if (!string) return string; + var brackets = /\{[^\{\}]*\}/g; + var result = string.replace(brackets, function(exp){ + exp = exp.replace(/(\{|\})/g, ""); //remove curly brackets + return evaluate(charId, exp, {spellListId}); + }); + return result; +} + //returns the value of the effect if it exists, //otherwise returns the result of the calculation if it exists, //otherwise returns 0 diff --git a/rpg-docs/public/custom_components/dicecloud-selector/dicecloud-selectable.html b/rpg-docs/public/custom_components/dicecloud-selector/dicecloud-selectable.html index fceeba7e..c88c3a30 100644 --- a/rpg-docs/public/custom_components/dicecloud-selector/dicecloud-selectable.html +++ b/rpg-docs/public/custom_components/dicecloud-selector/dicecloud-selectable.html @@ -249,7 +249,9 @@ }, _updateItems: function() { - var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*'); + var nodes = this.selectable + ? Polymer.dom(this).querySelectorAll(this.selectable) + : Polymer.dom(this).queryDistributedElements('*'); nodes = Array.prototype.filter.call(nodes, this._bindFilterItem); this._setItems(nodes); }, diff --git a/rpg-docs/server/migrations/migrations.js b/rpg-docs/server/migrations/migrations.js index 9eee2347..17ca3cf3 100644 --- a/rpg-docs/server/migrations/migrations.js +++ b/rpg-docs/server/migrations/migrations.js @@ -125,7 +125,7 @@ Migrations.add({ } }); var effect = Effects.findOne({ - charId: char._id, name: "Natural Carrying Capacity" + charId: char._id, name: "Natural Carrying Capacity", }); if (effect) return; Effects.insert({ @@ -141,7 +141,7 @@ Migrations.add({ }, }); effect = Effects.findOne({ - charId: char._id, name: "Natural Carrying Capacity" + charId: char._id, name: "Natural Carrying Capacity", }); if (!effect) throw "Carry capacity effect should be set by now." }); @@ -150,3 +150,19 @@ Migrations.add({ return; }, }); + +Migrations.add({ + version: 5, + 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; + }, +}); diff --git a/rpg-docs/server/publications/characterList.js b/rpg-docs/server/publications/characterList.js index b8c24b83..91e8e019 100644 --- a/rpg-docs/server/publications/characterList.js +++ b/rpg-docs/server/publications/characterList.js @@ -15,6 +15,7 @@ Meteor.publish("characterList", function(){ { fields: { name: 1, + urlName: 1, race: 1, alignment: 1, gender: 1,