Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e180595dcd | ||
|
|
ed708bdde0 | ||
|
|
d7852d640f | ||
|
|
a2fdee88b6 | ||
|
|
af070b1578 | ||
|
|
83a8eeef0f | ||
|
|
34f8e7402b | ||
|
|
1b7e2cd850 | ||
|
|
463b7f0fc9 | ||
|
|
266495abc8 | ||
|
|
453d4365d3 | ||
|
|
e0ce6275bf | ||
|
|
16b16ce6c6 | ||
|
|
80c72a274e | ||
|
|
91f0f7954c | ||
|
|
c74abcb608 | ||
|
|
da8b91594e | ||
|
|
fc26f5a73e | ||
|
|
4f60766d5d | ||
|
|
e992aeebef | ||
|
|
4108346a98 | ||
|
|
d2cc2833a9 |
@@ -186,7 +186,7 @@ Schemas.Character = new SimpleSchema({
|
|||||||
|
|
||||||
Characters.attachSchema(Schemas.Character);
|
Characters.attachSchema(Schemas.Character);
|
||||||
|
|
||||||
var attributeBase = function(charId, statName){
|
var attributeBase = preventLoop(function(charId, statName){
|
||||||
check(statName, String);
|
check(statName, String);
|
||||||
//if it's a damage multiplier, we treat it specially
|
//if it's a damage multiplier, we treat it specially
|
||||||
if (_.contains(DAMAGE_MULTIPLIERS, statName)){
|
if (_.contains(DAMAGE_MULTIPLIERS, statName)){
|
||||||
@@ -226,8 +226,8 @@ var attributeBase = function(charId, statName){
|
|||||||
var base = 0;
|
var base = 0;
|
||||||
var add = 0;
|
var add = 0;
|
||||||
var mul = 1;
|
var mul = 1;
|
||||||
var min = Math.NEGATIVE_INFINITY;
|
var min = Number.NEGATIVE_INFINITY;
|
||||||
var max = Math.POSITIVE_INFINITY;
|
var max = Number.POSITIVE_INFINITY;
|
||||||
|
|
||||||
Effects.find({
|
Effects.find({
|
||||||
charId: charId,
|
charId: charId,
|
||||||
@@ -253,8 +253,8 @@ var attributeBase = function(charId, statName){
|
|||||||
if (result < min) result = min;
|
if (result < min) result = min;
|
||||||
if (result > max) result = max;
|
if (result > max) result = max;
|
||||||
|
|
||||||
return result;
|
return Math.floor(result);
|
||||||
};
|
});
|
||||||
|
|
||||||
if (Meteor.isClient) {
|
if (Meteor.isClient) {
|
||||||
Template.registerHelper("characterCalculate", function(func, charId, input) {
|
Template.registerHelper("characterCalculate", function(func, charId, input) {
|
||||||
@@ -324,9 +324,9 @@ Characters.calculate = {
|
|||||||
value += attribute.adjustment;
|
value += attribute.adjustment;
|
||||||
return value;
|
return value;
|
||||||
}),
|
}),
|
||||||
attributeBase: memoize(preventLoop(function(charId, attributeName){
|
attributeBase: memoize(function(charId, attributeName){
|
||||||
return attributeBase(charId, attributeName);
|
return attributeBase(charId, attributeName);
|
||||||
})),
|
}),
|
||||||
skillMod: memoize(preventLoop(function(charId, skillName){
|
skillMod: memoize(preventLoop(function(charId, skillName){
|
||||||
var skill = Characters.calculate.getField(charId, skillName);
|
var skill = Characters.calculate.getField(charId, skillName);
|
||||||
//get the final value of the ability score
|
//get the final value of the ability score
|
||||||
@@ -345,8 +345,8 @@ Characters.calculate = {
|
|||||||
var value;
|
var value;
|
||||||
var add = 0;
|
var add = 0;
|
||||||
var mul = 1;
|
var mul = 1;
|
||||||
var min = Math.NEGATIVE_INFINITY;
|
var min = Number.NEGATIVE_INFINITY;
|
||||||
var max = Math.POSITIVE_INFINITY;
|
var max = Number.POSITIVE_INFINITY;
|
||||||
|
|
||||||
Effects.find({
|
Effects.find({
|
||||||
charId: charId,
|
charId: charId,
|
||||||
@@ -369,7 +369,7 @@ Characters.calculate = {
|
|||||||
if (result < min) result = min;
|
if (result < min) result = min;
|
||||||
if (result > max) result = max;
|
if (result > max) result = max;
|
||||||
|
|
||||||
return result;
|
return Math.floor(result);
|
||||||
})),
|
})),
|
||||||
proficiency: memoize(function(charId, skillName){
|
proficiency: memoize(function(charId, skillName){
|
||||||
//return largest value in proficiency array
|
//return largest value in proficiency array
|
||||||
@@ -390,7 +390,7 @@ Characters.calculate = {
|
|||||||
});
|
});
|
||||||
var advantage = Characters.calculate.advantage(charId, skillName);
|
var advantage = Characters.calculate.advantage(charId, skillName);
|
||||||
value += 5 * advantage;
|
value += 5 * advantage;
|
||||||
return value;
|
return Math.floor(value);
|
||||||
}),
|
}),
|
||||||
advantage: memoize(function(charId, skillName){
|
advantage: memoize(function(charId, skillName){
|
||||||
var advantage = Effects.find(
|
var advantage = Effects.find(
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ Spells.attachSchema(Schemas.Spell);
|
|||||||
|
|
||||||
Spells.attachBehaviour("softRemovable");
|
Spells.attachBehaviour("softRemovable");
|
||||||
makeChild(Spells); //children of spell lists
|
makeChild(Spells); //children of spell lists
|
||||||
|
makeParent(Spells, ["name", "enabled"]); //parents of attacks
|
||||||
|
|
||||||
Spells.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Spells.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Spells.deny(CHARACTER_SUBSCHEMA_DENY);
|
Spells.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Router.map(function() {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
characters: function(){
|
characters: function(){
|
||||||
return Characters.find({}, {fields: {_id: 1}});
|
return Characters.find({}, {fields: {_id: 1}, sort: {name: 1}});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onAfterAction: function() {
|
onAfterAction: function() {
|
||||||
|
|||||||
@@ -3,26 +3,26 @@
|
|||||||
<div layout vertical flex>
|
<div layout vertical flex>
|
||||||
<div layout horizontal>
|
<div layout horizontal>
|
||||||
<!--attackBonus-->
|
<!--attackBonus-->
|
||||||
<paper-input id="attackBonusInput"
|
<paper-input class="attackBonusInput"
|
||||||
label="Attack Bonus"
|
label="Attack Bonus"
|
||||||
floatinglabel
|
floatinglabel
|
||||||
value={{attackBonus}}
|
value={{attackBonus}}
|
||||||
flex></paper-input>
|
flex></paper-input>
|
||||||
<!--details-->
|
<!--details-->
|
||||||
<paper-input id="detailInput"
|
<paper-input class="detailInput"
|
||||||
label="Details"
|
label="Details"
|
||||||
floatinglabel
|
floatinglabel
|
||||||
value={{details}}></paper-input>
|
value={{details}}></paper-input>
|
||||||
</div>
|
</div>
|
||||||
<div layout horizontal>
|
<div layout horizontal>
|
||||||
<!--damageBonus-->
|
<!--damageBonus-->
|
||||||
<paper-input id="damageInput"
|
<paper-input class="damageInput"
|
||||||
label="Damage"
|
label="Damage"
|
||||||
floatinglabel
|
floatinglabel
|
||||||
value={{damage}}
|
value={{damage}}
|
||||||
flex></paper-input>
|
flex></paper-input>
|
||||||
<!--DamageType-->
|
<!--DamageType-->
|
||||||
<paper-dropdown-menu id="damageTypeDropdown" label="Damage Type">
|
<paper-dropdown-menu class="damageTypeDropdown" label="Damage Type">
|
||||||
<paper-dropdown layered class="dropdown">
|
<paper-dropdown layered class="dropdown">
|
||||||
<core-menu class="menu" selected={{damageType}}>
|
<core-menu class="menu" selected={{damageType}}>
|
||||||
{{#each damageTypes}}
|
{{#each damageTypes}}
|
||||||
@@ -34,6 +34,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--Delete Button-->
|
<!--Delete Button-->
|
||||||
<paper-icon-button id="deleteAttack" role="button" tabindex="0" icon="delete" aria-label="Delete"></paper-icon-button>
|
<paper-icon-button class="deleteAttack" role="button" tabindex="0" icon="delete" aria-label="Delete"></paper-icon-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -15,23 +15,23 @@ var damageTypes = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
Template.attackEdit.events({
|
Template.attackEdit.events({
|
||||||
"tap #deleteAttack": function(event, instance) {
|
"tap .deleteAttack": function(event, instance) {
|
||||||
Attacks.softRemoveNode(this._id);
|
Attacks.softRemoveNode(this._id);
|
||||||
GlobalUI.deletedToast(this._id, "Attacks", "Attack");
|
GlobalUI.deletedToast(this._id, "Attacks", "Attack");
|
||||||
},
|
},
|
||||||
"change #attackBonusInput": function(event) {
|
"change .attackBonusInput": function(event) {
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Attacks.update(this._id, {$set: {attackBonus: value}});
|
Attacks.update(this._id, {$set: {attackBonus: value}});
|
||||||
},
|
},
|
||||||
"change #damageInput": function(event) {
|
"change .damageInput": function(event) {
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Attacks.update(this._id, {$set: {damage: value}});
|
Attacks.update(this._id, {$set: {damage: value}});
|
||||||
},
|
},
|
||||||
"change #detailInput": function(event) {
|
"change .detailInput": function(event) {
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Attacks.update(this._id, {$set: {details: value}});
|
Attacks.update(this._id, {$set: {details: value}});
|
||||||
},
|
},
|
||||||
"core-select #damageTypeDropdown": function(event) {
|
"core-select .damageTypeDropdown": function(event) {
|
||||||
var detail = event.originalEvent.detail;
|
var detail = event.originalEvent.detail;
|
||||||
if (!detail.isSelected) return;
|
if (!detail.isSelected) return;
|
||||||
var value = detail.item.getAttribute("name");
|
var value = detail.item.getAttribute("name");
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ Template.resource.helpers({
|
|||||||
return !valuePositive;
|
return !valuePositive;
|
||||||
},
|
},
|
||||||
getColor: function(){
|
getColor: function(){
|
||||||
if (this.char.attributeValue(this.name) > 0){
|
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||||
|
if (value > 0){
|
||||||
return this.color;
|
return this.color;
|
||||||
} else {
|
} else {
|
||||||
return "grey";
|
return "grey";
|
||||||
|
|||||||
@@ -9,20 +9,24 @@
|
|||||||
<div class="pre-wrap">{{description}}</div>
|
<div class="pre-wrap">{{description}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div horizontal layout>
|
{{> experienceEdit}}
|
||||||
<!--Name-->
|
|
||||||
<paper-input id="experienceNameInput" label="Name" floatinglabel value={{name}} flex></paper-input>
|
|
||||||
<!--Value-->
|
|
||||||
<paper-input-decorator label="Value" floatinglabel>
|
|
||||||
<input id="valueInput" type="number" value={{value}}>
|
|
||||||
</paper-input-decorator>
|
|
||||||
</div>
|
|
||||||
<!--Description-->
|
|
||||||
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
|
||||||
<paper-autogrow-textarea>
|
|
||||||
<textarea id="experienceDescriptionInput" placeholder value={{description}}></textarea>
|
|
||||||
</paper-autogrow-textarea>
|
|
||||||
</paper-input-decorator>
|
|
||||||
{{/baseDialog}}
|
{{/baseDialog}}
|
||||||
{{/with}}
|
{{/with}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template name="experienceEdit">
|
||||||
|
<div horizontal layout>
|
||||||
|
<!--Name-->
|
||||||
|
<paper-input id="experienceNameInput" label="Name" floatinglabel value={{name}} flex></paper-input>
|
||||||
|
<!--Value-->
|
||||||
|
<paper-input-decorator label="Value" floatinglabel>
|
||||||
|
<input id="valueInput" type="number" value={{value}}>
|
||||||
|
</paper-input-decorator>
|
||||||
|
</div>
|
||||||
|
<!--Description-->
|
||||||
|
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
||||||
|
<paper-autogrow-textarea>
|
||||||
|
<textarea id="experienceDescriptionInput" placeholder value={{description}}></textarea>
|
||||||
|
</paper-autogrow-textarea>
|
||||||
|
</paper-input-decorator>
|
||||||
|
</template>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Template.experienceDialog.onRendered(function(){
|
Template.experienceEdit.onRendered(function(){
|
||||||
updatePolymerInputs(this);
|
updatePolymerInputs(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -22,8 +22,10 @@ Template.experienceDialog.events({
|
|||||||
);
|
);
|
||||||
GlobalUI.closeDetail();
|
GlobalUI.closeDetail();
|
||||||
},
|
},
|
||||||
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
|
});
|
||||||
"change #experienceNameInput, input #experienceNameInput": function(event){
|
|
||||||
|
Template.experienceEdit.events({
|
||||||
|
"change #experienceNameInput": function(event){
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Experiences.update(this._id, {$set: {name: value}});
|
Experiences.update(this._id, {$set: {name: value}});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
{{characterCalculate "attributeValue" ../_id name}}
|
{{characterCalculate "attributeValue" ../_id name}}
|
||||||
</div>
|
</div>
|
||||||
<div class="title white-text">
|
<div class="title white-text">
|
||||||
d{{diceNum}} {{characterCalculate "abilityMod" ../_id "constitution"}}
|
d{{diceNum}} {{conMod}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ Template.hitDice.helpers({
|
|||||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||||
return value <= 0;
|
return value <= 0;
|
||||||
},
|
},
|
||||||
|
conMod: function(){
|
||||||
|
return signedString(
|
||||||
|
Characters.calculate.abilityMod(this.char._id, "constitution")
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.hitDice.events({
|
Template.hitDice.events({
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ Template.characterSideList.helpers({
|
|||||||
{owner: userId},
|
{owner: userId},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{fields: {name: 1}}
|
{
|
||||||
|
fields: {name: 1},
|
||||||
|
sort: {name: 1},
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ function CacheObject(func, address, args, cache, context){
|
|||||||
var self = this;
|
var self = this;
|
||||||
self.currentValue = null;
|
self.currentValue = null;
|
||||||
self.dep = new Tracker.Dependency();
|
self.dep = new Tracker.Dependency();
|
||||||
|
self.numRun = 0;
|
||||||
|
|
||||||
//spawn a new autorun that keeps the value up-to-date
|
//spawn a new autorun that keeps the value up-to-date
|
||||||
Tracker.nonreactive(function() {
|
Tracker.nonreactive(function() {
|
||||||
@@ -26,8 +27,22 @@ function CacheObject(func, address, args, cache, context){
|
|||||||
delete cache[address];
|
delete cache[address];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//if we haven't run this before this flush, reset the counter after the flush
|
||||||
|
if(self.numRun === 0){
|
||||||
|
Tracker.afterFlush(function(){
|
||||||
|
self.numRun = 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.numRun++;
|
||||||
//call the expensive function
|
//call the expensive function
|
||||||
|
//even if we don't use its value, we need to track its dependencies
|
||||||
var newValue = func.apply(context, args);
|
var newValue = func.apply(context, args);
|
||||||
|
//prevent dependency loops, the memoized function shouldn't re-run
|
||||||
|
//more than once per flush
|
||||||
|
if (self.numRun > 1){
|
||||||
|
newValue = NaN;
|
||||||
|
if(_.isNaN(self.currentValue)) return;
|
||||||
|
}
|
||||||
//if the value changed, store the new value
|
//if the value changed, store the new value
|
||||||
if (self.currentValue !== newValue){
|
if (self.currentValue !== newValue){
|
||||||
self.currentValue = newValue;
|
self.currentValue = newValue;
|
||||||
|
|||||||
@@ -183,7 +183,39 @@ ChangeLogs.insert({
|
|||||||
"Big performance improvements: loading characters that you've viewed recently and changing effects on characters should be much faster",
|
"Big performance improvements: loading characters that you've viewed recently and changing effects on characters should be much faster",
|
||||||
"Spell dialogs no longer show their casting time, range, etc. if those fields aren't filled in",
|
"Spell dialogs no longer show their casting time, range, etc. if those fields aren't filled in",
|
||||||
"The settings dialog now has a done button so it can be closed on small devices",
|
"The settings dialog now has a done button so it can be closed on small devices",
|
||||||
"Experience dialogs should update their edit-mode inputs properly now",
|
|
||||||
"Container dialogs now have the weight summaries rounded down properly",
|
"Container dialogs now have the weight summaries rounded down properly",
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ChangeLogs.insert({
|
||||||
|
version: "0.6.1",
|
||||||
|
changes: [
|
||||||
|
"Experience dialogs should update their edit-mode inputs properly now",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
ChangeLogs.insert({
|
||||||
|
version: "0.6.2",
|
||||||
|
changes: [
|
||||||
|
"Fixed a regression which broke min and max effects",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
ChangeLogs.insert({
|
||||||
|
version: "0.6.3",
|
||||||
|
changes: [
|
||||||
|
"Fixed a regression that stopped skills and attributes from rounding down correctly",
|
||||||
|
"Made dependency loops return NaN immediately, rather than looping indefinitely until a page refresh. Adding an effect that adds \"strength\" to Strength, won't cause Strength to constantly increase or freeze the browser, Strength just becomes NaN",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
ChangeLogs.insert({
|
||||||
|
version: "0.6.4",
|
||||||
|
changes: [
|
||||||
|
"Hit dice now has a \"+\" between the dice and the constitution modifier",
|
||||||
|
"Items with multiple attacks should have the damage type editable on all attacks now",
|
||||||
|
"Spell attacks should now correctly inherit changes to their spell's name",
|
||||||
|
"Character lists should now be ordered alphabetically",
|
||||||
|
"Skills should have correct min and max effects applied again",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user