Merge branch 'master' into feature-custom-buffs
# Conflicts: # rpg-docs/client/views/character/inventory/itemDialog/itemDialog.html # rpg-docs/client/views/character/spells/spellDialog/spellDialog.html
This commit is contained in:
@@ -7,12 +7,32 @@ Template.attackEditList.helpers({
|
||||
|
||||
Template.attackEditList.events({
|
||||
"tap #addAttackButton": function() {
|
||||
if (typeof this.isSpell !== 'undefined' && this.isSpell) {
|
||||
var parentSpell = Spells.findOne({"_id": this.parentId})
|
||||
if (parentSpell && parentSpell.parent.collection == "SpellLists") {
|
||||
var spellList = SpellLists.findOne({"_id":parentSpell.parent.id});
|
||||
if (spellList && spellList.attackBonus) {
|
||||
Attacks.insert({
|
||||
charId: this.charId,
|
||||
parent: {
|
||||
id: this.parentId,
|
||||
collection: this.parentCollection
|
||||
},
|
||||
attackBonus: "attackBonus",
|
||||
damage: "1d10",
|
||||
damageType: "fire",
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Attacks.insert({
|
||||
charId: this.charId,
|
||||
parent: {
|
||||
id: this.parentId,
|
||||
collection: this.parentCollection
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template name="attackView">
|
||||
<div class="attackView layout horizontal">
|
||||
<div class="paper-font-headline layout horizontal center" style="margin-right: 16px;">
|
||||
{{evaluateSigned charId attackBonus}}
|
||||
{{evaluateAttackBonus charId attack}}
|
||||
</div>
|
||||
<div class="layout vertical">
|
||||
<div>
|
||||
{{evaluateString charId damage}} {{damageType}}
|
||||
{{evaluateDamage charId attack}} {{damageType}}
|
||||
</div>
|
||||
{{#if details}}
|
||||
{{#if attack.details}}
|
||||
<div class="paper-font-caption">
|
||||
{{details}}
|
||||
{{attack.details}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
Template.attackView.helpers ({
|
||||
evaluateAttackBonus: function(charId, attack) {
|
||||
if (attack.parent.collection == "Spells") {
|
||||
var spell = Spells.findOne(attack.parent.id);
|
||||
if (spell) {
|
||||
bonus = evaluate(charId, attack.attackBonus, {"spellListId": spell.parent.id});
|
||||
}
|
||||
} else {
|
||||
var bonus = evaluate(charId, attack.attackBonus);
|
||||
}
|
||||
|
||||
if (_.isFinite(bonus)) {
|
||||
return bonus > 0 ? "+" + bonus : "" + bonus;
|
||||
} else {
|
||||
return bonus;
|
||||
}
|
||||
},
|
||||
evaluateDamage: function(charId, attack) {
|
||||
if (attack.parent.collection == "Spells") {
|
||||
var spell = Spells.findOne(attack.parent.id);
|
||||
if (spell) {
|
||||
return evaluateSpellString(charId, spell.parent.id, attack.damage);
|
||||
}
|
||||
} else {
|
||||
return evaluateString(charId, attack.damage);
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -3,8 +3,8 @@
|
||||
<hr style="margin: 16px 0 16px 0;">
|
||||
<div class="attacks">
|
||||
<div class="spaceAfter paper-font-title">Attacks</div>
|
||||
{{#each attacks}}
|
||||
{{> attackView}}
|
||||
{{#each attack in attacks}}
|
||||
{{> attackView attack=attack charId=charId}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
<paper-toggle-button id="variantEncumbrance" checked={{settings.useVariantEncumbrance}}>
|
||||
Use variant encumbrance
|
||||
</paper-toggle-button>
|
||||
<paper-toggle-button id="swapStatAndModifier" checked={{settings.swapStatAndModifier}}>
|
||||
Swap stats and modifiers on Stats page
|
||||
</paper-toggle-button>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
<div class="buttons layout horizontal end-justified">
|
||||
|
||||
@@ -23,6 +23,15 @@ Template.characterSettings.events({
|
||||
);
|
||||
}
|
||||
},
|
||||
"change #swapStatAndModifier": function(event, instance){
|
||||
var value = instance.find("#swapStatAndModifier").checked;
|
||||
if (this.settings.swapStatAndModifier !== value){
|
||||
Characters.update(
|
||||
this._id,
|
||||
{$set: {"settings.swapStatAndModifier": value}}
|
||||
);
|
||||
}
|
||||
},
|
||||
"click .doneButton": function(event, instance){
|
||||
popDialogStack();
|
||||
},
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
label="Value"
|
||||
floatinglabel
|
||||
value={{effectValue}}>
|
||||
{{> formulaSuffix}}
|
||||
</paper-input>
|
||||
{{else}}
|
||||
<div style="height: 62px;"></div>
|
||||
|
||||
@@ -53,10 +53,10 @@ var stats = [
|
||||
{stat: "level7SpellSlots", name: "level 7", group: "Spell Slots"},
|
||||
{stat: "level8SpellSlots", name: "level 8", group: "Spell Slots"},
|
||||
{stat: "level9SpellSlots", name: "level 9", group: "Spell Slots"},
|
||||
{stat: "d6HitDice", name: "d6", group: "Hit Dice"},
|
||||
{stat: "d8HitDice", name: "d8", group: "Hit Dice"},
|
||||
{stat: "d10HitDice", name: "d10", group: "Hit Dice"},
|
||||
{stat: "d12HitDice", name: "d12", group: "Hit Dice"},
|
||||
{stat: "d6HitDice", name: "d6 Hit Dice", group: "Hit Dice"},
|
||||
{stat: "d8HitDice", name: "d8 Hit Dice", group: "Hit Dice"},
|
||||
{stat: "d10HitDice", name: "d10 Hit Dice", group: "Hit Dice"},
|
||||
{stat: "d12HitDice", name: "d12 Hit Dice", group: "Hit Dice"},
|
||||
{stat: "acidMultiplier", name: "Acid", group: "Weakness/Resistance"},
|
||||
{stat: "bludgeoningMultiplier", name: "Bludgeoning", group: "Weakness/Resistance"},
|
||||
{stat: "coldMultiplier", name: "Cold", group: "Weakness/Resistance"},
|
||||
|
||||
@@ -69,8 +69,11 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<!--description-->
|
||||
<paper-textarea label="Description" id="featureDescriptionInput" value={{description}}></paper-textarea>
|
||||
<!--Description-->
|
||||
<div class="description-input layout horizontal end">
|
||||
<paper-textarea id="featureDescriptionInput" label="Description" value={{description}}></paper-textarea>
|
||||
{{> textareaBracketSuffix}}
|
||||
</div>
|
||||
|
||||
{{> effectsEditList parentId=_id parentCollection="Features" charId=charId name=name enabled=enabled}}
|
||||
{{> proficiencyEditList parentId=_id parentCollection="Features" charId=charId enabled=enabled}}
|
||||
|
||||
@@ -19,30 +19,8 @@
|
||||
Attacks
|
||||
</div>
|
||||
<div class="bottom list">
|
||||
{{#each attacks}}
|
||||
<div class="item-slot">
|
||||
<div class="flexible attack item">
|
||||
<div class="layout horizontal">
|
||||
<div class="paper-font-headline layout horizontal center"
|
||||
style="margin-right: 16px;">
|
||||
{{evaluateSigned ../_id attackBonus}}
|
||||
</div>
|
||||
<div class="flex layout vertical">
|
||||
<div class="paper-font-body2">
|
||||
{{name}}
|
||||
</div>
|
||||
<div>
|
||||
{{evaluateString ../_id damage}} {{damageType}}
|
||||
</div>
|
||||
{{#if details}}
|
||||
<div>
|
||||
{{details}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#each attack in attacks}}
|
||||
{{>attackListItem attack=attack charId=_id}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-material>
|
||||
@@ -55,19 +33,19 @@
|
||||
Proficiencies
|
||||
</div>
|
||||
<div flex class="bottom list">
|
||||
{{#if weaponProfs.count}}
|
||||
{{#if weaponProfs.length}}
|
||||
<div class="paper-font-subhead">Weapons</div>
|
||||
{{/if}}
|
||||
{{#each weaponProfs}}
|
||||
{{> proficiencyListItem}}
|
||||
{{/each}}
|
||||
{{#if armorProfs.count}}
|
||||
{{#if armorProfs.length}}
|
||||
<div class="paper-font-subhead">Armor</div>
|
||||
{{/if}}
|
||||
{{#each armorProfs}}
|
||||
{{> proficiencyListItem}}
|
||||
{{/each}}
|
||||
{{#if toolProfs.count}}
|
||||
{{#if toolProfs.length}}
|
||||
<div class="paper-font-subhead">Tools</div>
|
||||
{{/if}}
|
||||
{{#each toolProfs}}
|
||||
@@ -156,3 +134,29 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
|
||||
<template name="attackListItem">
|
||||
<div class="item-slot">
|
||||
<div class="flexible attack item">
|
||||
<div class="layout horizontal">
|
||||
<div class="paper-font-headline layout horizontal center"
|
||||
style="margin-right: 16px;">
|
||||
{{evaluateAttackBonus charId attack}}
|
||||
</div>
|
||||
<div class="flex layout vertical">
|
||||
<div class="paper-font-body2">
|
||||
{{attack.name}}
|
||||
</div>
|
||||
<div>
|
||||
{{evaluateDamage charId attack}} {{attack.damageType}}
|
||||
</div>
|
||||
{{#if attack.details}}
|
||||
<div>
|
||||
{{attack.details}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,3 +1,21 @@
|
||||
var removeDuplicateProficiencies = function(proficiencies) {
|
||||
dict = {};
|
||||
proficiencies.forEach(function(prof) {
|
||||
if (prof.name in dict) { //if we have already gone over another proficiency for the same thing
|
||||
if (dict[prof.name].value < prof.value) {
|
||||
dict[prof.name] = prof; //then take the new one if it's higher, otherwise leave it
|
||||
}
|
||||
} else {
|
||||
dict[prof.name] = prof; //if it wasn't already there, store it
|
||||
}
|
||||
});
|
||||
profs = []
|
||||
_.forEach(dict, function(prof) {
|
||||
profs.push(prof);
|
||||
})
|
||||
return profs;
|
||||
};
|
||||
|
||||
Template.features.helpers({
|
||||
features: function(){
|
||||
var features = Features.find({charId: this._id}, {sort: {color: 1, name: 1}});
|
||||
@@ -27,13 +45,16 @@ Template.features.helpers({
|
||||
return !this.alwaysEnabled;
|
||||
},
|
||||
weaponProfs: function(){
|
||||
return Proficiencies.find({charId: this._id, type: "weapon"});
|
||||
var profs = Proficiencies.find({charId: this._id, type: "weapon"});
|
||||
return removeDuplicateProficiencies(profs);
|
||||
},
|
||||
armorProfs: function(){
|
||||
return Proficiencies.find({charId: this._id, type: "armor"});
|
||||
var profs = Proficiencies.find({charId: this._id, type: "armor"});
|
||||
return removeDuplicateProficiencies(profs);
|
||||
},
|
||||
toolProfs: function(){
|
||||
return Proficiencies.find({charId: this._id, type: "tool"});
|
||||
var profs = Proficiencies.find({charId: this._id, type: "tool"});
|
||||
return removeDuplicateProficiencies(profs);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -61,13 +82,6 @@ Template.features.events({
|
||||
element: event.currentTarget.parentElement,
|
||||
});
|
||||
},
|
||||
"click .attack": function(event){
|
||||
openParentDialog({
|
||||
parent: this.parent,
|
||||
charId: this.charId,
|
||||
element: event.currentTarget,
|
||||
});
|
||||
},
|
||||
"click .useFeature": function(event){
|
||||
var featureId = this._id;
|
||||
Features.update(featureId, {$inc: {used: 1}});
|
||||
@@ -133,3 +147,42 @@ Template.resource.events({
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Template.attackListItem.helpers({
|
||||
evaluateAttackBonus: function(charId, attack) {
|
||||
if (attack.parent.collection == "Spells") {
|
||||
var spell = Spells.findOne(attack.parent.id);
|
||||
if (spell) {
|
||||
bonus = evaluate(charId, attack.attackBonus, {"spellListId": spell.parent.id});
|
||||
}
|
||||
} else {
|
||||
var bonus = evaluate(charId, attack.attackBonus);
|
||||
}
|
||||
|
||||
if (_.isFinite(bonus)) {
|
||||
return bonus > 0 ? "+" + bonus : "" + bonus;
|
||||
} else {
|
||||
return bonus;
|
||||
}
|
||||
},
|
||||
evaluateDamage: function(charId, attack) {
|
||||
if (attack.parent.collection == "Spells") {
|
||||
var spell = Spells.findOne(attack.parent.id);
|
||||
if (spell) {
|
||||
return evaluateSpellString(charId, spell.parent.id, attack.damage);
|
||||
}
|
||||
} else {
|
||||
return evaluateString(charId, attack.damage);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Template.attackListItem.events({
|
||||
"click .attack": function(event, instance){
|
||||
openParentDialog({
|
||||
parent: instance.data.attack.parent,
|
||||
charId: instance.data.charId,
|
||||
element: event.currentTarget,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
</div>
|
||||
|
||||
<hr class="vertMargin">
|
||||
|
||||
<paper-textarea label="Description" id="containerDescriptionInput" value={{description}}>
|
||||
</paper-textarea>
|
||||
<div class="description-input layout horizontal end">
|
||||
<paper-textarea label="Description" id="containerDescriptionInput" value={{description}}>
|
||||
</paper-textarea>
|
||||
{{> textareaBracketSuffix}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="containerView">
|
||||
|
||||
@@ -62,9 +62,11 @@
|
||||
</div>
|
||||
|
||||
<!--Description-->
|
||||
<paper-textarea id="itemDescriptionInput" label="Description" value={{description}}>
|
||||
{{> bracketSuffix}}
|
||||
</paper-textarea>
|
||||
<div class="description-input layout horizontal end">
|
||||
<paper-textarea id="itemDescriptionInput" label="Description" value={{description}}></paper-textarea>
|
||||
{{> textareaBracketSuffix}}
|
||||
</div>
|
||||
|
||||
<!--Effects-->
|
||||
{{> effectsEditList parentId=_id parentCollection="Items" charId=charId enabled=equipped name=name}}
|
||||
<!--Attacks-->
|
||||
|
||||
@@ -7,6 +7,24 @@ var colorMap = {
|
||||
backstory: "j",
|
||||
};
|
||||
|
||||
var removeDuplicateProficiencies = function(proficiencies) {
|
||||
dict = {};
|
||||
proficiencies.forEach(function(prof) {
|
||||
if (prof.name in dict) { //if we have already gone over another proficiency for the same thing
|
||||
if (dict[prof.name].value < prof.value) {
|
||||
dict[prof.name] = prof; //then take the new one if it's higher, otherwise leave it
|
||||
}
|
||||
} else {
|
||||
dict[prof.name] = prof; //if it wasn't already there, store it
|
||||
}
|
||||
});
|
||||
profs = []
|
||||
_.forEach(dict, function(prof) {
|
||||
profs.push(prof);
|
||||
})
|
||||
return profs;
|
||||
};
|
||||
|
||||
Template.persona.helpers({
|
||||
characterDetails: function(){
|
||||
var char = Characters.findOne(
|
||||
@@ -33,7 +51,8 @@ Template.persona.helpers({
|
||||
};
|
||||
},
|
||||
languages: function(){
|
||||
return Proficiencies.find({charId: this._id, type: "language"});
|
||||
var profs = Proficiencies.find({charId: this._id, type: "language"});
|
||||
return removeDuplicateProficiencies(profs);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -15,6 +15,22 @@ Template.proficiencyListItem.helpers({
|
||||
|
||||
Template.proficiencyListItem.events({
|
||||
"click .proficiency": function(event, instance){
|
||||
if (this.parent.collection == "Characters") {
|
||||
if (this.parent.group == "background") {
|
||||
pushDialogStack({
|
||||
template: "backgroundDialog",
|
||||
data: {
|
||||
"charId": this.charId,
|
||||
"field":"background",
|
||||
"title":"Background",
|
||||
"color":"j",
|
||||
},
|
||||
element: event.currentTarget,
|
||||
})
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
openParentDialog({
|
||||
parent: this.parent,
|
||||
charId: this.charId,
|
||||
|
||||
@@ -113,8 +113,11 @@
|
||||
</div>
|
||||
|
||||
<!--Description-->
|
||||
<paper-textarea id="descriptionInput" label="Description" value="{{description}}">
|
||||
</paper-textarea>
|
||||
{{> attackEditList parentId=_id parentCollection="Spells" charId=charId enabled=true name=name}}
|
||||
<div class="description-input layout horizontal end">
|
||||
<paper-textarea id="descriptionInput" label="Description" style="width: calc(100% - 24px)" value={{description}}></paper-textarea>
|
||||
{{> textareaBracketSuffix}}
|
||||
</div>
|
||||
|
||||
{{> customBuffEditList parentId=_id parentCollection="Spells" charId=charId}}
|
||||
{{> attackEditList parentId=_id parentCollection="Spells" charId=charId enabled=true name=name isSpell=true}}
|
||||
</template>
|
||||
|
||||
@@ -40,8 +40,11 @@
|
||||
{{> formulaSuffix}}
|
||||
</paper-input>
|
||||
<!--Description-->
|
||||
<paper-textarea id="spellListDescriptionInput" label="Description" value={{description}}>
|
||||
</paper-textarea>
|
||||
<div class="description-input layout horizontal end">
|
||||
<paper-textarea id="spellListDescriptionInput" label="Description" value={{description}}>
|
||||
</paper-textarea>
|
||||
{{> textareaBracketSuffix}}
|
||||
</div>
|
||||
</div>
|
||||
{{/baseDialog}}
|
||||
{{/with}}
|
||||
|
||||
@@ -11,6 +11,12 @@ var spellLevels = [
|
||||
{name: "Level 9", level: 9},
|
||||
];
|
||||
|
||||
var materialNeedsGp = function(string) {
|
||||
if (!string) return false;
|
||||
gpRegExp = /\b[0-9]+ ?(cp|sp|gp)\b/i;
|
||||
return gpRegExp.test(string);
|
||||
}
|
||||
|
||||
const showUnprepared = (listId) => {
|
||||
return Session.get(`showUnprepared.${listId}`);
|
||||
}
|
||||
@@ -70,6 +76,7 @@ Template.spells.helpers({
|
||||
}
|
||||
if (this.components.material){
|
||||
components += components ? ", M" : "M";
|
||||
if (materialNeedsGp(this.components.material)) {components += "gp";}
|
||||
}
|
||||
if (this.components.concentration){
|
||||
components += components ? ", C" : "C";
|
||||
@@ -268,6 +275,7 @@ Template.spells.events({
|
||||
Spells.insert(spell);
|
||||
// Copy over attacks and effects
|
||||
_.each(result.attacks, (attack) => {
|
||||
if (!("attackBonus" in attack)) {attack.attackBonus = "attackBonus"} //if no attack bonus provided, use spell list's
|
||||
attack.charId = charId;
|
||||
attack.parent = {id: spellId, collection: "Spells"};
|
||||
Attacks.insert(attack);
|
||||
@@ -277,6 +285,31 @@ Template.spells.events({
|
||||
effect.parent = {id: spellId, collection: "Spells"};
|
||||
Effects.insert(effect);
|
||||
});
|
||||
|
||||
/******[UNCOMMENT ONCE BUFFS ARE ADDED]*******
|
||||
_.each(result.buffs, (buff) => {
|
||||
buff.charId = charId;
|
||||
buff.parent = {id: spellId, collection: "Spells"};
|
||||
buffId = Buffs.insert(buff);
|
||||
|
||||
_.each(buff.attacks, (attack) => {
|
||||
if (!(attackBonus in attack)) {attack.attackBonus = "attackBonus"} //if no attack bonus provided, use spell list's
|
||||
attack.charId = charId;
|
||||
attack.parent = {id: buffId, collection: "Buffs"};
|
||||
Attacks.insert(attack);
|
||||
});
|
||||
_.each(buff.effects, (effect) => {
|
||||
effect.charId = charId;
|
||||
effect.parent = {id: buffId, collection: "Buffs"};
|
||||
Effects.insert(effect);
|
||||
});
|
||||
_.each(buff.proficiencies, (prof) => {
|
||||
prof.charId = charId;
|
||||
prof.parent = {id: buffId, collection: "Buffs"};
|
||||
Proficiencies.insert(prof);
|
||||
});
|
||||
});
|
||||
*******[UNCOMMENT ONCE BUFFS ARE ADDED]******/
|
||||
},
|
||||
returnElement: () => $(`[data-id='${spellId}']`).get(0),
|
||||
})
|
||||
|
||||
@@ -2,12 +2,21 @@
|
||||
<div>
|
||||
<paper-material class="ability-mini-card layout horizontal">
|
||||
<div class="numbers">
|
||||
{{#if swap}}
|
||||
<div class="paper-font-display1 stat">
|
||||
{{abilityMod}}
|
||||
</div>
|
||||
<div class="paper-font-subhead modifier">
|
||||
{{characterCalculate "attributeValue" ../_id ability}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="paper-font-display1 stat">
|
||||
{{characterCalculate "attributeValue" ../_id ability}}
|
||||
</div>
|
||||
<div class="paper-font-subhead modifier">
|
||||
{{abilityMod}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="paper-font-subhead title flex layout horizontal center">
|
||||
{{title}}
|
||||
|
||||
@@ -5,5 +5,10 @@ Template.abilityMiniCard.helpers({
|
||||
Template.parentData()._id, this.ability
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
swap: function() {
|
||||
var character = Characters.findOne({"_id": Template.parentData()._id})
|
||||
if (character) {return character.settings.swapStatAndModifier;}
|
||||
else {return false;}
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user