From b76ac23713ff0adf7a34157758bebb5dd99a6ff7 Mon Sep 17 00:00:00 2001 From: Thaum Date: Fri, 17 Apr 2015 13:56:52 +0000 Subject: [PATCH] Made proficiencies their own objects, added migration functionality --- rpg-docs/.meteor/packages | 1 + rpg-docs/.meteor/versions | 1 + rpg-docs/Model/Character/Characters.js | 19 ++-- rpg-docs/Model/Character/Proficiencies.js | 16 +++- .../effectsEditList/effectsEditList.html | 2 +- .../features/featureDialog/featureDialog.html | 2 + .../journal/classDialog/classDialog.html | 1 + .../journal/raceDialog/raceDialog.html | 1 + .../proficiencyEdit/proficiencyEdit.html | 43 ++++++++++ .../proficiencyEdit/proficiencyEdit.js | 86 +++++++++++++++++++ .../proficiencyEditList.html | 18 ++++ .../proficiencyEditList.js | 24 ++++++ .../proficiencyView/proficiencyView.html | 6 ++ .../proficiencyView/proficiencyView.js | 45 ++++++++++ .../proficiencyViewList.html | 11 +++ .../proficiencyViewList.js | 5 ++ rpg-docs/lib/constants/saves.js | 8 ++ rpg-docs/lib/constants/skills.js | 21 +++++ rpg-docs/server/migrations/migrations.js | 31 +++++++ .../server/publications/singleCharacter.js | 7 +- 20 files changed, 331 insertions(+), 17 deletions(-) create mode 100644 rpg-docs/client/views/character/proficiencies/proficiencyEdit/proficiencyEdit.html create mode 100644 rpg-docs/client/views/character/proficiencies/proficiencyEdit/proficiencyEdit.js create mode 100644 rpg-docs/client/views/character/proficiencies/proficiencyEditList/proficiencyEditList.html create mode 100644 rpg-docs/client/views/character/proficiencies/proficiencyEditList/proficiencyEditList.js create mode 100644 rpg-docs/client/views/character/proficiencies/proficiencyView/proficiencyView.html create mode 100644 rpg-docs/client/views/character/proficiencies/proficiencyView/proficiencyView.js create mode 100644 rpg-docs/client/views/character/proficiencies/proficiencyViewList/proficiencyViewList.html create mode 100644 rpg-docs/client/views/character/proficiencies/proficiencyViewList/proficiencyViewList.js create mode 100644 rpg-docs/lib/constants/saves.js create mode 100644 rpg-docs/lib/constants/skills.js create mode 100644 rpg-docs/server/migrations/migrations.js diff --git a/rpg-docs/.meteor/packages b/rpg-docs/.meteor/packages index a080b530..0d171b6f 100644 --- a/rpg-docs/.meteor/packages +++ b/rpg-docs/.meteor/packages @@ -18,3 +18,4 @@ zimme:collection-softremovable momentjs:moment mike:mocha dburles:mongo-collection-instances +percolate:migrations diff --git a/rpg-docs/.meteor/versions b/rpg-docs/.meteor/versions index 84bcfa86..84f2efa4 100644 --- a/rpg-docs/.meteor/versions +++ b/rpg-docs/.meteor/versions @@ -55,6 +55,7 @@ mongo@1.1.0 npm-bcrypt@0.7.8_2 observe-sequence@1.0.6 ordered-dict@1.0.3 +percolate:migrations@0.7.3 practicalmeteor:chai@1.9.2_3 practicalmeteor:loglevel@1.1.0_3 random@1.0.3 diff --git a/rpg-docs/Model/Character/Characters.js b/rpg-docs/Model/Character/Characters.js index 5389c57c..21a28350 100644 --- a/rpg-docs/Model/Character/Characters.js +++ b/rpg-docs/Model/Character/Characters.js @@ -13,7 +13,6 @@ Schemas.Character = new SimpleSchema({ bonds: { type: String, defaultValue: "", trim: false}, flaws: { type: String, defaultValue: "", trim: false}, backstory: { type: String, defaultValue: "", trim: false}, - proficiencies:{ type: String, defaultValue: "", trim: false}, languages: { type: String, defaultValue: "", trim: false}, //attributes @@ -182,7 +181,7 @@ var attributeBase = function(charId, statName){ //start with the highest base value _.each(effects.base, function(effect){ - var efv = evaluateEffect(charId, effect) + var efv = evaluateEffect(charId, effect); if (efv > value){ value = efv; } @@ -210,7 +209,7 @@ var attributeBase = function(charId, statName){ value = value < max? value : max; }); return value; -} +}; //functions and calculated values. //These functions can only rely on this._id since no other @@ -302,12 +301,10 @@ Characters.helpers({ var charId = this._id; //return largest value in proficiency array var prof = 0; - Effects.find({charId: charId, stat: skillName, enabled: true}).forEach(function(effect){ - if(effect.operation === "proficiency"){ - var newProf = evaluateEffect(charId, effect); - if (newProf > prof){ - prof = newProf; - } + Proficiencies.find({charId: charId, name: skillName, enabled: true}).forEach(function(proficiency){ + var newProf = proficiency.value; + if (newProf > prof){ + prof = newProf; } }); return prof; @@ -317,7 +314,7 @@ Characters.helpers({ if (_.isString(skillName)){ var skill = this.getField(skillName); } - var charId = this._id + var charId = this._id; var mod = +this.skillMod(skillName); var value = 10 + mod; Effects.find({charId: charId, stat: skillName, enabled: true, operation: "passiveAdd"}).forEach(function(effect){ @@ -328,7 +325,7 @@ Characters.helpers({ }, advantage: function(skillName){ - var charId = this._id + var charId = this._id; var advantage = Effects.find({charId: charId, stat: skillName, enabled: true, operation: "advantage"}).count(); var disadvantage = Effects.find({charId: charId, stat: skillName, enabled: true, operation: "disadvantage"}).count(); if(advantage && !disadvantage) return 1; diff --git a/rpg-docs/Model/Character/Proficiencies.js b/rpg-docs/Model/Character/Proficiencies.js index 209b9bea..4e45929a 100644 --- a/rpg-docs/Model/Character/Proficiencies.js +++ b/rpg-docs/Model/Character/Proficiencies.js @@ -7,12 +7,24 @@ Schemas.Proficiency = new SimpleSchema({ }, name: { type: String, - trim: false + trim: false, + optional: true, }, value: { type: Number, - allowedValues: [0, 0.5, 1], + allowedValues: [0, 0.5, 1, 2], + defaultValue: 1, + decimal: true, }, + type: { + type: String, + allowedValues: ["skill", "save", "weapon", "armor", "tool", "language"], + defaultValue: "skill", + }, + enabled: { + type: Boolean, + defaultValue: true, + } }); Proficiencies.attachSchema(Schemas.Proficiency); diff --git a/rpg-docs/client/views/character/effects/effectsEditList/effectsEditList.html b/rpg-docs/client/views/character/effects/effectsEditList/effectsEditList.html index 658b0cae..4b1c7c0d 100644 --- a/rpg-docs/client/views/character/effects/effectsEditList/effectsEditList.html +++ b/rpg-docs/client/views/character/effects/effectsEditList/effectsEditList.html @@ -1,7 +1,7 @@ diff --git a/rpg-docs/client/views/character/journal/classDialog/classDialog.html b/rpg-docs/client/views/character/journal/classDialog/classDialog.html index be7bfc46..e83e5dcb 100644 --- a/rpg-docs/client/views/character/journal/classDialog/classDialog.html +++ b/rpg-docs/client/views/character/journal/classDialog/classDialog.html @@ -7,6 +7,7 @@ {{> effectsEditList parentId=_id parentCollection="Classes" charId=charId}} + {{> proficiencyEditList parentId=_id parentCollection="Characters" charId=charId}} {{/baseDialog}} {{/with}} \ No newline at end of file diff --git a/rpg-docs/client/views/character/journal/raceDialog/raceDialog.html b/rpg-docs/client/views/character/journal/raceDialog/raceDialog.html index f92aa9fb..1c2c18c5 100644 --- a/rpg-docs/client/views/character/journal/raceDialog/raceDialog.html +++ b/rpg-docs/client/views/character/journal/raceDialog/raceDialog.html @@ -2,5 +2,6 @@ {{#baseDialog title="Race" class=colorClass hideColor="true" hideDelete="true"}} {{> effectsEditList parentId=charId parentCollection="Characters" charId=charId}} + {{> proficiencyEditList parentId=charId parentCollection="Characters" charId=charId}} {{/baseDialog}} \ No newline at end of file diff --git a/rpg-docs/client/views/character/proficiencies/proficiencyEdit/proficiencyEdit.html b/rpg-docs/client/views/character/proficiencies/proficiencyEdit/proficiencyEdit.html new file mode 100644 index 00000000..c41e1dfe --- /dev/null +++ b/rpg-docs/client/views/character/proficiencies/proficiencyEdit/proficiencyEdit.html @@ -0,0 +1,43 @@ + + + + + diff --git a/rpg-docs/client/views/character/proficiencies/proficiencyEdit/proficiencyEdit.js b/rpg-docs/client/views/character/proficiencies/proficiencyEdit/proficiencyEdit.js new file mode 100644 index 00000000..0e9c48ab --- /dev/null +++ b/rpg-docs/client/views/character/proficiencies/proficiencyEdit/proficiencyEdit.js @@ -0,0 +1,86 @@ +var profTypes = [ + {type: "skill", name: "Skill"}, + {type: "save", name: "Saving Throw"}, + {type: "weapon", name: "Weapon"}, + {type: "armor", name: "Armor"}, + {type: "tool", name: "Tool"}, + {type: "language", name: "Language"} +]; + +var saves = [ + {name: "Strength Save", stat: "strengthSave"}, + {name: "Dexterity Save", stat: "dexteritySave"}, + {name: "Constitution Save", stat: "constitutionSave"}, + {name: "Intelligence Save", stat: "intelligenceSave"}, + {name: "Wisdom Save", stat: "wisdomSave"}, + {name: "Charisma Save", stat: "charismaSave"}, +]; + +var skills = [ + {name: "Acrobatics", stat: "acrobatics"}, + {name: "Animal Handling", stat: "animalHandling"}, + {name: "Arcana", stat: "arcana"}, + {name: "Athletics", stat: "athletics"}, + {name: "Deception", stat: "deception"}, + {name: "History", stat: "history"}, + {name: "Insight", stat: "insight"}, + {name: "Intimidation", stat: "intimidation"}, + {name: "Investigation", stat: "investigation"}, + {name: "Medicine", stat: "medicine"}, + {name: "Nature", stat: "nature"}, + {name: "Perception", stat: "perception"}, + {name: "Performance", stat: "performance"}, + {name: "Persuasion", stat: "persuasion"}, + {name: "Religion", stat: "religion"}, + {name: "Sleight of Hand", stat: "sleightOfHand"}, + {name: "Stealth", stat: "stealth"}, + {name: "Survival", stat: "survival"}, + {name: "Initiative", stat: "initiative"}, +]; + +Template.proficiencyEdit.helpers({ + proficiencyTypes: function(){ + return profTypes; + }, + nameInputTemplate: function(){ + if(!this.type) return null; + if(this.type === "skill"|| + this.type === "save") return "nameDropdown"; + return "nameInput"; + } +}); + +Template.proficiencyEdit.events({ + "core-select .typeDropDown": function(event){ + var detail = event.originalEvent.detail; + if(!detail.isSelected) return; + var type = detail.item.getAttribute("name"); + if (type == this.type) return; + Proficiencies.update(this._id, {$set: {type: type}}); + }, + "core-select .valueDropDown": function(event){ + var detail = event.originalEvent.detail; + if(!detail.isSelected) return; + var value = +detail.item.getAttribute("name"); + if (value == this.value) return; + Proficiencies.update(this._id, {$set: {value: value}}); + }, + "core-select .nameDropDown": function(event){ + var detail = event.originalEvent.detail; + if(!detail.isSelected) return; + var name = detail.item.getAttribute("name"); + if (name == this.name) return; + Proficiencies.update(this._id, {$set: {name: name}}); + }, + "change .nameInput": function(event){ + var name = event.currentTarget.value; + Proficiencies.update(this._id, {$set: {name: name}}); + } +}); + +Template.nameDropdown.helpers({ + nameDropdownItems: function(){ + if (this.type === "skill") return skills; + if (this.type === "save") return saves; + } +}); \ No newline at end of file diff --git a/rpg-docs/client/views/character/proficiencies/proficiencyEditList/proficiencyEditList.html b/rpg-docs/client/views/character/proficiencies/proficiencyEditList/proficiencyEditList.html new file mode 100644 index 00000000..5d1c9fe5 --- /dev/null +++ b/rpg-docs/client/views/character/proficiencies/proficiencyEditList/proficiencyEditList.html @@ -0,0 +1,18 @@ + + \ No newline at end of file diff --git a/rpg-docs/client/views/character/proficiencies/proficiencyEditList/proficiencyEditList.js b/rpg-docs/client/views/character/proficiencies/proficiencyEditList/proficiencyEditList.js new file mode 100644 index 00000000..60fe8b01 --- /dev/null +++ b/rpg-docs/client/views/character/proficiencies/proficiencyEditList/proficiencyEditList.js @@ -0,0 +1,24 @@ +Template.proficiencyEditList.helpers({ + proficiencies: function(){ + var cursor = Proficiencies.find({"parent.id": this.parentId, "parent.collection": this.parentCollection}); + return cursor; + } +}); + +Template.proficiencyEditList.events({ + "tap #addProficiencyButton": function(){ + if ( !_.isBoolean(this.enabled) ) { + this.enabled = true; + } + Proficiencies.insert({ + charId: this.charId, + parent: { + id: this.parentId, + collection: this.parentCollection + }, + enabled: this.enabled, + value: 1, + type: "skill", + }); + }, +}); diff --git a/rpg-docs/client/views/character/proficiencies/proficiencyView/proficiencyView.html b/rpg-docs/client/views/character/proficiencies/proficiencyView/proficiencyView.html new file mode 100644 index 00000000..d9a27836 --- /dev/null +++ b/rpg-docs/client/views/character/proficiencies/proficiencyView/proficiencyView.html @@ -0,0 +1,6 @@ + diff --git a/rpg-docs/client/views/character/proficiencies/proficiencyView/proficiencyView.js b/rpg-docs/client/views/character/proficiencies/proficiencyView/proficiencyView.js new file mode 100644 index 00000000..85a0b89b --- /dev/null +++ b/rpg-docs/client/views/character/proficiencies/proficiencyView/proficiencyView.js @@ -0,0 +1,45 @@ +var saves = { + strengthSave: "Strength Save", + dexteritySave: "Dexterity Save", + constitutionSave: "Constitution Save", + intelligenceSave: "Intelligence Save", + wisdomSave: "Wisdom Save", + charismaSave: "Charisma Save", +}; + +var skills = { + acrobatics: "Acrobatics", + animalHandling: "Animal Handling", + arcana: "Arcana", + athletics: "Athletics", + deception: "Deception", + history: "History", + insight: "Insight", + intimidation: "Intimidation", + investigation: "Investigation", + medicine: "Medicine", + nature: "Nature", + perception: "Perception", + performance: "Performance", + persuasion: "Persuasion", + religion: "Religion", + sleightOfHand: "Sleight of Hand", + stealth: "Stealth", + survival: "Survival", + initiative: "Initiative", +}; + +Template.proficiencyView.helpers({ + profIcon: function(){ + var prof = this.value; + if(prof > 0 && prof < 1) return "image:brightness-2"; + if(prof === 1) return "image:brightness-1"; + if(prof > 1) return "av:album"; + return "radio-button-off"; + }, + getName: function(){ + if(this.type === "skill") return skills[this.name]; + if(this.type === "save") return saves[this.name]; + return this.name; + } +}); diff --git a/rpg-docs/client/views/character/proficiencies/proficiencyViewList/proficiencyViewList.html b/rpg-docs/client/views/character/proficiencies/proficiencyViewList/proficiencyViewList.html new file mode 100644 index 00000000..1a54310c --- /dev/null +++ b/rpg-docs/client/views/character/proficiencies/proficiencyViewList/proficiencyViewList.html @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/rpg-docs/client/views/character/proficiencies/proficiencyViewList/proficiencyViewList.js b/rpg-docs/client/views/character/proficiencies/proficiencyViewList/proficiencyViewList.js new file mode 100644 index 00000000..c343751c --- /dev/null +++ b/rpg-docs/client/views/character/proficiencies/proficiencyViewList/proficiencyViewList.js @@ -0,0 +1,5 @@ +Template.proficiencyViewList.helpers({ + proficiencies: function(){ + return Proficiencies.find({"parent.id": this.parentId, charId: this.charId}); + } +}); diff --git a/rpg-docs/lib/constants/saves.js b/rpg-docs/lib/constants/saves.js new file mode 100644 index 00000000..ba0d2618 --- /dev/null +++ b/rpg-docs/lib/constants/saves.js @@ -0,0 +1,8 @@ +SAVES = [ + "strengthSave", + "dexteritySave", + "constitutionSave", + "intelligenceSave", + "wisdomSave", + "charismaSave", +]; diff --git a/rpg-docs/lib/constants/skills.js b/rpg-docs/lib/constants/skills.js new file mode 100644 index 00000000..ae7512ae --- /dev/null +++ b/rpg-docs/lib/constants/skills.js @@ -0,0 +1,21 @@ +SKILLS = [ + "acrobatics", + "animalHandling", + "arcana", + "athletics", + "deception", + "history", + "insight", + "intimidation", + "investigation", + "medicine", + "nature", + "perception", + "performance", + "persuasion", + "religion", + "sleightOfHand", + "stealth", + "survival", + "initiative", +]; \ No newline at end of file diff --git a/rpg-docs/server/migrations/migrations.js b/rpg-docs/server/migrations/migrations.js new file mode 100644 index 00000000..36f1f0cf --- /dev/null +++ b/rpg-docs/server/migrations/migrations.js @@ -0,0 +1,31 @@ +Migrations.add({ + version: 1, + up: function() { + return; + } +}); + +Migrations.add({ + version: 2, + name: "converts effect proficiencies to proficiency objects", + up: function() { + Effects.find({operation: "proficiency"}).forEach(function(effect){ + var type; + if(_.contains(SKILLS, effect.stat)) type = "skill"; + if(_.contains(SAVES, effect.stat)) type = "save"; + if(!type) throw "stat not a skill or a save"; + Proficiencies.insert({ + charId: effect.charId, + name: effect.stat, + value: effect.value, + parent: effect.parent, + type: type, + enabled: effect.enabled + }); + Effects.remove(effect._id); + }); + }, + down: function(){ + return; + } +}); diff --git a/rpg-docs/server/publications/singleCharacter.js b/rpg-docs/server/publications/singleCharacter.js index 823478cd..57f847ea 100644 --- a/rpg-docs/server/publications/singleCharacter.js +++ b/rpg-docs/server/publications/singleCharacter.js @@ -3,9 +3,9 @@ Meteor.publish("singleCharacter", function(characterId, userId){ Characters.findOne({ _id: characterId, $or: [ - {readers: userId}, - {writers: userId}, - {owner: userId} + {readers: userId}, + {writers: userId}, + {owner: userId} ] }) ){ @@ -24,6 +24,7 @@ Meteor.publish("singleCharacter", function(characterId, userId){ Spells.find ({charId: characterId}, {removed: true}), SpellLists.find ({charId: characterId}, {removed: true}), TemporaryHitPoints.find({charId: characterId}, {removed: true}), + Proficiencies.find ({charId: characterId}, {removed: true}), ]; } });