Small fixes for effects, health, permissions and formatting
This commit is contained in:
@@ -5,8 +5,8 @@ Effects = new Mongo.Collection("effects");
|
||||
* that modify their final value or presentation in some way
|
||||
*/
|
||||
Schemas.Effect = new SimpleSchema({
|
||||
charId: {
|
||||
type: String,
|
||||
charId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id
|
||||
},
|
||||
name: {
|
||||
@@ -26,7 +26,7 @@ Schemas.Effect = new SimpleSchema({
|
||||
},
|
||||
calculation: {
|
||||
type: String,
|
||||
optional: true,
|
||||
optional: true,
|
||||
trim: false
|
||||
},
|
||||
//indicates what the effect originated from
|
||||
@@ -52,57 +52,55 @@ Schemas.Effect = new SimpleSchema({
|
||||
|
||||
Effects.attachSchema(Schemas.Effect);
|
||||
|
||||
Characters.after.insert(function (userId, char) {
|
||||
if(Meteor.isServer){
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
type: "inate",
|
||||
name: "Constitution modifier for each level",
|
||||
stat: "hitPoints",
|
||||
operation: "add",
|
||||
calculation: "level * constitutionMod",
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters"
|
||||
}
|
||||
});
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
type: "inate",
|
||||
name: "Proficiency bonus by level",
|
||||
stat: "proficiencyBonus",
|
||||
operation: "add",
|
||||
calculation: "floor(level / 4 + 1.75)",
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters"
|
||||
}
|
||||
});
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
type: "inate",
|
||||
name: "Dexterity Armor Bonus",
|
||||
stat: "armor",
|
||||
operation: "add",
|
||||
calculation: "dexterityArmor",
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters"
|
||||
}
|
||||
});
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
type: "inate",
|
||||
name: "Natural Armor",
|
||||
stat: "armor",
|
||||
operation: "base",
|
||||
value: 10,
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters"
|
||||
}
|
||||
});
|
||||
}
|
||||
if(Meteor.isServer) Characters.after.insert(function (userId, char) {
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
type: "inate",
|
||||
name: "Constitution modifier for each level",
|
||||
stat: "hitPoints",
|
||||
operation: "add",
|
||||
calculation: "level * constitutionMod",
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters"
|
||||
}
|
||||
});
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
type: "inate",
|
||||
name: "Proficiency bonus by level",
|
||||
stat: "proficiencyBonus",
|
||||
operation: "add",
|
||||
calculation: "floor(level / 4 + 1.75)",
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters"
|
||||
}
|
||||
});
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
type: "inate",
|
||||
name: "Dexterity Armor Bonus",
|
||||
stat: "armor",
|
||||
operation: "add",
|
||||
calculation: "dexterityArmor",
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters"
|
||||
}
|
||||
});
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
type: "inate",
|
||||
name: "Natural Armor",
|
||||
stat: "armor",
|
||||
operation: "base",
|
||||
value: 10,
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Effects.attachBehaviour('softRemovable');
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template name="effectEdit">
|
||||
<div class="effectEdit" layout horizontal center>
|
||||
<paper-dropdown-menu id="statGroupDropDown" label="Stat Group" flex>
|
||||
<paper-dropdown-menu class="statGroupDropDown" label="Stat Group" flex>
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu id="statGroupMenu" class="menu" selected={{selectedStatGroup}}>
|
||||
<core-menu class="menu statGroupMenu" selected={{selectedStatGroup}}>
|
||||
{{#each statGroups}}
|
||||
<paper-item class="statGroupSelect" name={{this}}>{{this}}</paper-item>
|
||||
{{/each}}
|
||||
@@ -10,9 +10,9 @@
|
||||
</paper-dropdown>
|
||||
</paper-dropdown-menu>
|
||||
{{#if stats}}
|
||||
<paper-dropdown-menu id="statDropDown" label="Stat" flex>
|
||||
<paper-dropdown-menu class="statDropDown" label="Stat" flex>
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu id="statMenu" class="menu" selected={{stat}} on-tap="onStatMenuTap">
|
||||
<core-menu class="menu statMenu" selected={{stat}} on-tap="onStatMenuTap">
|
||||
{{#each stats}}
|
||||
<paper-item name={{stat}}>{{name}}</paper-item>
|
||||
{{/each}}
|
||||
@@ -21,9 +21,9 @@
|
||||
</paper-dropdown-menu>
|
||||
{{/if}}
|
||||
{{#if operations}}
|
||||
<paper-dropdown-menu id="operationDropDown" label="Operation" flex>
|
||||
<paper-dropdown-menu class="operationDropDown" label="Operation" flex>
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu id="operationMenu" class="menu" selected={{operation}}>
|
||||
<core-menu class="menu operationMenu" selected={{operation}}>
|
||||
{{#each operations}}
|
||||
<paper-item name={{operation}}>{{name}}</paper-item>
|
||||
{{/each}}
|
||||
@@ -32,19 +32,19 @@
|
||||
</paper-dropdown-menu>
|
||||
{{/if}}
|
||||
{{> Template.dynamic template=effectValueTemplate}}
|
||||
<paper-icon-button id="deleteEffect" role="button" tabindex="0" icon="delete" aria-label="Delete"></paper-icon-button>
|
||||
<paper-icon-button class="deleteEffect" role="button" tabindex="0" icon="delete" aria-label="Delete"></paper-icon-button>
|
||||
<br>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="regularEffectValue">
|
||||
<paper-input id="effectValueInput" label="Value" floatinglabel value={{effectValue}} flex></paper-input>
|
||||
<paper-input class="effectValueInput" label="Value" floatinglabel value={{effectValue}} flex></paper-input>
|
||||
</template>
|
||||
|
||||
<template name="multiplierEffectValue">
|
||||
<paper-dropdown-menu id="damageMultiplierDropDown" label="Damage Multiplier" flex>
|
||||
<paper-dropdown-menu class="damageMultiplierDropDown" label="Damage Multiplier" flex>
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu id="multiplierMenu" class="menu" selected={{value}}>
|
||||
<core-menu class="menu multiplierMenu" selected={{value}}>
|
||||
<paper-item name="0.5">Resistance</paper-item>
|
||||
<paper-item name="2">Vulnerability</paper-item>
|
||||
<paper-item name="0">Immunity</paper-item>
|
||||
@@ -54,9 +54,9 @@
|
||||
</template>
|
||||
|
||||
<template name="proficiencyEffectValue">
|
||||
<paper-dropdown-menu id="proficiencyDropDown" label="Proficiency" flex>
|
||||
<paper-dropdown-menu class="proficiencyDropDown" label="Proficiency" flex>
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu id="proficiencyMenu" class="menu" selected={{value}}>
|
||||
<core-menu class="menu proficiencyMenu" selected={{value}}>
|
||||
<paper-item name="1">Proficient</paper-item>
|
||||
<paper-item name="0.5">Half Prof. Bonus</paper-item>
|
||||
<paper-item name="2">Double Prof. Bonus</paper-item>
|
||||
|
||||
@@ -143,11 +143,11 @@ Template.regularEffectValue.helpers({
|
||||
});
|
||||
|
||||
Template.effectEdit.events({
|
||||
"tap #deleteEffect": function(event){
|
||||
"tap .deleteEffect": function(event){
|
||||
Effects.softRemoveNode(this._id);
|
||||
GlobalUI.deletedToast(this._id, "Effects", "Effect");
|
||||
},
|
||||
"core-select #statGroupDropDown": function(event, instance){
|
||||
"core-select .statGroupDropDown": function(event, instance){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var groupName = detail.item.getAttribute("name");
|
||||
@@ -163,35 +163,35 @@ Template.effectEdit.events({
|
||||
}
|
||||
}
|
||||
},
|
||||
"core-select #statDropDown": function(event){
|
||||
"core-select .statDropDown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var statName = detail.item.getAttribute("name");
|
||||
if (statName == this.stat) return;
|
||||
Effects.update(this._id, {$set: {stat: statName}});
|
||||
},
|
||||
"core-select #operationDropDown": function(event){
|
||||
"core-select .operationDropDown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var opName = detail.item.getAttribute("name");
|
||||
if (opName == this.operation) return;
|
||||
Effects.update(this._id, {$set: {operation: opName}});
|
||||
},
|
||||
"core-select #damageMultiplierDropDown": function(event){
|
||||
"core-select .damageMultiplierDropDown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var value = +detail.item.getAttribute("name");
|
||||
if (value == this.value) return;
|
||||
Effects.update(this._id, {$set: {value: value, calculation: "", operation: "mul"}});
|
||||
},
|
||||
"core-select #proficiencyDropDown": function(event){
|
||||
"core-select .proficiencyDropDown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var value = +detail.item.getAttribute("name");
|
||||
if (value == this.value) return;
|
||||
Effects.update(this._id, {$set: {value: value, calculation: ""}});
|
||||
},
|
||||
"change #effectValueInput": function(event){
|
||||
"change .effectValueInput": function(event){
|
||||
var value = event.currentTarget.value;
|
||||
var numValue = +value;
|
||||
if(_.isFinite(numValue)){
|
||||
|
||||
@@ -57,6 +57,13 @@ Template.healthCard.events({
|
||||
var value = event.currentTarget.value;
|
||||
var adjustment = value - this.attributeBase("hitPoints");
|
||||
Characters.update(this._id, {$set: {"hitPoints.adjustment": adjustment}});
|
||||
//reset the death saves if we are gaining HP
|
||||
if(value > 0)
|
||||
Characters.update(this._id, { $set: {
|
||||
"deathSave.pass": 0,
|
||||
"deathSave.fail": 0,
|
||||
"deathSave.stable": false
|
||||
} });
|
||||
},
|
||||
"change .tempHitPointSlider": function(event){
|
||||
var value = event.currentTarget.value;
|
||||
@@ -68,9 +75,9 @@ Template.healthCard.events({
|
||||
},
|
||||
"tap #addTempHP": function(event){
|
||||
GlobalUI.showDialog({
|
||||
template: "addTHPDialog",
|
||||
data: {charId: this._id}
|
||||
});
|
||||
template: "addTHPDialog",
|
||||
data: {charId: this._id}
|
||||
});
|
||||
},
|
||||
"tap .failBubble": function(event){
|
||||
if(event.currentTarget.disabled) return;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.summaryNumber{
|
||||
width: 50px;
|
||||
}
|
||||
@@ -15,46 +15,46 @@
|
||||
<!--numerical value-->
|
||||
<div>
|
||||
<!--Ability Mod-->
|
||||
<div>
|
||||
<div>{{abilityName}}</div>
|
||||
<div>{{char.abilityMod ability}}</div>
|
||||
<div horizontal center-justified layout>
|
||||
<div flex>{{abilityName}}</div>
|
||||
<div class="summaryNumber">{{char.abilityMod ability}}</div>
|
||||
</div>
|
||||
<!--Prof bonus-->
|
||||
{{#if char.proficiency skillName}}
|
||||
<div>
|
||||
<div>{{#with profSource}}{{statValue}}{{/with}}</div>
|
||||
<div>+{{profBonus}}</div>
|
||||
<div horizontal center-justified layout>
|
||||
<div flex>{{#with profSource}}{{statValue}}{{/with}}</div>
|
||||
<div class="summaryNumber">{{signedString profBonus}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<!--numerical effects-->
|
||||
{{#each addEffects}}
|
||||
<div>
|
||||
<div>{{sourceName}}</div>
|
||||
<div>+{{statValue}}</div>
|
||||
<div horizontal center-justified layout>
|
||||
<div flex>{{sourceName}}</div>
|
||||
<div class="summaryNumber">{{signedString statValue}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each mulEffects}}
|
||||
<div>
|
||||
<div>{{sourceName}}</div>
|
||||
<div>×{{statValue}}</div>
|
||||
<div horizontal center-justified layout>
|
||||
<div flex>{{sourceName}}</div>
|
||||
<div class="summaryNumber">×{{statValue}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each minEffects}}
|
||||
<div>
|
||||
<div>{{sourceName}}</div>
|
||||
<div>Min: {{statValue}}</div>
|
||||
<div horizontal center-justified layout>
|
||||
<div flex>{{sourceName}}</div>
|
||||
<div class="summaryNumber">Min: {{statValue}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each maxEffects}}
|
||||
<div>
|
||||
<div>{{sourceName}}</div>
|
||||
<div>Max: {{statValue}}</div>
|
||||
<div horizontal center-justified layout>
|
||||
<div flex>{{sourceName}}</div>
|
||||
<div class="summaryNumber">Max: {{statValue}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
<!--Total-->
|
||||
<div>
|
||||
<div>Total</div>
|
||||
<div>{{char.skillMod skillName}}</div>
|
||||
<div horizontal center-justified layout>
|
||||
<div flex>Total</div>
|
||||
<div class="summaryNumber">{{char.skillMod skillName}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Advantage effects-->
|
||||
@@ -78,4 +78,4 @@
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/baseDialog}}
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -16,9 +16,16 @@ CHARACTER_SUBSCHEMA_ALLOW = {
|
||||
};
|
||||
|
||||
CHARACTER_SUBSCHEMA_DENY = {
|
||||
update: function (userId, docs, fields, modifier) {
|
||||
// can't change character
|
||||
return _.contains(fields, 'charId');
|
||||
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"]
|
||||
};
|
||||
|
||||
@@ -130,7 +130,7 @@ var checkPermission = function(userId, charId){
|
||||
|
||||
var cascadeSoftRemove = function(id, removedWithId){
|
||||
_.each(childCollections, function(treeCollection){
|
||||
treeCollection.update({"parent.id": id}, {$set: {removed: true, removedWith: removedWithId}});
|
||||
treeCollection.update({"parent.id": id}, {$set: {removed: true, removedWith: removedWithId}}, {multi: true});
|
||||
treeCollection.find({"parent.id": id}).forEach(function(doc){
|
||||
cascadeSoftRemove(doc._id, removedWithId);
|
||||
});
|
||||
@@ -158,7 +158,7 @@ Meteor.methods({
|
||||
var collection = Mongo.Collection.get(collectionName);
|
||||
collection.restore(id);
|
||||
_.each(childCollections, function(treeCollection){
|
||||
treeCollection.update({removedWith: id, removed: true}, { $unset: {removed: true, removedWith: ""} });
|
||||
treeCollection.update({removedWith: id, removed: true}, { $unset: {removed: true, removedWith: ""} }, {multi: true});
|
||||
});
|
||||
},
|
||||
updateChildren: function (parent, modifier, limitToInheritance) {
|
||||
|
||||
Reference in New Issue
Block a user