diff --git a/README.md b/README.md index 4a9302cb..8a410eeb 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ TODO ==== -Strip the core interaction out of swipe-pages to create an element that just listens to swipe events - -wishlist: - -* swipes are emitted as an event if possible -* swiping should translate the element -* it should bounce back to its resting position when released +* Get Polymer installed using bower. +* Install Vulcanize package listed below +* Copy the differential polymer demo to get polymer implemented nicely +* Update Meteor +* Install and use LESS Packages used ============= @@ -48,8 +46,13 @@ Packages used * aldeed:autoform * Automatically generates bootstrap forms for collection2 Schemas. * [github](https://github.com/aldeed/meteor-autoform) +* differential:vulcanize + * Bakes all the polymer imports into one file + * [github](https://github.com/Differential/meteor-vulcanize) ************ - -To Speed up builds when you know you wont need online package checking use -METEOR_OFFLINE_CATALOG=1 \ No newline at end of file + +Resources +========= + +[differential's polymer demo](https://github.com/Differential/polymer-demo) diff --git a/rpg-docs/.bowerrc b/rpg-docs/.bowerrc new file mode 100644 index 00000000..1ad2d4f1 --- /dev/null +++ b/rpg-docs/.bowerrc @@ -0,0 +1 @@ +{"directory":"public/components/"} \ No newline at end of file diff --git a/rpg-docs/.gitignore b/rpg-docs/.gitignore new file mode 100644 index 00000000..3ba35773 --- /dev/null +++ b/rpg-docs/.gitignore @@ -0,0 +1,3 @@ +.meteor/local +.meteor/meteorite +public/components \ No newline at end of file diff --git a/rpg-docs/.meteor/release b/rpg-docs/.meteor/release index f1b62559..fdc65835 100644 --- a/rpg-docs/.meteor/release +++ b/rpg-docs/.meteor/release @@ -1 +1 @@ -METEOR@1.0.1 +METEOR@1.0.2.1 diff --git a/rpg-docs/.meteor/versions b/rpg-docs/.meteor/versions index 7d59a45b..3e9dd96c 100644 --- a/rpg-docs/.meteor/versions +++ b/rpg-docs/.meteor/versions @@ -1,77 +1,74 @@ -accounts-base@1.1.2 -accounts-password@1.0.4 -accounts-ui-unstyled@1.1.4 -accounts-ui@1.1.3 -aldeed:autoform@4.1.0 -aldeed:collection2@2.2.0 +accounts-base@1.1.3 +accounts-password@1.0.5 +accounts-ui@1.1.4 +accounts-ui-unstyled@1.1.5 +aldeed:autoform@4.2.2 +aldeed:collection2@2.3.0 aldeed:simple-schema@1.1.0 -application-configuration@1.0.3 -autoupdate@1.1.3 -base64@1.0.1 -binary-heap@1.0.1 -blaze-tools@1.0.1 -blaze@2.0.3 -boilerplate-generator@1.0.1 -callback-hook@1.0.1 -check@1.0.2 -ctl-helper@1.0.4 -ctl@1.0.2 +application-configuration@1.0.4 +autoupdate@1.1.4 +base64@1.0.2 +binary-heap@1.0.2 +blaze@2.0.4 +blaze-tools@1.0.2 +boilerplate-generator@1.0.2 +callback-hook@1.0.2 +check@1.0.3 cw4gn3r:jquery-event-drag@2.2.0 -dburles:collection-helpers@1.0.1 -ddp@1.0.12 -deps@1.0.5 -ejson@1.0.4 -email@1.0.4 -fastclick@1.0.1 -follower-livedata@1.0.2 -geojson-utils@1.0.1 -html-tools@1.0.2 -htmljs@1.0.2 -http@1.0.8 -id-map@1.0.1 -insecure@1.0.1 -iron:controller@1.0.3 -iron:core@1.0.3 -iron:dynamic-template@1.0.3 -iron:layout@1.0.3 -iron:location@1.0.3 -iron:middleware-stack@1.0.3 -iron:router@1.0.3 -iron:url@1.0.3 -jquery@1.0.1 -json@1.0.1 -launch-screen@1.0.0 -less@1.0.11 -livedata@1.0.11 -localstorage@1.0.1 -logging@1.0.5 -meteor-platform@1.2.0 -meteor@1.1.3 -minifiers@1.1.2 -minimongo@1.0.5 -mobile-status-bar@1.0.1 -mongo-livedata@1.0.6 -mongo@1.0.9 -mrt:moment@2.6.0 +dburles:collection-helpers@1.0.2 +ddp@1.0.13 +deps@1.0.6 +ejson@1.0.5 +email@1.0.5 +fastclick@1.0.2 +follower-livedata@1.0.3 +geojson-utils@1.0.2 +html-tools@1.0.3 +htmljs@1.0.3 +http@1.0.9 +id-map@1.0.2 +insecure@1.0.2 +iron:controller@1.0.6 +iron:core@1.0.6 +iron:dynamic-template@1.0.6 +iron:layout@1.0.6 +iron:location@1.0.6 +iron:middleware-stack@1.0.6 +iron:router@1.0.6 +iron:url@1.0.6 +jquery@1.0.2 +json@1.0.2 +launch-screen@1.0.1 +less@1.0.12 +livedata@1.0.12 +localstorage@1.0.2 +logging@1.0.6 +meteor@1.1.4 +meteor-platform@1.2.1 +minifiers@1.1.3 +minimongo@1.0.6 +mobile-status-bar@1.0.2 +momentjs:moment@2.8.4 +mongo@1.0.11 npm-bcrypt@0.7.7 -observe-sequence@1.0.3 -ordered-dict@1.0.1 -random@1.0.1 -reactive-dict@1.0.4 -reactive-var@1.0.3 -reload@1.1.1 -retry@1.0.1 -routepolicy@1.0.2 -service-configuration@1.0.2 -session@1.0.4 -sha@1.0.1 -spacebars-compiler@1.0.3 -spacebars@1.0.3 -srp@1.0.1 -templating@1.0.9 -tracker@1.0.3 -ui@1.0.4 -underscore@1.0.1 -url@1.0.2 -webapp-hashing@1.0.1 -webapp@1.1.4 +observe-sequence@1.0.4 +ordered-dict@1.0.2 +random@1.0.2 +reactive-dict@1.0.5 +reactive-var@1.0.4 +reload@1.1.2 +retry@1.0.2 +routepolicy@1.0.3 +service-configuration@1.0.3 +session@1.0.5 +sha@1.0.2 +spacebars@1.0.4 +spacebars-compiler@1.0.4 +srp@1.0.2 +templating@1.0.10 +tracker@1.0.4 +ui@1.0.5 +underscore@1.0.2 +url@1.0.3 +webapp@1.1.5 +webapp-hashing@1.0.2 diff --git a/rpg-docs/Model/Character/Characters.js b/rpg-docs/Model/Character/Characters.js index cc9c085e..e0cd5b2c 100644 --- a/rpg-docs/Model/Character/Characters.js +++ b/rpg-docs/Model/Character/Characters.js @@ -37,7 +37,7 @@ Schemas.Character = new SimpleSchema({ "proficiencyBonus.effects": { type: [Schemas.Effect], defaultValue: [ - {name: "Proficiency bonus by level", calculation: "floor(level / 4.1) + 2", operation: "add", type: "inate"} + {name: "Proficiency bonus by level", calculation: "floor(level / 4 + 1.75)", operation: "add", type: "inate"} ] }, speed: {type: Schemas.Attribute}, @@ -68,6 +68,8 @@ Schemas.Character = new SimpleSchema({ superiorityDice: {type: Schemas.Attribute}, expertiseDice: {type: Schemas.Attribute}, + //specific features + rageDamage: {type: Schemas.Attribute}, //hit dice d6HitDice: {type: Schemas.Attribute}, @@ -174,52 +176,24 @@ Schemas.Character = new SimpleSchema({ strengthAttack: {type: Schemas.Skill}, "strengthAttack.ability": {type: String,defaultValue: "strength"}, - "strengthAttack.effects": { - type: [Schemas.Effect], - defaultValue: [{name: "Attack Proficiency", value: 1, operation: "proficiency", type: "inate"}] - }, dexterityAttack: {type: Schemas.Skill}, "dexterityAttack.ability": { type: String, defaultValue: "dexterity" }, - "dexterityAttack.proficiency": { - type: [Schemas.Effect], - defaultValue: [{name: "Attack Proficiency", value: 1, operation: "proficiency", type: "inate"}] - }, constitutionAttack: {type: Schemas.Skill}, "constitutionAttack.ability":{ type: String, defaultValue: "constitution" }, - "constitutionAttack.proficiency": { - type: [Schemas.Effect], - defaultValue: [{name: "Attack Proficiency", value: 1, operation: "proficiency", type: "inate"}] - }, intelligenceAttack: {type: Schemas.Skill}, "intelligenceAttack.ability":{ type: String, defaultValue: "intelligence" }, - "intelligenceAttack.proficiency": { - type: [Schemas.Effect], - defaultValue: [{name: "Attack Proficiency", value: 1, operation: "proficiency", type: "inate"}] - }, wisdomAttack: {type: Schemas.Skill}, "wisdomAttack.ability": { type: String, defaultValue: "wisdom" }, - "wisdomAttack.proficiency": { - type: [Schemas.Effect], - defaultValue: [{name: "Attack Proficiency", value: 1, operation: "proficiency", type: "inate"}] - }, charismaAttack: {type: Schemas.Skill}, "charismaAttack.ability": { type: String, defaultValue: "charisma" }, - "charismaAttack.proficiency": { - type: [Schemas.Effect], - defaultValue: [{name: "Attack Proficiency", value: 1, operation: "proficiency", type: "inate"}] - }, rangedAttack: {type: Schemas.Skill}, "rangedAttack.ability": { type: String, defaultValue: "dexterity" }, - "rangedAttack.proficiency": { - type: [Schemas.Effect], - defaultValue: [{name: "Attack Proficiency", value: 1, operation: "proficiency", type: "inate"}] - }, dexterityArmor: {type: Schemas.Skill}, "dexterityArmor.ability": { type: String, defaultValue: "dexterity" }, @@ -239,19 +213,22 @@ Schemas.Character = new SimpleSchema({ }, //mechanics - features: { type: [Schemas.Feature], defaultValue: []}, + features: { type: [String], defaultValue: [], regEx: SimpleSchema.RegEx.Id,}, + customFeatures: { type: [Schemas.Feature], defaultValue: []}, + actions: { type: [Schemas.Action], defaultValue: []}, deathSave: { type: Schemas.DeathSave }, time: { type: Number, min: 0, decimal: true, defaultValue: 0}, initiativeOrder:{ type: Number, min: 0, max: 1, decimal: true, defaultValue: 0}, - expirations: { type: [Schemas.Expiration], defaultValue: []}, - spells: { type: [Schemas.Spell], defaultValue: []} + buffs: { type: [Schemas.Buff], defaultValue: []} //TODO add permission stuff for owner, readers and writers + //TODO add per-character settings }); Characters.attachSchema(Schemas.Character); //reactively remove expired effects -//this can be optimised a lot once clients can do projections +//TODO broken with the move from expirations -> buffs +//TODO fix by finding every buff whose expiry is >= current time, pull those buffs Characters.find({},{fields: {time: 1, expirations: 1, features: 1}}).observe({ changed: function(character){ var currentTime = character.time; @@ -276,25 +253,38 @@ Characters.find({},{fields: {time: 1, expirations: 1, features: 1}}).observe({ }); var attributeBase = function(charId, attribute){ + var effects = _.groupBy(attribute.effects, "operation"); var value = 0; - _.each(attribute.effects, function(effect){ - switch(effect.operation) { - case "add": - value += evaluateEffect(charId, effect); - break; - case "mul": - value *= evaluateEffect(charId, effect); - break; - case "min": - var min = evaluateEffect(charId, effect); - value = value > min? value : min; - break; - case "max": - var max = evaluateEffect(charId, effect); - value = value < max? value : max; - break; + + //start with the highest base value + _.each(effects.base, function(effect){ + var efv = evaluateEffect(charId, effect) + if (effect.value > value){ + value = effect.value; } }); + + //add all the add values + _.each(effects.add, function(effect){ + value += evaluateEffect(charId, effect); + }); + + //multiply all the mul values + _.each(effects.mul, function(effect){ + value *= evaluateEffect(charId, effect); + }); + + //ensure value is >= all mins + _.each(effects.min, function(effect){ + var min = evaluateEffect(charId, effect); + value = value > min? value : min; + }); + + //ensure value is <= all maxes + _.each(effects.max, function(effect){ + var max = evaluateEffect(charId, effect); + value = value < max? value : max; + }); return value; } @@ -309,7 +299,7 @@ Characters.helpers({ fieldSelector[fieldName] = 1; var char = Characters.findOne(this._id, {fields: fieldSelector}); var field = char[fieldName]; - if(!field){ + if(field === undefined){ throw new Meteor.Error("getField failed", "getField could not find field " + fieldName + " in character "+ char._id); } @@ -333,35 +323,15 @@ Characters.helpers({ return this.getField(fieldName); }, - attributeValue: (function(){ - //store a private array of attributes we've visited without returning - //if we try to visit the same attribute twice before resolving its value - //we are in a dependency loop and need to GTFO - var visitedAttributes = []; - return function(attributeName){ - check(attributeName, String); - //we're still evaluating this attribute, must be in a loop - if(_.contains(visitedAttributes, attributeName)) { - console.log("dependency loop detected"); - return NaN; - } - //push this attribute to the list of visited attributes - //we can't visit it again unless it returns first - visitedAttributes.push(attributeName); - - try{ - var charId = this._id; - var attribute = this.getField(attributeName); - //base value - var value = attributeBase(charId, attribute); - value += attribute.adjustment; - }finally{ - //this attribute returns or fails, pull it from the array, we may visit it again safely - visitedAttributes = _.without(visitedAttributes, attributeName); - } - return value; - } - })(), + attributeValue: function(attributeName){ + var charId = this._id; + var attribute = this.getField(attributeName); + //base value + var value = this.attributeBase(attributeName); + //plus adjustment + value += attribute.adjustment; + return value; + }, attributeBase: (function(){ //store a private array of attributes we've visited without returning diff --git a/rpg-docs/Model/Character/Features.js b/rpg-docs/Model/Character/Features.js new file mode 100644 index 00000000..b7f545a3 --- /dev/null +++ b/rpg-docs/Model/Character/Features.js @@ -0,0 +1,42 @@ +//Features are features that can be selected but not edited +//they are the things that come in the player's handbook and +//facilitate the quick building of characters +//They are the primary means of collecting cease and desist letters :( +// +//Should only be edited by admins +// +//TODO add a Meteor Method that lets users add a feature to their character +//and pushes the effects and actions accordingly +// +//TODO add a Method that updates every character with a given feature if that feature should change + +Features = new Meteor.Collection("features"); + +Schemas.Feature = new SimpleSchema({ + _id: { + type: String, + regEx: SimpleSchema.RegEx.Id, + autoValue: function(){ + if(!this.isSet) return Random.id(); + } + }, + name: {type: String}, + description:{type: String, optional: true}, + source: {type: String, optional: true}, + effects: {type: [Schemas.Effect], defaultValue: []}, + actions: {type: [Schemas.Action], defaultValue: []}, + attacks: {type: [Schemas.Attack], defaultValue: []}, + spells: {type: [Schemas.Spell] , defaultValue: []}, +}); + +Features.attachSchema(Schemas.Feature); + +//observe standard features for changes and update characters using them +Features.find().observe({ + changed: function(newFeature, oldFeature){ + //TODO + }, + removed: function(oldFeature){ + //TODO + } +}); \ No newline at end of file diff --git a/rpg-docs/Model/Character/SubSchemas/Action.js b/rpg-docs/Model/Character/SubSchemas/Action.js new file mode 100644 index 00000000..a3796b12 --- /dev/null +++ b/rpg-docs/Model/Character/SubSchemas/Action.js @@ -0,0 +1,29 @@ +/* + * Actions are given to a character by items and features + */ +Schemas.Action = new SimpleSchema({ + _id: { + type: String, + regEx: SimpleSchema.RegEx.Id, + autoValue: function(){ + if(!this.isSet) return Random.id(); + } + }, + name: { + type: String + }, + description: { + type: String + }, + type: { + type: String, + allowedValues: ["action, bonus, reaction, free"], + defaultValue: "action" + }, + selfBuffs: { + type: [Schemas.Buff], defaultValue: [] + }, + selfAdjustments: { + type: [Schemas.Adjustment], defaultValue: [] + } +}); \ No newline at end of file diff --git a/rpg-docs/Model/Character/SubSchemas/Adjustment.js b/rpg-docs/Model/Character/SubSchemas/Adjustment.js new file mode 100644 index 00000000..0b4623fd --- /dev/null +++ b/rpg-docs/Model/Character/SubSchemas/Adjustment.js @@ -0,0 +1,25 @@ +/* + * Adjustments make instantaneous changes to the value of some attribute + * Damage, healing and resource cost/recovery are all adjustments + */ +Schemas.Adjustment = new SimpleSchema({ + name: { + type: String, + optional: true + }, + //which stat the adjustment is applied to + stat: { + type: String, + optional: true + }, + //the value added to the stat + value: { + type: Number, + decimal: true, + optional: true + }, + calculation: { + type: String, + optional: true + } +}); \ No newline at end of file diff --git a/rpg-docs/Model/Character/SubSchemas/Attack.js b/rpg-docs/Model/Character/SubSchemas/Attack.js new file mode 100644 index 00000000..0c04b263 --- /dev/null +++ b/rpg-docs/Model/Character/SubSchemas/Attack.js @@ -0,0 +1,31 @@ +/* + * Attacks are given to a character by items and features + */ +Schemas.Attack = new SimpleSchema({ + _id: { + type: String, + regEx: SimpleSchema.RegEx.Id, + autoValue: function(){ + if(!this.isSet) return Random.id(); + } + }, + name: { + type: String + }, + range: { + type: String, + optional: true + }, + attackBonus: { + type: String, + optional: true + }, + damage: { + type: String + }, + damageType: { + type: String, + allowedValues: ["acid", "bludgeoning", "cold", "fire", "force", "lightning", "necrotic", + "piercing", "poison", "psychic", "radiant", "slashing", "thunder"] + } +}); \ No newline at end of file diff --git a/rpg-docs/Model/Character/SubSchemas/Buff.js b/rpg-docs/Model/Character/SubSchemas/Buff.js new file mode 100644 index 00000000..f658da52 --- /dev/null +++ b/rpg-docs/Model/Character/SubSchemas/Buff.js @@ -0,0 +1,18 @@ +//buffs are temporary once applied and store things which expire and their expiry time +Schemas.Buff = new SimpleSchema({ + //buff id + _id: { + type: String, + regEx: SimpleSchema.RegEx.Id, + autoValue: function(){ + if(!this.isSet) return Random.id(); + }}, + + //things that expire + effects: { type: [Schemas.Effect], defaultValue: [] }, + actions: { type: [Schemas.Action], defaultValue: [] }, + + //expiry time + expiry: { type: Number, optional: true}, + duration: { type: Number } +}); diff --git a/rpg-docs/Model/Character/SubSchemas/Effect/Effect.js b/rpg-docs/Model/Character/SubSchemas/Effect.js similarity index 68% rename from rpg-docs/Model/Character/SubSchemas/Effect/Effect.js rename to rpg-docs/Model/Character/SubSchemas/Effect.js index 4a858dae..82b4474f 100644 --- a/rpg-docs/Model/Character/SubSchemas/Effect/Effect.js +++ b/rpg-docs/Model/Character/SubSchemas/Effect.js @@ -1,5 +1,5 @@ /* - * Effects are reason-value pairs attached to skills and abilities + * Effects are reason-value attached to skills and abilities * that modify their final value or presentation in some way */ Schemas.Effect = new SimpleSchema({ @@ -16,7 +16,7 @@ Schemas.Effect = new SimpleSchema({ operation: { type: String, defaultValue: "add", - allowedValues: ["proficiency","add","mul","min","max","advantage","disadvantage","passiveAdd","fail","conditional","passiveAdd"] + allowedValues: ["base", "proficiency","add","mul","min","max","advantage","disadvantage","passiveAdd","fail","conditional","passiveAdd"] }, value: { type: Number, @@ -32,5 +32,10 @@ Schemas.Effect = new SimpleSchema({ type: String, defaultValue: "editable", allowedValues: ["editable", "feat", "buff", "equipment", "inate"] + }, + //which stat the effect is applied to + stat: { + type: String, + optional: true } }); \ No newline at end of file diff --git a/rpg-docs/Model/Character/SubSchemas/Effect/Buff.js b/rpg-docs/Model/Character/SubSchemas/Effect/Buff.js deleted file mode 100644 index cbe993d0..00000000 --- a/rpg-docs/Model/Character/SubSchemas/Effect/Buff.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * A buff becomes an effect when applied on a creature. - * It is the effect plus the stat to which it should be applied - */ -Schemas.Buff = new SimpleSchema({ - stat: { - type: String - }, - effect: { - type: Schemas.Effect - } -}); \ No newline at end of file diff --git a/rpg-docs/Model/Character/SubSchemas/Effect/Vulnerability.js b/rpg-docs/Model/Character/SubSchemas/Effect/Vulnerability.js deleted file mode 100644 index e69de29b..00000000 diff --git a/rpg-docs/Model/Character/SubSchemas/Expiration.js b/rpg-docs/Model/Character/SubSchemas/Expiration.js deleted file mode 100644 index 349a44cb..00000000 --- a/rpg-docs/Model/Character/SubSchemas/Expiration.js +++ /dev/null @@ -1,13 +0,0 @@ -//schema to store all effects which expire and their expiry dates -Schemas.Expiration = new SimpleSchema({ - _id: { - type: String, - regEx: SimpleSchema.RegEx.Id, - autoValue: function(){ - if(!this.isSet) return Random.id(); - }}, - stat: { type: String }, - effectIds: { type: [String], regEx: SimpleSchema.RegEx.Id }, - featureIds:{ type: [String], regEx: SimpleSchema.RegEx.Id }, - expiry: { type: Number } -}); diff --git a/rpg-docs/Model/Character/SubSchemas/Feature.js b/rpg-docs/Model/Character/SubSchemas/Feature.js deleted file mode 100644 index d0ed7156..00000000 --- a/rpg-docs/Model/Character/SubSchemas/Feature.js +++ /dev/null @@ -1,22 +0,0 @@ -Schemas.Feature = new SimpleSchema({ - _id: { - type: String, - regEx: SimpleSchema.RegEx.Id, - autoValue: function(){ - if(!this.isSet) return Random.id(); - } - }, - name: {type: String}, - description:{type: String}, - source: {type: String}, - buffs: {type: [Schemas.Buff], defaultValue: []}, - enabled: {type: Boolean, defaultValue: false}, - duration: {type: Number, optional: true}, - uses: {type: Number, min: 0, optional: true}, - maxUses: {type: Number, min: 0, optional: true}, - reset: { - type: String, - optional: true, - allowedValues: ["longRest", "shortRest"] - } -}); diff --git a/rpg-docs/Model/Character/SubSchemas/Spell.js b/rpg-docs/Model/Character/SubSchemas/Spell.js index 927d3eb5..520ae054 100644 --- a/rpg-docs/Model/Character/SubSchemas/Spell.js +++ b/rpg-docs/Model/Character/SubSchemas/Spell.js @@ -13,8 +13,10 @@ Schemas.Spell = new SimpleSchema({ duration: {type: Number}, "components.verbal": {type: Boolean}, "components.somatic": {type: Boolean}, - "components.material": {type: String}, + "components.material": {type: String, optional: true}, "components.concentration": {type: Boolean}, - buffs: {type: [Schemas.Buff], optional: true}, + ritual: {type: Boolean}, + selfBuffs: {type: [Schemas.Buff], defaultValue: []}, level: {type: Number}, + class: {type: String} }); \ No newline at end of file diff --git a/rpg-docs/Model/Inventory/Items.js b/rpg-docs/Model/Inventory/Items.js index ea6bfa42..3b231f23 100644 --- a/rpg-docs/Model/Inventory/Items.js +++ b/rpg-docs/Model/Inventory/Items.js @@ -4,18 +4,42 @@ Schemas.Item = new SimpleSchema({ name: {type: String, defaultValue: "New Item"}, plural: {type: String, optional: true}, description:{type: String, defaultValue: ""}, - container: {type: String, regEx: SimpleSchema.RegEx.Id}, + container: {type: String}, //id of container it normally is stowed in + character: {type: String, regEx: SimpleSchema.RegEx.Id}, //id of owner quantity: {type: Number, min: 0, defaultValue: 1}, weight: {type: Number, min: 0, defaultValue: 0, decimal: true}, value: {type: Number, min: 0, defaultValue: 0, decimal: true}, tradeGood: {type: Boolean, defaultValue: false}, stackable: {type: Boolean, defaultValue: false}, - buffs: {type: [Schemas.Buff], defaultValue: []}, - equipmentSlot: {type: String, defaultValue: "", allowedValues: ["head", "body", "arms", "hands", "held", "feet"]}, + feature: {type: Schemas.Feature}, + equipmentSlot: { + type: String, + defaultValue: "none", + allowedValues: ["none", "head", "armor", "arms", "hands", "held", "feet"] + }, + equipped: {type: Boolean, defaultValue: false} }); Items.attachSchema(Schemas.Item); +//update the features of the items as needed +Items.find({}, {fields: {feature: 1, character: 1, equipped: 1}}).observe({ + added: function(newItem){ + if(newItem.feature && newItem.character) + addFeatureEffects(newItem.character, newItem.feature); + }, + changed: function(newItem, oldItem){ + if(oldItem.feature && oldItem.character) + removeFeatureEffects(oldItem.character, oldItem.feature); + if(newItem.feature && newItem.character) + addFeatureEffects(newItem.character, newItem.feature); + }, + removed: function(oldItem){ + if(oldItem.feature && oldItem.character) + removeFeatureEffects(oldItem.character, oldItem.feature); + } +}); + Items.helpers({ totalValue: function(){ return this.value * this.quantity; diff --git a/rpg-docs/bower.json b/rpg-docs/bower.json new file mode 100644 index 00000000..5b99a63a --- /dev/null +++ b/rpg-docs/bower.json @@ -0,0 +1,25 @@ +{ + "name": "RPG Docs", + "version": "0.0.0", + "homepage": "", + "authors": ["Stefan Zermatten"], + "license": "none", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "polymer": "Polymer/polymer#~0.5.2", + "core-elements": "Polymer/core-elements#~0.5.2", + "paper-elements": "Polymer/paper-elements#~0.5.2" + }, + "resolutions": { + "core-component-page": "^0.5.0", + "polymer": "^0.5.0", + "webcomponentsjs": "^0.5.0" + } +} \ No newline at end of file diff --git a/rpg-docs/client/views/GeneralCSS/general.css b/rpg-docs/client/views/GeneralCSS/general.css index d961f5eb..18d6b9e9 100644 --- a/rpg-docs/client/views/GeneralCSS/general.css +++ b/rpg-docs/client/views/GeneralCSS/general.css @@ -58,7 +58,6 @@ paper-button { } .card { - width: 148px; margin: 4px; padding: 16px; font-size: 14px; @@ -67,7 +66,7 @@ paper-button { } .card.double { - width: 304px; + width: 332px; } .card paper-button { diff --git a/rpg-docs/client/views/GeneralCSS/typography.css b/rpg-docs/client/views/GeneralCSS/typography.css index d7d9d08e..ba8cec3e 100644 --- a/rpg-docs/client/views/GeneralCSS/typography.css +++ b/rpg-docs/client/views/GeneralCSS/typography.css @@ -31,7 +31,7 @@ h1, .headline { letter-spacing: 0; } -.white-text h1, .white-text .headline{ +.white-text h1, .white-text .headline, .white-text.headline{ color: rgba(255,255,255,0.87); } diff --git a/rpg-docs/client/views/character/Features/features.html b/rpg-docs/client/views/character/Features/features.html deleted file mode 100644 index 853f5fbd..00000000 --- a/rpg-docs/client/views/character/Features/features.html +++ /dev/null @@ -1,8 +0,0 @@ - \ No newline at end of file diff --git a/rpg-docs/client/views/character/Stats/stats.css b/rpg-docs/client/views/character/Stats/stats.css index e2d44935..d249b7d1 100644 --- a/rpg-docs/client/views/character/Stats/stats.css +++ b/rpg-docs/client/views/character/Stats/stats.css @@ -11,6 +11,7 @@ #stats .card { flex-grow: 1; + max-width: 480px; } #stats .abilityFlex{ @@ -25,6 +26,26 @@ flex-grow: 1; } +.attribute.card, .skill.card { + padding: 0; + display: flex; + flex-direction: column; + text-align: center; +} + +.card-top { + flex-grow: 1; + padding: 16px; + border-radius: 2px 2px 0 0; + display: flex; + align-items: center; + justify-content: center; +} + +.card .subhead { + padding: 16px; +} + .editEffect > * { vertical-align: bottom; } @@ -35,6 +56,14 @@ padding: 16px; } +#armorHeading { + background: url(/jpg/rusted-metal-armor.jpg) no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + #detailContainer { position: fixed; display: flex; diff --git a/rpg-docs/client/views/character/Stats/stats.html b/rpg-docs/client/views/character/Stats/stats.html index 63967878..b57633bb 100644 --- a/rpg-docs/client/views/character/Stats/stats.html +++ b/rpg-docs/client/views/character/Stats/stats.html @@ -4,73 +4,6 @@
{{> abilityCards}}
-
- -

{{attributeValue "armor"}}

-

Armor

-
- -

{{skillMod "initiative"}}

-

Initiative

-
- -

{{attributeValue "proficiencyBonus"}}

-

Proficiency Bonus

-
- -

{{attributeValue "speed"}}

-

Speed

-
- -

{{passiveSkill "perception"}}

-

Passive Perception

-
- -

- {{> hitDice hitDice="d6HitDice" d="6"}} -

-

- {{> hitDice hitDice="d8HitDice" d="8"}} -

-

- {{> hitDice hitDice="d10HitDice" d="10"}} -

-

- {{> hitDice hitDice="d12HitDice" d="12"}} -

-

Hit Dice

-
- {{# if canCast}} - -

{{> spellSlots}}

-

Spell Slots

-
- {{/if}} - {{# if attributeBase "rages"}} - -

{{attributeValue "rages"}}

-

rages

-
- {{/if}} - {{# if attributeBase "sorceryPoints"}} - -

{{attributeValue "sorceryPoints"}}

-

Sorcery Points

-
- {{/if}} - {{# if attributeBase "expertiseDice"}} - -

{{attributeValue "expertiseDice"}}

-

Expertise Dice

-
- {{/if}} - {{# if attributeBase "superiorityDice"}} - -

{{attributeValue "superiorityDice"}}

-

Superiority Dice

-
- {{/if}} -
@@ -80,12 +13,6 @@ - - + + @@ -90,7 +103,7 @@ {{> skillRow name="Animal Handling" skill="animalHandling"}} {{> skillRow name="Insight" skill="insight"}} {{> skillRow name="Medicine" skill="medicine"}} - {{> skillRow name="Perception" skill="perception"}} + {{> skillRow name="Perception" skill="perception" showPassive="true"}} {{> skillRow name="Survival" skill="survival"}} @@ -114,3 +127,9 @@ + + \ No newline at end of file diff --git a/rpg-docs/client/views/character/characterSheet.html b/rpg-docs/client/views/character/characterSheet.html index b5b28d97..3d3a82ff 100644 --- a/rpg-docs/client/views/character/characterSheet.html +++ b/rpg-docs/client/views/character/characterSheet.html @@ -3,7 +3,6 @@ Stats Features Inventory - Proficiency Bonus Spellbook Persona Journal @@ -11,7 +10,7 @@ {{> stats}} - features + {{> features}} inventory spellBook persona diff --git a/rpg-docs/client/views/character/features/features.html b/rpg-docs/client/views/character/features/features.html new file mode 100644 index 00000000..a0817e26 --- /dev/null +++ b/rpg-docs/client/views/character/features/features.html @@ -0,0 +1,32 @@ + \ No newline at end of file diff --git a/rpg-docs/client/views/character/Features/features.js b/rpg-docs/client/views/character/features/features.js similarity index 100% rename from rpg-docs/client/views/character/Features/features.js rename to rpg-docs/client/views/character/features/features.js diff --git a/rpg-docs/client/views/character/inventory/containerTable/containerTable.html b/rpg-docs/client/views/character/inventory/containerTable/containerTable.html deleted file mode 100644 index 2ae1ab0d..00000000 --- a/rpg-docs/client/views/character/inventory/containerTable/containerTable.html +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/rpg-docs/client/views/character/inventory/containerTable/containerTable.js b/rpg-docs/client/views/character/inventory/containerTable/containerTable.js deleted file mode 100644 index 0edf1c42..00000000 --- a/rpg-docs/client/views/character/inventory/containerTable/containerTable.js +++ /dev/null @@ -1,5 +0,0 @@ -Template.containerTable.helpers({ - items: function(){ - return Items.find({container: this._id}); - } -}); \ No newline at end of file diff --git a/rpg-docs/client/views/character/inventory/inventory.html b/rpg-docs/client/views/character/inventory/inventory.html index 962aeca5..6b38212a 100644 --- a/rpg-docs/client/views/character/inventory/inventory.html +++ b/rpg-docs/client/views/character/inventory/inventory.html @@ -1,6 +1,20 @@ \ No newline at end of file diff --git a/rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.html b/rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.html deleted file mode 100644 index 0d0560da..00000000 --- a/rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.html +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.js b/rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.js deleted file mode 100644 index 84f36e4c..00000000 --- a/rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.js +++ /dev/null @@ -1,5 +0,0 @@ -Template.inventoryTables.helpers({ - containers: function(){ - return Containers.find({owner: this._id}); - } -}); \ No newline at end of file diff --git a/rpg-docs/client/views/character/inventory/itemRow/itemRow.css b/rpg-docs/client/views/character/inventory/itemRow/itemRow.css deleted file mode 100644 index e9201f42..00000000 --- a/rpg-docs/client/views/character/inventory/itemRow/itemRow.css +++ /dev/null @@ -1,3 +0,0 @@ -tr.selected{ - background-color: #4182BC; -} \ No newline at end of file diff --git a/rpg-docs/client/views/character/inventory/itemRow/itemRow.html b/rpg-docs/client/views/character/inventory/itemRow/itemRow.html deleted file mode 100644 index 33f38a87..00000000 --- a/rpg-docs/client/views/character/inventory/itemRow/itemRow.html +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/rpg-docs/client/views/character/inventory/itemRow/itemRow.js b/rpg-docs/client/views/character/inventory/itemRow/itemRow.js deleted file mode 100644 index af8df0eb..00000000 --- a/rpg-docs/client/views/character/inventory/itemRow/itemRow.js +++ /dev/null @@ -1,15 +0,0 @@ -Template.itemRow.helpers({ - isSelected: function(){ - return Session.get('selectedItemRow')=== this._id; - } -}); - -Template.itemRow.events({ - "click": function(e){ - if(Session.get('selectedItemRow')=== this._id){ - Session.set('selectedItemRow', null); - } else{ - Session.set('selectedItemRow', this._id); - } - } -}); \ No newline at end of file diff --git a/rpg-docs/client/views/character/skills/skills.html b/rpg-docs/client/views/character/skills/skills.html index 1fa0f6f1..147653be 100644 --- a/rpg-docs/client/views/character/skills/skills.html +++ b/rpg-docs/client/views/character/skills/skills.html @@ -22,6 +22,11 @@ {{else}}
{{../skillMod skill}}
{{/if}} -
{{name}}
+
+ {{name}} + {{#if showPassive}} + ({{../passiveSkill skill}}) + {{/if}} +
\ No newline at end of file diff --git a/rpg-docs/lib/functions/buffsToCharacter.js b/rpg-docs/lib/functions/buffsToCharacter.js deleted file mode 100644 index 0d7ecd0c..00000000 --- a/rpg-docs/lib/functions/buffsToCharacter.js +++ /dev/null @@ -1,42 +0,0 @@ -//give a character a set of buffs that expire after [duration] -pushBuffs = function(id, buffArray, duration){ - _.each(buffArray, function(buff){ - var pushObject = {}; - if(duration > 0){ - //expiry time is now plus duration - var expiry = Characters.findOne(id, {fields: {time: 1}}).time + duration; - //ensure the effect has an id - buff.effect._id = buff.effect._id || Random.id(); - //build the expiration object - var expiration = { - stat: buff.stat, - effectId: buff.effect._id, - expiry: expiry - }; - //push expiration object to character - Characters.update(id, {$push: {expirations: expiration } }); - } - //push the effect to the character - pushObject[buff.stat] = buff.effect; - Characters.update(id, {$push: pushObject}); - }); -}; - -//pull all the buffs listed in the buffArray -pullBuffs = function(id, buffArray){ - _.each(buffArray, function(buff){ - pullEffect(id, buff.effect._id); - }); -}; - -//pull a single effect by stat and id -pullEffect = function(id, stat, effectId){ - var pullObject = {}; - pullObject[stat] = {_id: effectId}; - Characters.update(id, {$pull: pullObject }); -} - -//pull an expiry by id -pullExpiry = function(id, expiryId){ - Characters.update(id, {$pull: {expirations: {_id: expiryId} } }); -} \ No newline at end of file diff --git a/rpg-docs/lib/methods/actionUtils.js b/rpg-docs/lib/methods/actionUtils.js new file mode 100644 index 00000000..fa8002a3 --- /dev/null +++ b/rpg-docs/lib/methods/actionUtils.js @@ -0,0 +1,22 @@ +Meteor.methods({ + updateAction: function (charId, oldAction, newAction) { + var selector = {_id: charId, "actions._id": oldAction._id}; + var setter = {"actions.$": newAction}; + Characters.update( + selector, + { $set: setter } + ); + } +}); + +pullAction = function(id, action){ + var pullObject = {}; + pullObject["actions"] = {_id: action._id}; + Characters.update(id, {$pull: pullObject }); +}; + +pushAction = function(id, action){ + var pushObject = {}; + pushObject["actions"] = action; + Characters.update(id, {$push: pushObject}); +}; diff --git a/rpg-docs/lib/methods/attackUtils.js b/rpg-docs/lib/methods/attackUtils.js new file mode 100644 index 00000000..e9f7d1f0 --- /dev/null +++ b/rpg-docs/lib/methods/attackUtils.js @@ -0,0 +1,22 @@ +Meteor.methods({ + updateAttack: function (charId, oldAttack, newAttack) { + var selector = {_id: charId, "attacks._id": oldAttack._id}; + var setter = {"attacks.$": newAttack}; + Characters.update( + selector, + { $set: setter } + ); + } +}); + +pullAttack = function(id, attack){ + var pullObject = {}; + pullObject["attacks"] = {_id: attack._id}; + Characters.update(id, {$pull: pullObject }); +}; + +pushAttack = function(id, attack){ + var pushObject = {}; + pushObject["attacks"] = attack; + Characters.update(id, {$push: pushObject}); +}; diff --git a/rpg-docs/lib/methods/effectUtils.js b/rpg-docs/lib/methods/effectUtils.js new file mode 100644 index 00000000..408df881 --- /dev/null +++ b/rpg-docs/lib/methods/effectUtils.js @@ -0,0 +1,27 @@ +Meteor.methods({ + updateEffect: function (charId, attributeName, effectId, newEffect) { + var selector = {_id: charId}; + selector[attributeName + ".effects._id"] = effectId; + var setter = {}; + setter[attributeName + ".effects.$"] = newEffect + Characters.update( + selector, + { $set: setter } + ) + } +}); + +//pull a single effect by stat and id +pullEffect = function(id, effect){ + var pullObject = {}; + pullObject[effect.stat + ".effects"] = {_id: effect._id}; + Characters.update(id, {$pull: pullObject }); +} + +pushEffect = function(id, effect){ + var pushObject = {}; + pushObject[effect.stat + ".effects"] = effect; + Characters.update(id, {$push: pushObject}); +} + + diff --git a/rpg-docs/lib/methods/featureUtils.js b/rpg-docs/lib/methods/featureUtils.js new file mode 100644 index 00000000..7dd69c1a --- /dev/null +++ b/rpg-docs/lib/methods/featureUtils.js @@ -0,0 +1,56 @@ +Meteor.methods({ + addFeature: function(charId, newFeature){ + Characters.update( + charId, + { $push: {"customFeatures": newFeature} } + ); + addFeatureEffects(charId, newFeature); + }, + removeFeature: function(charId, oldFeature){ + Characters.update( + charId, + { $pull: { "customFeatures": {"_id": oldFeature._id} } } + ); + removeFeatureEffects(charId, oldFeature); + }, + updateFeature: function (charId, oldFeature, newFeature) { + var selector = {_id: charId, "customFeatures._id": oldFeature._id}; + var setter = {"customFeatures.$": newFeature}; + Characters.update( + selector, + { $set: setter } + ); + removeFeatureEffects(charId, oldFeature); + addFeatureEffects(charId, newFeature); + } +}); + +addFeatureEffects = function(charId, newFeature){ + _.each(newFeature.effects, function(effect){ + pushEffect(charId, effect); + }); + _.each(newFeature.actions, function(action){ + pushAction(charId, action); + }); + _.each(newFeature.attacks, function(attack){ + pushAttack(charId, attack); + }); + _.each(newFeature.spells, function(spell){ + pushSpell(charId, spell); + }); +} + +removeFeatureEffects = function(charId, oldFeature){ + _.each(oldFeature.effects, function(effect){ + pullEffect(charId, effect); + }); + _.each(oldFeature.actions, function(action){ + pullAction(charId, action); + }); + _.each(newFeature.attacks, function(attack){ + pushAttack(charId, attack); + }); + _.each(newFeature.spells, function(spell){ + pushSpell(charId, spell); + }); +}; \ No newline at end of file diff --git a/rpg-docs/lib/methods/spellUtils.js b/rpg-docs/lib/methods/spellUtils.js new file mode 100644 index 00000000..54d73f8d --- /dev/null +++ b/rpg-docs/lib/methods/spellUtils.js @@ -0,0 +1,22 @@ +Meteor.methods({ + updateSpell: function (charId, oldSpell, newSpell) { + var selector = {_id: charId, "spells._id": oldSpell._id}; + var setter = {"spells.$": newSpell}; + Characters.update( + selector, + { $set: setter } + ); + } +}); + +pullSpell = function(id, spell){ + var pullObject = {}; + pullObject["spells"] = {_id: spell._id}; + Characters.update(id, {$pull: pullObject }); +}; + +pushSpell = function(id, spell){ + var pushObject = {}; + pushObject["spells"] = spell; + Characters.update(id, {$push: pushObject}); +}; diff --git a/rpg-docs/lib/methods/updateEffect.js b/rpg-docs/lib/methods/updateEffect.js deleted file mode 100644 index be74a399..00000000 --- a/rpg-docs/lib/methods/updateEffect.js +++ /dev/null @@ -1,12 +0,0 @@ -Meteor.methods({ - updateEffect: function (charId, attributeName, effectId, newEffect) { - var selector = {_id: charId}; - selector[attributeName + ".effects._id"] = effectId; - var setter = {}; - setter[attributeName + ".effects.$"] = newEffect - Characters.update( - selector, - { $set: setter } - ) - } -}); \ No newline at end of file diff --git a/rpg-docs/nohup.out b/rpg-docs/nohup.out deleted file mode 100644 index 52bf12b0..00000000 --- a/rpg-docs/nohup.out +++ /dev/null @@ -1,29 +0,0 @@ -[[[[[ ~/workspace/rpg-docs ]]]]] - -=> Started proxy. -=> Started MongoDB. -I20141122-15:44:13.239(0)? ** You've set up some data subscriptions with Meteor.publish(), but -I20141122-15:44:13.351(0)? ** you still have autopublish turned on. Because autopublish is still -I20141122-15:44:13.352(0)? ** on, your Meteor.publish() calls won't have much effect. All data -I20141122-15:44:13.352(0)? ** will still be sent to all clients. -I20141122-15:44:13.352(0)? ** -I20141122-15:44:13.352(0)? ** Turn off autopublish by removing the autopublish package: -I20141122-15:44:13.353(0)? ** -I20141122-15:44:13.353(0)? ** $ meteor remove autopublish -I20141122-15:44:13.353(0)? ** -I20141122-15:44:13.353(0)? ** .. and make sure you have Meteor.publish() and Meteor.subscribe() calls -I20141122-15:44:13.353(0)? ** for each collection that you want clients to see. -I20141122-15:44:13.353(0)?  -=> Started your app. - -=> App running at: http://localhost:3000/ -Can't listen on port 3000. Perhaps another Meteor is running? - -Running two copies of Meteor in the same application directory -will not work. If something else is using port 3000, you can -specify an alternative port with --port . -Can't listen on port 3000. Perhaps another Meteor is running? - -Running two copies of Meteor in the same application directory -will not work. If something else is using port 3000, you can -specify an alternative port with --port . diff --git a/rpg-docs/public/jpg/rusted-metal-armor.jpg b/rpg-docs/public/jpg/rusted-metal-armor.jpg new file mode 100644 index 00000000..5e3e7e9e Binary files /dev/null and b/rpg-docs/public/jpg/rusted-metal-armor.jpg differ