Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e180595dcd | ||
|
|
ed708bdde0 | ||
|
|
d7852d640f | ||
|
|
a2fdee88b6 | ||
|
|
af070b1578 | ||
|
|
83a8eeef0f | ||
|
|
34f8e7402b | ||
|
|
1b7e2cd850 | ||
|
|
463b7f0fc9 | ||
|
|
266495abc8 | ||
|
|
453d4365d3 | ||
|
|
e0ce6275bf | ||
|
|
16b16ce6c6 | ||
|
|
80c72a274e | ||
|
|
91f0f7954c | ||
|
|
c74abcb608 | ||
|
|
da8b91594e | ||
|
|
fc26f5a73e | ||
|
|
d2cc2833a9 |
@@ -186,7 +186,7 @@ Schemas.Character = new SimpleSchema({
|
||||
|
||||
Characters.attachSchema(Schemas.Character);
|
||||
|
||||
var attributeBase = function(charId, statName){
|
||||
var attributeBase = preventLoop(function(charId, statName){
|
||||
check(statName, String);
|
||||
//if it's a damage multiplier, we treat it specially
|
||||
if (_.contains(DAMAGE_MULTIPLIERS, statName)){
|
||||
@@ -226,8 +226,8 @@ var attributeBase = function(charId, statName){
|
||||
var base = 0;
|
||||
var add = 0;
|
||||
var mul = 1;
|
||||
var min = Math.NEGATIVE_INFINITY;
|
||||
var max = Math.POSITIVE_INFINITY;
|
||||
var min = Number.NEGATIVE_INFINITY;
|
||||
var max = Number.POSITIVE_INFINITY;
|
||||
|
||||
Effects.find({
|
||||
charId: charId,
|
||||
@@ -253,8 +253,8 @@ var attributeBase = function(charId, statName){
|
||||
if (result < min) result = min;
|
||||
if (result > max) result = max;
|
||||
|
||||
return result;
|
||||
};
|
||||
return Math.floor(result);
|
||||
});
|
||||
|
||||
if (Meteor.isClient) {
|
||||
Template.registerHelper("characterCalculate", function(func, charId, input) {
|
||||
@@ -324,9 +324,9 @@ Characters.calculate = {
|
||||
value += attribute.adjustment;
|
||||
return value;
|
||||
}),
|
||||
attributeBase: memoize(preventLoop(function(charId, attributeName){
|
||||
attributeBase: memoize(function(charId, attributeName){
|
||||
return attributeBase(charId, attributeName);
|
||||
})),
|
||||
}),
|
||||
skillMod: memoize(preventLoop(function(charId, skillName){
|
||||
var skill = Characters.calculate.getField(charId, skillName);
|
||||
//get the final value of the ability score
|
||||
@@ -345,8 +345,8 @@ Characters.calculate = {
|
||||
var value;
|
||||
var add = 0;
|
||||
var mul = 1;
|
||||
var min = Math.NEGATIVE_INFINITY;
|
||||
var max = Math.POSITIVE_INFINITY;
|
||||
var min = Number.NEGATIVE_INFINITY;
|
||||
var max = Number.POSITIVE_INFINITY;
|
||||
|
||||
Effects.find({
|
||||
charId: charId,
|
||||
@@ -369,7 +369,7 @@ Characters.calculate = {
|
||||
if (result < min) result = min;
|
||||
if (result > max) result = max;
|
||||
|
||||
return result;
|
||||
return Math.floor(result);
|
||||
})),
|
||||
proficiency: memoize(function(charId, skillName){
|
||||
//return largest value in proficiency array
|
||||
@@ -390,7 +390,7 @@ Characters.calculate = {
|
||||
});
|
||||
var advantage = Characters.calculate.advantage(charId, skillName);
|
||||
value += 5 * advantage;
|
||||
return value;
|
||||
return Math.floor(value);
|
||||
}),
|
||||
advantage: memoize(function(charId, skillName){
|
||||
var advantage = Effects.find(
|
||||
|
||||
@@ -62,6 +62,7 @@ Spells.attachSchema(Schemas.Spell);
|
||||
|
||||
Spells.attachBehaviour("softRemovable");
|
||||
makeChild(Spells); //children of spell lists
|
||||
makeParent(Spells, ["name", "enabled"]); //parents of attacks
|
||||
|
||||
Spells.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||
Spells.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||
|
||||
@@ -27,7 +27,7 @@ Router.map(function() {
|
||||
},
|
||||
data: {
|
||||
characters: function(){
|
||||
return Characters.find({}, {fields: {_id: 1}});
|
||||
return Characters.find({}, {fields: {_id: 1}, sort: {name: 1}});
|
||||
}
|
||||
},
|
||||
onAfterAction: function() {
|
||||
|
||||
@@ -3,26 +3,26 @@
|
||||
<div layout vertical flex>
|
||||
<div layout horizontal>
|
||||
<!--attackBonus-->
|
||||
<paper-input id="attackBonusInput"
|
||||
<paper-input class="attackBonusInput"
|
||||
label="Attack Bonus"
|
||||
floatinglabel
|
||||
value={{attackBonus}}
|
||||
flex></paper-input>
|
||||
<!--details-->
|
||||
<paper-input id="detailInput"
|
||||
<paper-input class="detailInput"
|
||||
label="Details"
|
||||
floatinglabel
|
||||
value={{details}}></paper-input>
|
||||
</div>
|
||||
<div layout horizontal>
|
||||
<!--damageBonus-->
|
||||
<paper-input id="damageInput"
|
||||
<paper-input class="damageInput"
|
||||
label="Damage"
|
||||
floatinglabel
|
||||
value={{damage}}
|
||||
flex></paper-input>
|
||||
<!--DamageType-->
|
||||
<paper-dropdown-menu id="damageTypeDropdown" label="Damage Type">
|
||||
<paper-dropdown-menu class="damageTypeDropdown" label="Damage Type">
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu class="menu" selected={{damageType}}>
|
||||
{{#each damageTypes}}
|
||||
@@ -34,6 +34,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<!--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>
|
||||
</template>
|
||||
@@ -15,23 +15,23 @@ var damageTypes = [
|
||||
];
|
||||
|
||||
Template.attackEdit.events({
|
||||
"tap #deleteAttack": function(event, instance) {
|
||||
"tap .deleteAttack": function(event, instance) {
|
||||
Attacks.softRemoveNode(this._id);
|
||||
GlobalUI.deletedToast(this._id, "Attacks", "Attack");
|
||||
},
|
||||
"change #attackBonusInput": function(event) {
|
||||
"change .attackBonusInput": function(event) {
|
||||
var value = event.currentTarget.value;
|
||||
Attacks.update(this._id, {$set: {attackBonus: value}});
|
||||
},
|
||||
"change #damageInput": function(event) {
|
||||
"change .damageInput": function(event) {
|
||||
var value = event.currentTarget.value;
|
||||
Attacks.update(this._id, {$set: {damage: value}});
|
||||
},
|
||||
"change #detailInput": function(event) {
|
||||
"change .detailInput": function(event) {
|
||||
var value = event.currentTarget.value;
|
||||
Attacks.update(this._id, {$set: {details: value}});
|
||||
},
|
||||
"core-select #damageTypeDropdown": function(event) {
|
||||
"core-select .damageTypeDropdown": function(event) {
|
||||
var detail = event.originalEvent.detail;
|
||||
if (!detail.isSelected) return;
|
||||
var value = detail.item.getAttribute("name");
|
||||
|
||||
@@ -107,7 +107,8 @@ Template.resource.helpers({
|
||||
return !valuePositive;
|
||||
},
|
||||
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;
|
||||
} else {
|
||||
return "grey";
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
{{characterCalculate "attributeValue" ../_id name}}
|
||||
</div>
|
||||
<div class="title white-text">
|
||||
d{{diceNum}} {{characterCalculate "abilityMod" ../_id "constitution"}}
|
||||
d{{diceNum}} {{conMod}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,11 @@ Template.hitDice.helpers({
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
return value <= 0;
|
||||
},
|
||||
conMod: function(){
|
||||
return signedString(
|
||||
Characters.calculate.abilityMod(this.char._id, "constitution")
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Template.hitDice.events({
|
||||
|
||||
@@ -13,7 +13,10 @@ Template.characterSideList.helpers({
|
||||
{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;
|
||||
self.currentValue = null;
|
||||
self.dep = new Tracker.Dependency();
|
||||
self.numRun = 0;
|
||||
|
||||
//spawn a new autorun that keeps the value up-to-date
|
||||
Tracker.nonreactive(function() {
|
||||
@@ -26,8 +27,22 @@ function CacheObject(func, address, args, cache, context){
|
||||
delete cache[address];
|
||||
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
|
||||
//even if we don't use its value, we need to track its dependencies
|
||||
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 (self.currentValue !== newValue){
|
||||
self.currentValue = newValue;
|
||||
|
||||
@@ -193,3 +193,29 @@ ChangeLogs.insert({
|
||||
"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