Compare commits
101 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6a9911dfc | ||
|
|
8a1871ee18 | ||
|
|
402f885f85 | ||
|
|
d07c118d47 | ||
|
|
103d44eeec | ||
|
|
33196c6771 | ||
|
|
80dc862047 | ||
|
|
314da14ad1 | ||
|
|
e5dbe81ac1 | ||
|
|
7e68ef64cc | ||
|
|
c9d71cad52 | ||
|
|
d79a808c81 | ||
|
|
1016c39bdf | ||
|
|
5f4923e049 | ||
|
|
e83237a728 | ||
|
|
9f323738bf | ||
|
|
1fc76fa50d | ||
|
|
36d5ff0a88 | ||
|
|
d05874ed13 | ||
|
|
df2521e69c | ||
|
|
3c6a685fe8 | ||
|
|
a77e560284 | ||
|
|
4cec83918f | ||
|
|
fec95c51c6 | ||
|
|
425c42d049 | ||
|
|
ab6f0c4f5b | ||
|
|
5d6e57b896 | ||
|
|
7c0a8125f2 | ||
|
|
7481ef08a8 | ||
|
|
b578dd5fb0 | ||
|
|
5d6f934d88 | ||
|
|
337f0bfa8a | ||
|
|
c62784894b | ||
|
|
75fff43d7d | ||
|
|
a9eeeac0df | ||
|
|
c8af0ff0a9 | ||
|
|
9e200db7b9 | ||
|
|
c08cf83096 | ||
|
|
d9368b06d0 | ||
|
|
2703367681 | ||
|
|
d419442549 | ||
|
|
99df01c950 | ||
|
|
d76349b3bb | ||
|
|
39c061f4e8 | ||
|
|
6d167ddb22 | ||
|
|
037acbd459 | ||
|
|
4d3fc3bb09 | ||
|
|
4b984d4fac | ||
|
|
58843613ba | ||
|
|
39b549b24b | ||
|
|
c79177de72 | ||
|
|
11d09b1487 | ||
|
|
0e4918d57d | ||
|
|
949f313af2 | ||
|
|
85b63f152f | ||
|
|
2141d52a7a | ||
|
|
4c84235064 | ||
|
|
0e194a5408 | ||
|
|
4b60eac330 | ||
|
|
cb017c359d | ||
|
|
15aaaa5c14 | ||
|
|
290bee83b4 | ||
|
|
fcd2461205 | ||
|
|
52198d0249 | ||
|
|
ba7ccfdfa0 | ||
|
|
92d3b086fa | ||
|
|
e180595dcd | ||
|
|
ed708bdde0 | ||
|
|
d7852d640f | ||
|
|
a2fdee88b6 | ||
|
|
af070b1578 | ||
|
|
83a8eeef0f | ||
|
|
34f8e7402b | ||
|
|
1b7e2cd850 | ||
|
|
463b7f0fc9 | ||
|
|
266495abc8 | ||
|
|
453d4365d3 | ||
|
|
e0ce6275bf | ||
|
|
16b16ce6c6 | ||
|
|
80c72a274e | ||
|
|
91f0f7954c | ||
|
|
c74abcb608 | ||
|
|
da8b91594e | ||
|
|
fc26f5a73e | ||
|
|
4f60766d5d | ||
|
|
e992aeebef | ||
|
|
4108346a98 | ||
|
|
946fadadc2 | ||
|
|
d2cc2833a9 | ||
|
|
af57326194 | ||
|
|
98c69e9e17 | ||
|
|
395edd0563 | ||
|
|
43e87e7786 | ||
|
|
ad347504c6 | ||
|
|
4e6e99b695 | ||
|
|
104624a322 | ||
|
|
79d166e6af | ||
|
|
86c934e8ac | ||
|
|
a034cbf30e | ||
|
|
d5680ebf8a | ||
|
|
53f2fcc945 |
60
README.md
60
README.md
@@ -1,58 +1,4 @@
|
||||
TODO
|
||||
====
|
||||
RPG Docs
|
||||
========
|
||||
|
||||
* 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
|
||||
=============
|
||||
|
||||
* meteor-platform
|
||||
* Base Meteor.
|
||||
* [Docs](http://docs.meteor.com/#/full/)
|
||||
* autopublish
|
||||
* Publishes everything to the client.
|
||||
* Must be removed before release
|
||||
* insecure
|
||||
* Allows the client the freedom to modify any colleciton.
|
||||
* Must be removed before release
|
||||
* iron:router
|
||||
* Enables pagination and URL's to direct to specific templates.
|
||||
* [Tutorial](http://www.manuel-schoebel.com/blog/iron-router-tutorial)
|
||||
* accounts-password
|
||||
* Lets users create accounts with a simple password
|
||||
* accounts-ui
|
||||
* Adds simple UI for logging in
|
||||
* random
|
||||
* Somewhat decent cryptographically strong psuedo random number generation.
|
||||
* [readme](https://atmospherejs.com/meteor/random)
|
||||
* dburles:collection-helpers
|
||||
* Adds template-style helpers to collections. [github page](https://github.com/dburles/meteor-collection-helpers)
|
||||
* reactive-var
|
||||
* Friendly reactive variables
|
||||
* [Meteor Docs](http://docs.meteor.com/#/full/reactivevar_pkg)
|
||||
* cw4gn3r:jquery-event-drag
|
||||
* Adds jquery drag events
|
||||
* underscore
|
||||
* Handy javascript utilities
|
||||
* [Docs](http://underscorejs.org/)
|
||||
* aldeed:collection2
|
||||
* Extends collections with Schemas
|
||||
* [(gitHub page)](https://github.com/aldeed/meteor-collection2)
|
||||
* uses [SimpleSchema](https://github.com/aldeed/meteor-simple-schema)
|
||||
* 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)
|
||||
|
||||
************
|
||||
|
||||
Resources
|
||||
=========
|
||||
|
||||
[differential's polymer demo](https://github.com/Differential/polymer-demo)
|
||||
This is the repo for [DiceCloud](dicecloud.com). The currently deployed version should always be the head of the master branch.
|
||||
|
||||
5
rpg-docs/.gitignore
vendored
5
rpg-docs/.gitignore
vendored
@@ -1,5 +1,8 @@
|
||||
.meteor/local
|
||||
.meteor/meteorite
|
||||
.demeteorized
|
||||
packages
|
||||
settings.json
|
||||
public/components
|
||||
nohup.out
|
||||
dump
|
||||
dump
|
||||
|
||||
@@ -6,3 +6,7 @@ notices-for-0.9.0
|
||||
notices-for-0.9.1
|
||||
0.9.4-platform-file
|
||||
notices-for-facebook-graph-api-2
|
||||
1.2.0-standard-minifiers-package
|
||||
1.2.0-meteor-platform-split
|
||||
1.2.0-cordova-changes
|
||||
1.2.0-breaking-changes
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# 'meteor add' and 'meteor remove' will edit this file for you,
|
||||
# but you can also edit it by hand.
|
||||
|
||||
meteor-platform
|
||||
thaum:vulcanize@0.0.5
|
||||
iron:router
|
||||
accounts-password
|
||||
accounts-ui
|
||||
@@ -12,7 +12,6 @@ dburles:collection-helpers
|
||||
reactive-var
|
||||
underscore
|
||||
aldeed:collection2
|
||||
differential:vulcanize
|
||||
matb33:collection-hooks
|
||||
zimme:collection-softremovable
|
||||
momentjs:moment
|
||||
@@ -27,3 +26,21 @@ fourseven:scss@2.1.1
|
||||
wolves:bourbon
|
||||
meteorhacks:subs-manager
|
||||
meteorhacks:kadira
|
||||
chuangbo:marked
|
||||
reywood:iron-router-ga
|
||||
standard-minifiers
|
||||
meteor-base
|
||||
mobile-experience
|
||||
mongo
|
||||
blaze-html-templates
|
||||
session
|
||||
jquery
|
||||
tracker
|
||||
logging
|
||||
reload
|
||||
ejson
|
||||
spacebars
|
||||
check
|
||||
useraccounts:iron-routing
|
||||
wizonesolutions:canonical
|
||||
meteorhacks:fast-render
|
||||
|
||||
@@ -1 +1 @@
|
||||
METEOR@1.1.0.2
|
||||
METEOR@1.2.0.2
|
||||
|
||||
@@ -1,94 +1,121 @@
|
||||
accounts-base@1.2.0
|
||||
accounts-google@1.0.4
|
||||
accounts-oauth@1.1.5
|
||||
accounts-password@1.1.1
|
||||
accounts-ui@1.1.5
|
||||
accounts-ui-unstyled@1.1.7
|
||||
aldeed:collection2@2.3.3
|
||||
accounts-base@1.2.1
|
||||
accounts-google@1.0.6
|
||||
accounts-oauth@1.1.7
|
||||
accounts-password@1.1.3
|
||||
accounts-ui@1.1.6
|
||||
accounts-ui-unstyled@1.1.8
|
||||
aldeed:collection2@2.5.0
|
||||
aldeed:simple-schema@1.3.3
|
||||
autoupdate@1.2.1
|
||||
base64@1.0.3
|
||||
binary-heap@1.0.3
|
||||
blaze@2.1.2
|
||||
blaze-tools@1.0.3
|
||||
boilerplate-generator@1.0.3
|
||||
callback-hook@1.0.3
|
||||
check@1.0.5
|
||||
coffeescript@1.0.6
|
||||
autoupdate@1.2.3
|
||||
babel-compiler@5.8.24_1
|
||||
babel-runtime@0.1.4
|
||||
base64@1.0.4
|
||||
binary-heap@1.0.4
|
||||
blaze@2.1.3
|
||||
blaze-html-templates@1.0.1
|
||||
blaze-tools@1.0.4
|
||||
boilerplate-generator@1.0.4
|
||||
caching-compiler@1.0.0
|
||||
caching-html-compiler@1.0.2
|
||||
callback-hook@1.0.4
|
||||
check@1.0.6
|
||||
chuangbo:cookie@1.1.0
|
||||
chuangbo:marked@0.3.5_1
|
||||
coffeescript@1.0.10
|
||||
dburles:collection-helpers@1.0.3
|
||||
dburles:mongo-collection-instances@0.3.3
|
||||
ddp@1.1.0
|
||||
deps@1.0.7
|
||||
differential:vulcanize@0.0.5
|
||||
dburles:mongo-collection-instances@0.3.4
|
||||
ddp@1.2.2
|
||||
ddp-client@1.2.1
|
||||
ddp-common@1.2.1
|
||||
ddp-rate-limiter@1.0.0
|
||||
ddp-server@1.2.1
|
||||
deps@1.0.9
|
||||
diff-sequence@1.0.1
|
||||
ecmascript@0.1.5
|
||||
ecmascript-collections@0.1.6
|
||||
ecwyne:mathjs@0.25.0
|
||||
ejson@1.0.6
|
||||
email@1.0.6
|
||||
fastclick@1.0.3
|
||||
ejson@1.0.7
|
||||
email@1.0.7
|
||||
fastclick@1.0.7
|
||||
fourseven:scss@2.1.1
|
||||
geojson-utils@1.0.3
|
||||
google@1.1.5
|
||||
html-tools@1.0.4
|
||||
htmljs@1.0.4
|
||||
http@1.1.0
|
||||
id-map@1.0.3
|
||||
iron:controller@1.0.7
|
||||
iron:core@1.0.7
|
||||
iron:dynamic-template@1.0.7
|
||||
iron:layout@1.0.7
|
||||
iron:location@1.0.7
|
||||
iron:middleware-stack@1.0.7
|
||||
iron:router@1.0.7
|
||||
iron:url@1.0.7
|
||||
jquery@1.11.3_2
|
||||
json@1.0.3
|
||||
lai:collection-extensions@0.1.3
|
||||
launch-screen@1.0.2
|
||||
less@1.0.14
|
||||
livedata@1.0.13
|
||||
localstorage@1.0.3
|
||||
logging@1.0.7
|
||||
matb33:collection-hooks@0.7.13
|
||||
meteor@1.1.6
|
||||
meteor-platform@1.2.2
|
||||
meteorhacks:kadira@2.21.0
|
||||
geojson-utils@1.0.4
|
||||
google@1.1.6
|
||||
hot-code-push@1.0.0
|
||||
html-tools@1.0.5
|
||||
htmljs@1.0.5
|
||||
http@1.1.1
|
||||
id-map@1.0.4
|
||||
iron:controller@1.0.8
|
||||
iron:core@1.0.8
|
||||
iron:dynamic-template@1.0.8
|
||||
iron:layout@1.0.8
|
||||
iron:location@1.0.9
|
||||
iron:middleware-stack@1.0.9
|
||||
iron:router@1.0.9
|
||||
iron:url@1.0.9
|
||||
jquery@1.11.4
|
||||
lai:collection-extensions@0.1.4
|
||||
launch-screen@1.0.4
|
||||
less@2.5.0_3
|
||||
livedata@1.0.15
|
||||
localstorage@1.0.5
|
||||
logging@1.0.8
|
||||
matb33:collection-hooks@0.8.1
|
||||
meteor@1.1.9
|
||||
meteor-base@1.0.1
|
||||
meteorhacks:fast-render@2.10.0
|
||||
meteorhacks:inject-data@1.4.1
|
||||
meteorhacks:kadira@2.23.4
|
||||
meteorhacks:meteorx@1.3.1
|
||||
meteorhacks:subs-manager@1.3.0
|
||||
minifiers@1.1.5
|
||||
minimongo@1.0.8
|
||||
mobile-status-bar@1.0.3
|
||||
momentjs:moment@2.10.3
|
||||
mongo@1.1.0
|
||||
mongo-livedata@1.0.8
|
||||
meteorhacks:picker@1.0.3
|
||||
meteorhacks:subs-manager@1.6.2
|
||||
minifiers@1.1.7
|
||||
minimongo@1.0.10
|
||||
mobile-experience@1.0.1
|
||||
mobile-status-bar@1.0.6
|
||||
momentjs:moment@2.10.6
|
||||
mongo@1.1.2
|
||||
mongo-id@1.0.1
|
||||
mongo-livedata@1.0.9
|
||||
npm-bcrypt@0.7.8_2
|
||||
oauth@1.1.4
|
||||
oauth2@1.1.3
|
||||
observe-sequence@1.0.6
|
||||
ordered-dict@1.0.3
|
||||
percolate:migrations@0.7.5
|
||||
random@1.0.3
|
||||
reactive-dict@1.1.0
|
||||
reactive-var@1.0.5
|
||||
reload@1.1.3
|
||||
retry@1.0.3
|
||||
routepolicy@1.0.5
|
||||
service-configuration@1.0.4
|
||||
session@1.1.0
|
||||
sha@1.0.3
|
||||
npm-mongo@1.4.39_1
|
||||
oauth@1.1.6
|
||||
oauth2@1.1.5
|
||||
observe-sequence@1.0.7
|
||||
ordered-dict@1.0.4
|
||||
percolate:migrations@0.9.6
|
||||
promise@0.5.0
|
||||
random@1.0.4
|
||||
rate-limit@1.0.0
|
||||
reactive-dict@1.1.2
|
||||
reactive-var@1.0.6
|
||||
reload@1.1.4
|
||||
retry@1.0.4
|
||||
reywood:iron-router-ga@0.7.1
|
||||
routepolicy@1.0.6
|
||||
service-configuration@1.0.5
|
||||
session@1.1.1
|
||||
sha@1.0.4
|
||||
softwarerero:accounts-t9n@1.0.9
|
||||
spacebars@1.0.6
|
||||
spacebars-compiler@1.0.6
|
||||
spacebars@1.0.7
|
||||
spacebars-compiler@1.0.7
|
||||
splendido:accounts-emails-field@1.2.0
|
||||
splendido:accounts-meld@1.3.0
|
||||
srp@1.0.3
|
||||
templating@1.1.1
|
||||
tracker@1.0.7
|
||||
ui@1.0.6
|
||||
underscore@1.0.3
|
||||
url@1.0.4
|
||||
useraccounts:core@1.9.1
|
||||
useraccounts:polymer@1.9.1
|
||||
webapp@1.2.0
|
||||
webapp-hashing@1.0.3
|
||||
wolves:bourbon@1.0.0
|
||||
zimme:collection-behaviours@1.0.4
|
||||
splendido:accounts-meld@1.3.1
|
||||
srp@1.0.4
|
||||
standard-minifiers@1.0.1
|
||||
templating@1.1.4
|
||||
templating-tools@1.0.0
|
||||
thaum:vulcanize@0.0.5
|
||||
tracker@1.0.9
|
||||
ui@1.0.8
|
||||
underscore@1.0.4
|
||||
url@1.0.5
|
||||
useraccounts:core@1.12.3
|
||||
useraccounts:iron-routing@1.12.3
|
||||
useraccounts:polymer@1.12.3
|
||||
webapp@1.2.2
|
||||
webapp-hashing@1.0.5
|
||||
wizonesolutions:canonical@0.0.5
|
||||
wolves:bourbon@1.2.0
|
||||
zimme:collection-behaviours@1.1.3
|
||||
zimme:collection-softremovable@1.0.4
|
||||
|
||||
@@ -7,6 +7,7 @@ Schemas.Action = new SimpleSchema({
|
||||
charId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
|
||||
@@ -7,6 +7,7 @@ Schemas.Attack = new SimpleSchema({
|
||||
charId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
@@ -69,5 +70,17 @@ Attacks.attachSchema(Schemas.Attack);
|
||||
Attacks.attachBehaviour("softRemovable");
|
||||
makeChild(Attacks, ["name", "enabled"]); //children of lots of things
|
||||
|
||||
Attacks.after.insert(function (userId, attack) {
|
||||
//Check to see if this attack's parent is a spell, if so, mirror prepared state to enabled
|
||||
if (attack.parent.collection === "Spells") {
|
||||
var parentSpell = Spells.findOne(attack.parent.id);
|
||||
if (parentSpell.prepared === "unprepared") {
|
||||
Attacks.update(attack._id, {$set: {enabled: false}});
|
||||
} else if (parentSpell.prepared === "prepared" || "always") {
|
||||
Attacks.update(attack._id, {$set: {enabled: true}});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Attacks.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||
Attacks.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||
|
||||
@@ -4,6 +4,7 @@ Schemas.Buff = new SimpleSchema({
|
||||
charId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
|
||||
@@ -3,16 +3,17 @@ Characters = new Mongo.Collection("characters");
|
||||
|
||||
Schemas.Character = new SimpleSchema({
|
||||
//strings
|
||||
name: {type: String, defaultValue: "", trim: false},
|
||||
alignment: {type: String, defaultValue: "", trim: false},
|
||||
gender: {type: String, defaultValue: "", trim: false},
|
||||
race: {type: String, defaultValue: "", trim: false},
|
||||
description: {type: String, defaultValue: "", trim: false},
|
||||
personality: {type: String, defaultValue: "", trim: false},
|
||||
ideals: {type: String, defaultValue: "", trim: false},
|
||||
bonds: {type: String, defaultValue: "", trim: false},
|
||||
flaws: {type: String, defaultValue: "", trim: false},
|
||||
backstory: {type: String, defaultValue: "", trim: false},
|
||||
name: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
alignment: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
gender: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
race: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
picture: {type: String, defaultValue: "", trim: true, optional: true},
|
||||
description: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
personality: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
ideals: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
bonds: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
flaws: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
backstory: {type: String, defaultValue: "", trim: false, optional: true},
|
||||
|
||||
//attributes
|
||||
//ability scores
|
||||
@@ -32,6 +33,7 @@ Schemas.Character = new SimpleSchema({
|
||||
age: {type: Schemas.Attribute},
|
||||
ageRate: {type: Schemas.Attribute},
|
||||
armor: {type: Schemas.Attribute},
|
||||
carryMultiplier: {type: Schemas.Attribute},
|
||||
|
||||
//resources
|
||||
level1SpellSlots: {type: Schemas.Attribute},
|
||||
@@ -186,95 +188,105 @@ 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)){
|
||||
var effects = Effects.find(
|
||||
{charId: charId, stat: statName, enabled: true, operation: "mul"}
|
||||
).fetch();
|
||||
var resistCount = 0;
|
||||
var vulnCount = 0;
|
||||
var multiplierEvaluationFail = false;
|
||||
_.each(effects, function(effect){
|
||||
var val = evaluateEffect(charId, effect);
|
||||
if (val === 0.5){ //resistance
|
||||
resistCount += 1;
|
||||
} else if (val === 2){ //vulnerability
|
||||
vulnCount += 1;
|
||||
} else if (val === 0){ //imunity
|
||||
return 0; //imunity is absolute
|
||||
} else {
|
||||
multiplierEvaluationFail = true;
|
||||
}
|
||||
});
|
||||
if (multiplierEvaluationFail){
|
||||
//we can't work it out correctly, set the value to 1
|
||||
//and try work it out using regular maths below
|
||||
value = 1;
|
||||
} else if (resistCount && !vulnCount){
|
||||
var invulnerabilityCount = Effects.find({
|
||||
charId: charId,
|
||||
stat: statName,
|
||||
enabled: true,
|
||||
operation: "mul",
|
||||
value: 0,
|
||||
}).count();
|
||||
if (invulnerabilityCount) return 0;
|
||||
var resistCount = Effects.find({
|
||||
charId: charId,
|
||||
stat: statName,
|
||||
enabled: true,
|
||||
operation: "mul",
|
||||
value: 0.5,
|
||||
}).count();
|
||||
var vulnCount = Effects.find({
|
||||
charId: charId,
|
||||
stat: statName,
|
||||
enabled: true,
|
||||
operation: "mul",
|
||||
value: 2,
|
||||
}).count();
|
||||
if (!resistCount && !vulnCount){
|
||||
return 1;
|
||||
} else if (resistCount && !vulnCount){
|
||||
return 0.5;
|
||||
} else if (!resistCount && vulnCount){
|
||||
} else if (!resistCount && vulnCount){
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
var value;
|
||||
var base = 0;
|
||||
var add = 0;
|
||||
var mul = 1;
|
||||
var min = Number.NEGATIVE_INFINITY;
|
||||
var max = Number.POSITIVE_INFINITY;
|
||||
|
||||
var value = 0;
|
||||
|
||||
//start with the highest base value
|
||||
Effects.find(
|
||||
{charId: charId, stat: statName, enabled: true, operation: "base"}
|
||||
).forEach(function(effect){
|
||||
var efv = evaluateEffect(charId, effect);
|
||||
if (efv > value){
|
||||
value = efv;
|
||||
Effects.find({
|
||||
charId: charId,
|
||||
stat: statName,
|
||||
enabled: true,
|
||||
operation: {$in: ["base", "add", "mul", "min", "max"]},
|
||||
}).forEach(function(effect) {
|
||||
value = evaluateEffect(charId, effect);
|
||||
if (effect.operation === "base"){
|
||||
if (value > base) base = value;
|
||||
} else if (effect.operation === "add"){
|
||||
add += value;
|
||||
} else if (effect.operation === "mul"){
|
||||
mul *= value;
|
||||
} else if (effect.operation === "min"){
|
||||
if (value > min) min = value;
|
||||
} else if (effect.operation === "max"){
|
||||
if (value < max) max = value;
|
||||
}
|
||||
});
|
||||
|
||||
//add all the add values
|
||||
Effects.find(
|
||||
{charId: charId, stat: statName, enabled: true, operation: "add"}
|
||||
).forEach(function(effect){
|
||||
value += evaluateEffect(charId, effect);
|
||||
});
|
||||
var result = (base + add) * mul;
|
||||
if (result < min) result = min;
|
||||
if (result > max) result = max;
|
||||
|
||||
//multiply all the mul values
|
||||
Effects.find(
|
||||
{charId: charId, stat: statName, enabled: true, operation: "mul"}
|
||||
).forEach(function(effect){
|
||||
value *= evaluateEffect(charId, effect);
|
||||
});
|
||||
return Math.floor(result);
|
||||
});
|
||||
|
||||
//ensure value is >= all mins
|
||||
Effects.find(
|
||||
{charId: charId, stat: statName, enabled: true, operation: "min"}
|
||||
).forEach(function(effect){
|
||||
var min = evaluateEffect(charId, effect);
|
||||
value = value > min ? value : min;
|
||||
if (Meteor.isClient) {
|
||||
Template.registerHelper("characterCalculate", function(func, charId, input) {
|
||||
try {
|
||||
return Characters.calculate[func](charId, input);
|
||||
} catch (e){
|
||||
if (!Characters.calculate[func]){
|
||||
throw new Error(func + "is not a function name");
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//ensure value is <= all maxes
|
||||
Effects.find(
|
||||
{charId: charId, stat: statName, enabled: true, operation: "max"}
|
||||
).forEach(function(effect){
|
||||
var max = evaluateEffect(charId, effect);
|
||||
value = value < max ? value : max;
|
||||
//create a local memoize with a argument concatenating hash function
|
||||
var memoize = function(f) {
|
||||
return Tracker.memoize(f, function() {
|
||||
return _.reduce(arguments, function(memo, arg) {
|
||||
return memo + arg;
|
||||
}, "");
|
||||
});
|
||||
return value;
|
||||
};
|
||||
|
||||
//functions and calculated values.
|
||||
//These functions can only rely on this._id since no other
|
||||
//field is likely to be attached to all returned characters
|
||||
Characters.helpers({
|
||||
//returns the value stored in the field requested
|
||||
//will set up dependencies on just that field
|
||||
getField : function(fieldName){
|
||||
//memoize funcitons that have finds and slow loops
|
||||
Characters.calculate = {
|
||||
getField: function(charId, fieldName) {
|
||||
var fieldSelector = {};
|
||||
fieldSelector[fieldName] = 1;
|
||||
var char = Characters.findOne(this._id, {fields: fieldSelector});
|
||||
var char = Characters.findOne(charId, {fields: fieldSelector});
|
||||
var field = char[fieldName];
|
||||
if (field === undefined){
|
||||
throw new Meteor.Error(
|
||||
@@ -287,8 +299,7 @@ Characters.helpers({
|
||||
}
|
||||
return field;
|
||||
},
|
||||
//returns the value of a field
|
||||
fieldValue : function(fieldName){
|
||||
fieldValue: function(charId, fieldName) {
|
||||
if (!Schemas.Character.schema(fieldName)){
|
||||
throw new Meteor.Error(
|
||||
"Field not found",
|
||||
@@ -298,102 +309,92 @@ Characters.helpers({
|
||||
//duck typing to get the right value function
|
||||
//.ability implies skill
|
||||
if (Schemas.Character.schema(fieldName + ".ability")){
|
||||
return this.skillMod(fieldName);
|
||||
return Characters.calculate.skillMod(charId, fieldName);
|
||||
}
|
||||
//adjustment implies attribute
|
||||
if (Schemas.Character.schema(fieldName + ".adjustment")){
|
||||
return this.attributeValue(fieldName);
|
||||
return Characters.calculate.attributeValue(charId, fieldName);
|
||||
}
|
||||
//fall back to just returning the field itself
|
||||
return this.getField(fieldName);
|
||||
return Characters.calculate.getField(charId, fieldName);
|
||||
},
|
||||
|
||||
attributeValue: function(attributeName){
|
||||
var charId = this._id;
|
||||
var attribute = this.getField(attributeName);
|
||||
attributeValue: memoize(function(charId, attributeName){
|
||||
var attribute = Characters.calculate.getField(charId, attributeName);
|
||||
//base value
|
||||
var value = this.attributeBase(attributeName);
|
||||
var value = Characters.calculate.attributeBase(charId, attributeName);
|
||||
//plus adjustment
|
||||
value += attribute.adjustment;
|
||||
return value;
|
||||
},
|
||||
|
||||
attributeBase: preventLoop(function(attributeName){
|
||||
var charId = this._id;
|
||||
//base value
|
||||
}),
|
||||
attributeBase: memoize(function(charId, attributeName){
|
||||
return attributeBase(charId, attributeName);
|
||||
}),
|
||||
|
||||
skillMod: preventLoop(function(skillName){
|
||||
var charId = this._id;
|
||||
var skill = this.getField(skillName);
|
||||
skillMod: memoize(preventLoop(function(charId, skillName){
|
||||
var skill = Characters.calculate.getField(charId, skillName);
|
||||
//get the final value of the ability score
|
||||
var ability = this.attributeValue(skill.ability);
|
||||
var ability = Characters.calculate.attributeValue(charId, skill.ability);
|
||||
|
||||
//base modifier
|
||||
var mod = +getMod(ability);
|
||||
|
||||
//multiply proficiency bonus by largest value in proficiency array
|
||||
var prof = this.proficiency(skillName);
|
||||
var prof = Characters.calculate.proficiency(charId, skillName);
|
||||
|
||||
//add multiplied proficiency bonus to modifier
|
||||
mod += prof * this.attributeValue("proficiencyBonus");
|
||||
mod += prof * Characters.calculate.attributeValue(charId, "proficiencyBonus");
|
||||
|
||||
//apply all effects
|
||||
var rawEffects = Effects.find(
|
||||
{charId: charId, stat: skillName, enabled: true}
|
||||
).fetch();
|
||||
var effects = _.groupBy(rawEffects, "operation");
|
||||
_.forEach(effects.add, function(effect){
|
||||
mod += evaluateEffect(charId, effect);
|
||||
});
|
||||
_.forEach(effects.mul, function(effect){
|
||||
mod *= evaluateEffect(charId, effect);
|
||||
});
|
||||
_.forEach(effects.min, function(effect){
|
||||
var min = evaluateEffect(charId, effect);
|
||||
mod = mod > min ? mod : min;
|
||||
});
|
||||
_.forEach(effects.max, function(effect){
|
||||
var max = evaluateEffect(charId, effect);
|
||||
mod = mod < max ? mod : max;
|
||||
});
|
||||
return signedString(mod);
|
||||
}),
|
||||
var value;
|
||||
var add = 0;
|
||||
var mul = 1;
|
||||
var min = Number.NEGATIVE_INFINITY;
|
||||
var max = Number.POSITIVE_INFINITY;
|
||||
|
||||
proficiency: function(skillName){
|
||||
var charId = this._id;
|
||||
//return largest value in proficiency array
|
||||
var prof = 0;
|
||||
Proficiencies.find(
|
||||
{charId: charId, name: skillName, enabled: true}
|
||||
).forEach(function(proficiency){
|
||||
var newProf = proficiency.value;
|
||||
if (newProf > prof){
|
||||
prof = newProf;
|
||||
Effects.find({
|
||||
charId: charId,
|
||||
stat: skillName,
|
||||
enabled: true,
|
||||
operation: {$in: ["base", "add", "mul", "min", "max"]},
|
||||
}).forEach(function(effect) {
|
||||
value = evaluateEffect(charId, effect);
|
||||
if (effect.operation === "add"){
|
||||
add += value;
|
||||
} else if (effect.operation === "mul"){
|
||||
mul *= value;
|
||||
} else if (effect.operation === "min"){
|
||||
if (value > min) min = value;
|
||||
} else if (effect.operation === "max"){
|
||||
if (value < max) max = value;
|
||||
}
|
||||
});
|
||||
return prof;
|
||||
},
|
||||
var result = (mod + add) * mul;
|
||||
if (result < min) result = min;
|
||||
if (result > max) result = max;
|
||||
|
||||
passiveSkill: function(skillName){
|
||||
if (_.isString(skillName)){
|
||||
var skill = this.getField(skillName);
|
||||
}
|
||||
var charId = this._id;
|
||||
var mod = +this.skillMod(skillName);
|
||||
return Math.floor(result);
|
||||
})),
|
||||
proficiency: memoize(function(charId, skillName){
|
||||
//return largest value in proficiency array
|
||||
var prof = Proficiencies.findOne(
|
||||
{charId: charId, name: skillName, enabled: true},
|
||||
{sort: {value: -1}}
|
||||
);
|
||||
return prof && prof.value || 0;
|
||||
}),
|
||||
passiveSkill: memoize(function(charId, skillName){
|
||||
var skill = Characters.calculate.getField(charId, skillName);
|
||||
var mod = +Characters.calculate.skillMod(charId, skillName);
|
||||
var value = 10 + mod;
|
||||
Effects.find(
|
||||
{charId: charId, stat: skillName, enabled: true, operation: "passiveAdd"}
|
||||
).forEach(function(effect){
|
||||
value += evaluateEffect(charId, effect);
|
||||
});
|
||||
return value;
|
||||
//TODO decide whether (dis)advantage gives (-)+5 to passive checks
|
||||
},
|
||||
|
||||
advantage: function(skillName){
|
||||
var charId = this._id;
|
||||
var advantage = Characters.calculate.advantage(charId, skillName);
|
||||
value += 5 * advantage;
|
||||
return Math.floor(value);
|
||||
}),
|
||||
advantage: memoize(function(charId, skillName){
|
||||
var advantage = Effects.find(
|
||||
{charId: charId, stat: skillName, enabled: true, operation: "advantage"}
|
||||
).count();
|
||||
@@ -403,19 +404,18 @@ Characters.helpers({
|
||||
if (advantage && !disadvantage) return 1;
|
||||
if (disadvantage && !advantage) return -1;
|
||||
return 0;
|
||||
}),
|
||||
abilityMod: function(charId, attribute){
|
||||
return getMod(
|
||||
Characters.calculate.attributeValue(charId, attribute)
|
||||
);
|
||||
},
|
||||
|
||||
abilityMod: function(attribute){
|
||||
return signedString(getMod(this.attributeValue(attribute)));
|
||||
},
|
||||
|
||||
passiveAbility: function(attribute){
|
||||
var mod = +getMod(this.attributeValue(attribute));
|
||||
passiveAbility: function(charId, attribute){
|
||||
var mod = +getMod(Characters.calculate.attributeValue(charId, attribute));
|
||||
return 10 + mod;
|
||||
},
|
||||
|
||||
xpLevel: function(){
|
||||
var xp = this.experience();
|
||||
xpLevel: function(charId){
|
||||
var xp = Characters.calculate.experience(charId);
|
||||
for (var i = 0; i < 19; i++){
|
||||
if (xp < XP_TABLE[i]){
|
||||
return i;
|
||||
@@ -424,30 +424,103 @@ Characters.helpers({
|
||||
if (xp > 355000) return 20;
|
||||
return 0;
|
||||
},
|
||||
|
||||
level: function(){
|
||||
level: memoize(function(charId){
|
||||
var level = 0;
|
||||
Classes.find({charId: this._id}).forEach(function(cls){
|
||||
Classes.find({charId: charId}).forEach(function(cls){
|
||||
level += cls.level;
|
||||
});
|
||||
return level;
|
||||
},
|
||||
|
||||
experience: function(){
|
||||
}),
|
||||
experience: memoize(function(charId){
|
||||
var xp = 0;
|
||||
Experiences.find(
|
||||
{charId: this._id},
|
||||
{charId: charId},
|
||||
{fields: {value: 1}}
|
||||
).forEach(function(e){
|
||||
xp += e.value;
|
||||
});
|
||||
return xp;
|
||||
}),
|
||||
};
|
||||
|
||||
var depreciated = function() {
|
||||
//var err = new Error("this function has been depreciated");
|
||||
var name = "";
|
||||
if (Template.instance()){
|
||||
name = Template.instance().view.name;
|
||||
}
|
||||
var logString = "this function has been depreciated \n";
|
||||
if (name){
|
||||
logString += "View: " + name + "\n\n";
|
||||
}
|
||||
//logString += err.stack + "\n\n---------------------\n\n";
|
||||
console.log(logString);
|
||||
};
|
||||
|
||||
//functions and calculated values.
|
||||
//These functions can only rely on this._id since no other
|
||||
//field is likely to be attached to all returned characters
|
||||
Characters.helpers({
|
||||
//returns the value stored in the field requested
|
||||
//will set up dependencies on just that field
|
||||
getField : function(fieldName){
|
||||
depreciated();
|
||||
return Characters.calculate.getField(this._id, fieldName);
|
||||
},
|
||||
//returns the value of a field
|
||||
fieldValue : function(fieldName){
|
||||
depreciated();
|
||||
return Characters.calculate.fieldValue(this._id, fieldName);
|
||||
},
|
||||
attributeValue: function(attributeName){
|
||||
depreciated();
|
||||
return Characters.calculate.attributeValue(this._id, attributeName);
|
||||
},
|
||||
attributeBase: function(attributeName){
|
||||
depreciated();
|
||||
return Characters.calculate.attributeBase(this._id, attributeName);
|
||||
},
|
||||
skillMod: function(skillName){
|
||||
depreciated();
|
||||
return Characters.calculate.skillMod(this._id, skillName);
|
||||
},
|
||||
proficiency: function(skillName){
|
||||
depreciated();
|
||||
return Characters.calculate.proficiency(this._id, skillName);
|
||||
},
|
||||
passiveSkill: function(skillName){
|
||||
depreciated();
|
||||
return Characters.calculate.passiveSkill(this._id, skillName);
|
||||
},
|
||||
advantage: function(skillName){
|
||||
depreciated();
|
||||
return Characters.calculate.advantage(this._id, skillName);
|
||||
},
|
||||
abilityMod: function(attribute){
|
||||
depreciated();
|
||||
return Characters.calculate.abilityMod(this._id, attribute);
|
||||
},
|
||||
passiveAbility: function(attribute){
|
||||
depreciated();
|
||||
return Characters.calculate.passiveAbility(this._id, attribute);
|
||||
},
|
||||
xpLevel: function(){
|
||||
depreciated();
|
||||
return Characters.calculate.xpLevel(this._id);
|
||||
},
|
||||
level: function(){
|
||||
depreciated();
|
||||
return Characters.calculate.level(this._id);
|
||||
},
|
||||
experience: function(){
|
||||
depreciated();
|
||||
return Characters.calculate.experience(this._id);
|
||||
},
|
||||
});
|
||||
|
||||
//clean up all data related to that character before removing it
|
||||
Characters.after.remove(function(userId, character) {
|
||||
if (Meteor.isServer){
|
||||
if (Meteor.isServer){
|
||||
Characters.after.remove(function(userId, character) {
|
||||
Actions .remove({charId: character._id});
|
||||
Attacks .remove({charId: character._id});
|
||||
Buffs .remove({charId: character._id});
|
||||
@@ -460,8 +533,8 @@ Characters.after.remove(function(userId, character) {
|
||||
SpellLists .remove({charId: character._id});
|
||||
Items .remove({charId: character._id});
|
||||
Containers .remove({charId: character._id});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Characters.allow({
|
||||
insert: function(userId, doc) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Classes = new Mongo.Collection("classes");
|
||||
|
||||
Schemas.Class = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
|
||||
name: {type: String, trim: false},
|
||||
level: {type: Number},
|
||||
createdAt: {
|
||||
|
||||
@@ -8,6 +8,7 @@ Schemas.Effect = new SimpleSchema({
|
||||
charId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
@@ -107,6 +108,18 @@ if (Meteor.isServer) Characters.after.insert(function(userId, char) {
|
||||
group: "Inate",
|
||||
},
|
||||
});
|
||||
Effects.insert({
|
||||
charId: char._id,
|
||||
name: "Natural Carrying Capacity",
|
||||
stat: "carryMultiplier",
|
||||
operation: "base",
|
||||
value: "1",
|
||||
parent: {
|
||||
id: char._id,
|
||||
collection: "Characters",
|
||||
group: "Inate",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
Effects.attachBehaviour("softRemovable");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Experiences = new Mongo.Collection("experience");
|
||||
|
||||
Schemas.Experience = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
|
||||
name: {type: String, defaultValue: "New Experience", trim: false},
|
||||
description: {type: String, optional: true, trim: false},
|
||||
value: {type: Number, defaultValue: 0},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Features = new Mongo.Collection("features");
|
||||
|
||||
Schemas.Feature = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
|
||||
name: {type: String, trim: false},
|
||||
description: {type: String, optional: true, trim: false},
|
||||
uses: {type: String, optional: true, trim: false},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Notes = new Mongo.Collection("notes");
|
||||
|
||||
Schemas.Note = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
|
||||
name: {type: String, trim: false},
|
||||
description: {type: String, optional: true, trim: false},
|
||||
color: {
|
||||
|
||||
@@ -4,6 +4,7 @@ Schemas.Proficiency = new SimpleSchema({
|
||||
charId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
@@ -30,7 +31,7 @@ Schemas.Proficiency = new SimpleSchema({
|
||||
Proficiencies.attachSchema(Schemas.Proficiency);
|
||||
|
||||
Proficiencies.attachBehaviour("softRemovable");
|
||||
makeChild(Proficiencies);
|
||||
makeChild(Proficiencies, ["enabled"]);
|
||||
|
||||
Proficiencies.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||
Proficiencies.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SpellLists = new Mongo.Collection("spellLists");
|
||||
|
||||
Schemas.SpellLists = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
|
||||
name: {type: String, trim: false},
|
||||
description: {type: String, optional: true, trim: false},
|
||||
saveDC: {type: String, optional: true, trim: false},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Spells = new Mongo.Collection("spells");
|
||||
|
||||
Schemas.Spell = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
|
||||
prepared: {
|
||||
type: String,
|
||||
defaultValue: "prepared",
|
||||
@@ -62,6 +62,23 @@ Spells.attachSchema(Schemas.Spell);
|
||||
|
||||
Spells.attachBehaviour("softRemovable");
|
||||
makeChild(Spells); //children of spell lists
|
||||
makeParent(Spells, ["name", "enabled"]); //parents of attacks
|
||||
|
||||
Spells.after.update(function (userId, spell, fieldNames) {
|
||||
//Update prepared state of spell and child attacks to be enabled or not
|
||||
if (_.contains(fieldNames, "prepared")) {
|
||||
var childAttacks = Attacks.find({"parent.id": spell._id}).fetch();
|
||||
if (spell.prepared === "unprepared") {
|
||||
_.each(childAttacks, function(attack){
|
||||
Attacks.update(attack._id, {$set: {enabled: false}});
|
||||
});
|
||||
} else if (spell.prepared === "prepared" || "always") {
|
||||
_.each(childAttacks, function(attack){
|
||||
Attacks.update(attack._id, {$set: {enabled: true}});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Spells.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||
Spells.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
* 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,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
TemporaryHitPoints = new Mongo.Collection("temporaryHitPoints");
|
||||
|
||||
Schemas.TemporaryHitPoints = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
|
||||
name: {type: String, optional: true},
|
||||
maximum: {type: Number, defaultValue: 0},
|
||||
used: {type: Number, defaultValue: 0},
|
||||
deleteOnZero:{type: Boolean, defaultValue: true},
|
||||
maximum: {type: Number, defaultValue: 0, min: 0, max: 500},
|
||||
used: {type: Number, defaultValue: 0, min: 0, max: 500},
|
||||
deleteOnZero:{type: Boolean, defaultValue: false},
|
||||
dateAdded: {
|
||||
type: Date,
|
||||
autoValue: function() {
|
||||
|
||||
@@ -3,7 +3,7 @@ Containers = new Mongo.Collection("containers");
|
||||
|
||||
Schemas.Container = new SimpleSchema({
|
||||
name: {type: String, trim: false},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
|
||||
isCarried: {type: Boolean},
|
||||
weight: {type: Number, min: 0, defaultValue: 0, decimal: true},
|
||||
value: {type: Number, min: 0, defaultValue: 0, decimal: true},
|
||||
|
||||
@@ -4,7 +4,7 @@ Schemas.Item = new SimpleSchema({
|
||||
name: {type: String, defaultValue: "New Item", trim: false},
|
||||
plural: {type: String, optional: true, trim: false},
|
||||
description:{type: String, optional: true, trim: false},
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id}, //id of owner
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1}, //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},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
Router.configure({
|
||||
loadingTemplate: "loading",
|
||||
layoutTemplate: "layout",
|
||||
trackPageView: true,
|
||||
});
|
||||
|
||||
Router.plugin("ensureSignedIn", {
|
||||
@@ -27,12 +28,13 @@ Router.map(function() {
|
||||
},
|
||||
data: {
|
||||
characters: function(){
|
||||
return Characters.find({}, {fields: {_id: 1}});
|
||||
return Characters.find({}, {fields: {_id: 1}, sort: {name: 1}});
|
||||
}
|
||||
},
|
||||
onAfterAction: function() {
|
||||
document.title = appName;
|
||||
},
|
||||
fastRender: true,
|
||||
});
|
||||
|
||||
this.route("characterSheet", {
|
||||
@@ -56,6 +58,13 @@ Router.map(function() {
|
||||
document.title = name;
|
||||
}
|
||||
},
|
||||
//analytics
|
||||
trackPageView: false,
|
||||
onRun: function() {
|
||||
window.ga && window.ga("send", "pageview", "/character");
|
||||
this.next();
|
||||
},
|
||||
fastRender: true,
|
||||
});
|
||||
|
||||
this.route("loading", {
|
||||
@@ -84,6 +93,7 @@ Router.map(function() {
|
||||
onAfterAction: function() {
|
||||
document.title = appName;
|
||||
},
|
||||
fastRender: true,
|
||||
});
|
||||
|
||||
this.route("/guide", {
|
||||
|
||||
@@ -77,10 +77,10 @@ this.GlobalUI = (function() {
|
||||
|
||||
var throttleBack = _.throttle(function() {
|
||||
history.back();
|
||||
}, 800, {trailing: false});
|
||||
}, 100, {trailing: false});
|
||||
|
||||
GlobalUI.closeDetail = function() {
|
||||
if (!!(window.history && window.history.pushState)) {
|
||||
if (window.history && history.pushState && history.state.detail === "opened") {
|
||||
throttleBack();
|
||||
} else {
|
||||
Session.set("global.ui.detailShow", false);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
Template.registerHelper("canEditCharacter", function(charId) {
|
||||
return canEditCharacter(charId);
|
||||
});
|
||||
|
||||
canEditCharacter = function(charId) {
|
||||
var char = Characters.findOne(charId)
|
||||
var userId = Meteor.userId();
|
||||
return char.owner === userId ||
|
||||
_.contains(char.writers, userId);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,17 +3,24 @@
|
||||
$thickColumnWidth: 304px;
|
||||
$thinColumnWidth: 240px;
|
||||
|
||||
//Column layouts of cards
|
||||
//Column layout
|
||||
.column-container {
|
||||
@include column-fill(balance);
|
||||
@include column-gap(8px);
|
||||
@include column-gap(0px);
|
||||
@include column-width($thickColumnWidth);
|
||||
padding: 8px;
|
||||
padding: 4px;
|
||||
|
||||
&.thin-columns {
|
||||
@include column-count(4);
|
||||
@include column-width($thinColumnWidth);
|
||||
}
|
||||
& > div {
|
||||
padding: 4px;
|
||||
//stop divs breaking over multiple columns
|
||||
-webkit-column-break-inside: avoid;
|
||||
page-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
//Cards
|
||||
@@ -21,20 +28,6 @@ $thinColumnWidth: 240px;
|
||||
background: white;
|
||||
border-radius: 2px;
|
||||
|
||||
.column-container & {
|
||||
margin-bottom: 8px;
|
||||
width: 100%;
|
||||
//hack to stop flickering
|
||||
-webkit-backface-visibility: hidden;
|
||||
-webkit-transform: translateX(0);
|
||||
//stop breaking over column divide
|
||||
-webkit-column-break-inside: avoid;
|
||||
page-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
//Fixes extra margin at top of columns
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.top {
|
||||
cursor: pointer;
|
||||
padding: 16px;
|
||||
@@ -91,6 +84,6 @@ $thinColumnWidth: 240px;
|
||||
}
|
||||
|
||||
/* undo pointer cursor on detail box heading */
|
||||
#globalDetail .card .top {
|
||||
#globalDetail.card .top {
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ core-header-panel[drawer] {
|
||||
box-shadow: 2px 0px 5px 0px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
//Paragraphs
|
||||
p {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
//Horizontal rule
|
||||
hr {
|
||||
background-color: #444;
|
||||
@@ -37,13 +42,13 @@ hr {
|
||||
color: #444;
|
||||
height: 1px;
|
||||
line-height: 0;
|
||||
margin: 16px -16px;
|
||||
margin: 16px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
//FABs
|
||||
.floatyButton {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
td {
|
||||
padding: 8px;
|
||||
&:nth-child(1) {
|
||||
min-width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.strengthTable{
|
||||
@@ -15,4 +12,10 @@ td {
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.summaryTable {
|
||||
&:nth-child(3){
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template name="characterSettings">
|
||||
{{#with character}}
|
||||
<div>
|
||||
<table>
|
||||
<div style="height: 100px;">
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<td>Hide Spells tab</td>
|
||||
<td>
|
||||
@@ -23,4 +23,5 @@
|
||||
</table>
|
||||
</div>
|
||||
{{/with}}
|
||||
<paper-button id="doneButton" affirmative> Done </paper-button>
|
||||
</template>
|
||||
|
||||
@@ -20,7 +20,7 @@ Template.characterSheet.helpers({
|
||||
hideSpellcasting: function() {
|
||||
var char = Characters.findOne(this._id);
|
||||
return char && char.settings.hideSpellcasting;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Template.characterSheet.events({
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
label="Value"
|
||||
floatinglabel
|
||||
value={{effectValue}}
|
||||
flex>
|
||||
flex
|
||||
style="flex-basis: 100px;">
|
||||
</paper-input>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ var stats = [
|
||||
{stat: "rageDamage", name: "Rage Damage", group: "Stats"},
|
||||
{stat: "expertiseDice", name: "Expertise Dice", group: "Stats"},
|
||||
{stat: "superiorityDice", name: "Superiority Dice", group: "Stats"},
|
||||
{stat: "carryMultiplier", name: "Carry Capacity Multiplier", group: "Stats"},
|
||||
{stat: "level1SpellSlots", name: "level 1", group: "Spell Slots"},
|
||||
{stat: "level2SpellSlots", name: "level 2", group: "Spell Slots"},
|
||||
{stat: "level3SpellSlots", name: "level 3", group: "Spell Slots"},
|
||||
|
||||
@@ -42,6 +42,7 @@ var stats = {
|
||||
"rageDamage":{"name":"Rage Damage"},
|
||||
"expertiseDice":{"name":"Expertise Dice"},
|
||||
"superiorityDice":{"name":"Superiority Dice"},
|
||||
"carryMultiplier": {"name": "Carry Capacity Multiplier"},
|
||||
"level1SpellSlots":{"name":"level 1 Spell Slots"},
|
||||
"level2SpellSlots":{"name":"level 2 Spell Slots"},
|
||||
"level3SpellSlots":{"name":"level 3 Spell Slots"},
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
{{/if}}
|
||||
|
||||
{{#if description}}
|
||||
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||
<div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
|
||||
{{/if}}
|
||||
|
||||
{{> effectsViewList charId=charId parentId=_id}}
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
{{>resource name="sorceryPoints" title="Sorcery Points" color="teal" char=this}}
|
||||
<!--superiorityDice-->
|
||||
{{>resource name="superiorityDice" title="Superiority Dice" color="teal" char=this}}
|
||||
|
||||
|
||||
<!--Attacks-->
|
||||
<div>
|
||||
<paper-shadow class="card">
|
||||
<div class="top white">
|
||||
Attacks
|
||||
@@ -48,8 +49,10 @@
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
|
||||
<!--Proficiencies-->
|
||||
<div>
|
||||
<paper-shadow class="card">
|
||||
<div class="white top">
|
||||
Proficiencies
|
||||
@@ -75,13 +78,15 @@
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
|
||||
<!--features-->
|
||||
{{#each features}}
|
||||
<div>
|
||||
<paper-shadow class="card featureCard"
|
||||
hero-id="main" {{detailHero}}>
|
||||
<div class="top {{colorClass}} subhead"
|
||||
layout horizontal
|
||||
<div class="top {{colorClass}} subhead"
|
||||
layout horizontal
|
||||
hero-id="toolbar" {{detailHero}}>
|
||||
<div flex hero-id="title" {{detailHero}}>
|
||||
{{name}}
|
||||
@@ -94,57 +99,61 @@
|
||||
{{#if canEnable}}
|
||||
<core-tooltip label="Feature enabled"
|
||||
position="left">
|
||||
<paper-checkbox class="enabledCheckbox"
|
||||
checked={{enabled}}>
|
||||
<paper-checkbox class="enabledCheckbox"
|
||||
checked={{enabled}}
|
||||
disabled={{#unless canEditCharacter charId}}true{{/unless}}>
|
||||
</paper-checkbox>
|
||||
</core-tooltip>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if description}}
|
||||
<div flex class="bottom text"
|
||||
>{{evaluateString charId description}}</div>
|
||||
<div flex class="bottom">
|
||||
{{#markdown}}{{evaluateString charId shortDescription}}{{/markdown}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if hasUses}}
|
||||
<div layout horizontal center end-justified>
|
||||
<paper-button class="useFeature"
|
||||
<paper-button class="useFeature"
|
||||
disabled={{noUsesLeft}}>
|
||||
Use
|
||||
</paper-button>
|
||||
<paper-button class="resetFeature"
|
||||
<paper-button class="resetFeature"
|
||||
disabled={{usesFull}}>
|
||||
Reset
|
||||
</paper-button>
|
||||
</div>
|
||||
{{/if}}
|
||||
</paper-shadow>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="fab-buffer"></div>
|
||||
</div>
|
||||
{{#if canEditCharacter _id}}
|
||||
<paper-fab id="addFeature"
|
||||
class="floatyButton"
|
||||
icon="add"
|
||||
title="Add"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
aria-label="Add"
|
||||
<paper-fab id="addFeature"
|
||||
class="floatyButton"
|
||||
icon="add"
|
||||
title="Add"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
aria-label="Add"
|
||||
hero-id="main"></paper-fab>
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="resource">
|
||||
{{#if char.attributeBase name}}
|
||||
<paper-shadow class="card"
|
||||
{{#if characterCalculate "attributeBase" char._id name}}
|
||||
<div>
|
||||
<paper-shadow class="card"
|
||||
hero-id="main" {{detailHero name char._id}}
|
||||
layout horizontal>
|
||||
<div class="left {{getColor}} display1 white-text"
|
||||
<div class="left {{getColor}} display1 white-text"
|
||||
hero-id="toolbar" {{detailHero name char._id}}
|
||||
layout horizontal center>
|
||||
<div style="margin-right: 8px;">
|
||||
<paper-icon-button class="resourceUp"
|
||||
icon="arrow-drop-up"
|
||||
<paper-icon-button class="resourceUp"
|
||||
icon="arrow-drop-up"
|
||||
disabled={{cantIncrement}}>
|
||||
</paper-icon-button>
|
||||
<paper-icon-button class="resourceDown"
|
||||
@@ -152,13 +161,14 @@
|
||||
disabled={{cantDecrement}}>
|
||||
</paper-icon-button>
|
||||
</div>
|
||||
<div>{{char.attributeValue name}}</div>
|
||||
<div>{{characterCalculate "attributeValue" char._id name}}</div>
|
||||
<!--<div>/{{char.attributeBase name}}</div>-->
|
||||
</div>
|
||||
<div class="right clickable"
|
||||
<div class="right clickable"
|
||||
flex layout horizontal center>
|
||||
{{title}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
|
||||
@@ -3,14 +3,19 @@ Template.features.helpers({
|
||||
var features = Features.find({charId: this._id}, {sort: {color: 1, name: 1}});
|
||||
return features;
|
||||
},
|
||||
shortDescription: function() {
|
||||
if (_.isString(this.description)){
|
||||
return this.description.split(/^( *[-*_]){3,} *(?:\n+|$)/m)[0];
|
||||
}
|
||||
},
|
||||
hasUses: function(){
|
||||
return this.usesValue() > 0;
|
||||
},
|
||||
noUsesLeft: function(){
|
||||
return this.usesLeft() <= 0;
|
||||
return this.usesLeft() <= 0 || !canEditCharacter(this.charId);
|
||||
},
|
||||
usesFull: function(){
|
||||
return this.usesLeft() >= this.usesValue();
|
||||
return this.usesLeft() >= this.usesValue() || !canEditCharacter(this.charId);
|
||||
},
|
||||
colorClass: function(){
|
||||
return getColorClass(this.color);
|
||||
@@ -96,16 +101,19 @@ Template.features.events({
|
||||
|
||||
Template.resource.helpers({
|
||||
cantIncrement: function(){
|
||||
var baseBigger = this.char.attributeValue(this.name) <
|
||||
this.char.attributeBase(this.name);
|
||||
return !baseBigger;
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
var base = Characters.calculate.attributeBase(this.char._id, this.name);
|
||||
var baseBigger = value < base;
|
||||
return !baseBigger || !canEditCharacter(this.char._id);
|
||||
},
|
||||
cantDecrement: function(){
|
||||
var valuePositive = this.char.attributeValue(this.name) > 0;
|
||||
return !valuePositive;
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
var valuePositive = value > 0;
|
||||
return !valuePositive || !canEditCharacter(this.char._id);
|
||||
},
|
||||
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";
|
||||
@@ -115,14 +123,17 @@ Template.resource.helpers({
|
||||
|
||||
Template.resource.events({
|
||||
"tap .resourceUp": function(event){
|
||||
if (this.char.attributeValue(this.name) < this.char.attributeBase(this.name)){
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
var base = Characters.calculate.attributeBase(this.char._id, this.name);
|
||||
if (value < base){
|
||||
var modifier = {$inc: {}};
|
||||
modifier.$inc[this.name + ".adjustment"] = 1;
|
||||
Characters.update(this.char._id, modifier, {validate: false});
|
||||
}
|
||||
},
|
||||
"tap .resourceDown": function(event){
|
||||
if (this.char.attributeValue(this.name) > 0){
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
if (value > 0){
|
||||
var modifier = {$inc: {}};
|
||||
modifier.$inc[this.name + ".adjustment"] = -1;
|
||||
Characters.update(this.char._id, modifier, {validate: false});
|
||||
|
||||
@@ -13,8 +13,10 @@ var getFractionCarried = function(char) {
|
||||
weight += item.totalWeight();
|
||||
});
|
||||
//get strength
|
||||
var strength = char.attributeValue("strength");
|
||||
var capacity = strength * 15;
|
||||
var strength = Characters.calculate.attributeValue(char._id, "strength");
|
||||
var carryMultiplier = Characters.calculate
|
||||
.attributeValue(char._id, "carryMultiplier");
|
||||
var capacity = strength * 15 * carryMultiplier;
|
||||
return weight / capacity;
|
||||
};
|
||||
|
||||
@@ -22,7 +24,7 @@ Template.carryCapacityBar.onCreated(function() {
|
||||
var self = this;
|
||||
self.carriedFraction = new ReactiveVar(0);
|
||||
self.autorun(function() {
|
||||
self.carriedFraction.set(getFractionCarried(self.data));
|
||||
self.carriedFraction.set(getFractionCarried(Template.currentData()));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
<template name="containerView">
|
||||
<div layout horizontal wrap center justified>
|
||||
<table class="summaryTable fullwidth">
|
||||
<tr><td>Container</td><td>{{weight}}lbs</td><td>{{longValueString value}}</td></tr>
|
||||
<tr><td>Contents</td><td>{{contentsWeight}}lbs</td><td>{{longValueString contentsValue}}</td></tr>
|
||||
<tr class="body2"><td>Total</td><td>{{totalWeight}}lbs</td><td>{{longValueString totalValue}}</td></tr>
|
||||
<tr><td>Container</td><td>{{round weight}}lbs</td><td>{{longValueString value}}</td></tr>
|
||||
<tr><td>Contents</td><td>{{round contentsWeight}}lbs</td><td>{{longValueString contentsValue}}</td></tr>
|
||||
<tr class="body2"><td>Total</td><td>{{round totalWeight}}lbs</td><td>{{longValueString totalValue}}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
{{#if description}}
|
||||
<hr class="vertMargin">
|
||||
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||
<div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<div id="inventory" class="scroll-y" fit>
|
||||
<div class="column-container">
|
||||
<!--Net Worth-->
|
||||
<div>
|
||||
<paper-shadow class="card">
|
||||
<div class="white top" layout horizontal center>
|
||||
<div class="subhead" flex>
|
||||
@@ -13,7 +14,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
<!--Weight Carried-->
|
||||
<div>
|
||||
<paper-shadow class="card"
|
||||
hero-id="main" {{detailHero "weightCarried" _id}}>
|
||||
<div class="top green white-text weightCarried"
|
||||
@@ -35,8 +38,7 @@
|
||||
<div class="item-slot">
|
||||
<div class="item buff"
|
||||
hero-id="main" {{detailHero}}
|
||||
layout horizontal center
|
||||
draggable="true">
|
||||
layout horizontal center>
|
||||
<div flex>
|
||||
<core-icon icon="work"
|
||||
style="margin-right: 16px">
|
||||
@@ -49,7 +51,9 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
</paper-shadow>
|
||||
</div>
|
||||
<!--Equipment-->
|
||||
<div>
|
||||
<paper-shadow class="card equipmentContainer">
|
||||
<div class="white top" layout horizontal center>
|
||||
<div class="subhead" flex>
|
||||
@@ -77,7 +81,9 @@
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
<!--Carried Items-->
|
||||
<div>
|
||||
<paper-shadow class="card carriedContainer">
|
||||
<div class="white top" layout horizontal center>
|
||||
<div class="subhead" flex>
|
||||
@@ -96,8 +102,10 @@
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
{{#each containers}}
|
||||
<paper-shadow class="card itemContainer"
|
||||
<div>
|
||||
<paper-shadow class="card itemContainer"
|
||||
hero-id="main" {{detailHero}}>
|
||||
<div class="top {{colorClass}}"
|
||||
hero-id="toolbar" {{detailHero}}
|
||||
@@ -114,6 +122,7 @@
|
||||
</div>
|
||||
<core-tooltip label="Container carried" position="left">
|
||||
<paper-checkbox class="carriedCheckbox"
|
||||
disabled={{#unless canEditCharacter charId}}true{{/unless}}
|
||||
checked={{isCarried}}>
|
||||
</paper-checkbox>
|
||||
</core-tooltip>
|
||||
@@ -124,6 +133,7 @@
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="fab-buffer"></div>
|
||||
@@ -152,11 +162,11 @@
|
||||
<div class="item {{hidden}} inventoryItem"
|
||||
hero-id="main" {{detailHero}}
|
||||
layout horizontal center
|
||||
draggable="true">
|
||||
draggable={{canEditCharacter charId}}>
|
||||
<div flex class="itemName">
|
||||
{{#if ne1 quantity}}{{quantity}} {{/if}}{{pluralName}}
|
||||
</div>
|
||||
{{#if settings.showIncrement}}
|
||||
{{#if settings.showIncrement}}{{#if canEditCharacter charId}}
|
||||
<div class="incrementButtons">
|
||||
<paper-icon-button class="addItemQuantity"
|
||||
icon="add"
|
||||
@@ -166,7 +176,7 @@
|
||||
icon="remove"
|
||||
style="margin-right: -8px"></paper-icon-button>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -44,6 +44,12 @@ Template.inventory.helpers({
|
||||
).forEach(function(item){
|
||||
worth += item.totalValue();
|
||||
});
|
||||
Containers.find(
|
||||
{charId: this._id},
|
||||
{fields: {value : 1}}
|
||||
).forEach(function(container) {
|
||||
if (container.value) worth += container.value;
|
||||
});
|
||||
return worth;
|
||||
},
|
||||
weightCarried: function(){
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
{{#if requiresAttunement}}<div class="vertMargin">Requires Attunement</div>{{/if}}
|
||||
</div>
|
||||
{{#if description}}
|
||||
<hr class="vertMargin">
|
||||
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||
<hr style="margin: 16px 0 16px 0;">
|
||||
<div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
|
||||
{{/if}}
|
||||
{{> effectsViewList charId=charId parentId=_id}}
|
||||
{{> attacksViewList charId=charId parentId=_id}}
|
||||
|
||||
@@ -6,23 +6,27 @@
|
||||
</div>
|
||||
{{#if description}}
|
||||
<hr class="vertMargin">
|
||||
<div class="pre-wrap">{{description}}</div>
|
||||
<div>{{#markdown}}{{description}}{{/markdown}}</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<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>
|
||||
{{> experienceEdit}}
|
||||
{{/baseDialog}}
|
||||
{{/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,3 +1,7 @@
|
||||
Template.experienceEdit.onRendered(function(){
|
||||
updatePolymerInputs(this);
|
||||
});
|
||||
|
||||
Template.experienceDialog.helpers({
|
||||
experience: function(){
|
||||
Experiences.findOne(this.experienceId);
|
||||
@@ -18,8 +22,10 @@ Template.experienceDialog.events({
|
||||
);
|
||||
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;
|
||||
Experiences.update(this._id, {$set: {name: value}});
|
||||
},
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
<div id="journal" class="scroll-y" fit>
|
||||
<div class="column-container">
|
||||
<!--Experience Table-->
|
||||
<paper-shadow class="card experiencesCard"
|
||||
<div><paper-shadow class="card experiencesCard"
|
||||
hero-id="main" {{detailHero}}>
|
||||
<div class="top white subhead"
|
||||
hero-id="toolbar" {{detailHero}}
|
||||
layout horizontal center>
|
||||
<div flex>Experience</div>
|
||||
<div >{{experience}} XP</div>
|
||||
<paper-icon-button class="black54" id="addXP" icon="add"></paper-icon-button>
|
||||
<div >{{characterCalculate "experience" _id}} XP</div>
|
||||
<paper-icon-button class="black54" id="addXP" icon="add"
|
||||
disabled={{#unless canEditCharacter _id}}true{{/unless}}></paper-icon-button>
|
||||
</div>
|
||||
<div class="bottom list">
|
||||
{{#each experiences}}
|
||||
@@ -36,16 +37,16 @@
|
||||
</paper-button>
|
||||
</div>
|
||||
{{/if}}
|
||||
</paper-shadow>
|
||||
</paper-shadow></div>
|
||||
<!--Class Table-->
|
||||
<paper-shadow class="card"
|
||||
<div><paper-shadow class="card"
|
||||
hero-id="main" {{detailHero}}>
|
||||
<div class="white top"
|
||||
hero-id="toolbar" {{detailHero}}
|
||||
layout horizontal center>
|
||||
<div flex>
|
||||
<div class="containerName subhead">
|
||||
Level {{level}}
|
||||
Level {{characterCalculate "level" _id}}
|
||||
</div>
|
||||
{{#if nextLevelXP}}
|
||||
<div class="caption">
|
||||
@@ -55,7 +56,8 @@
|
||||
</div>
|
||||
<paper-icon-button class="black54"
|
||||
id="addClassButton"
|
||||
icon="add">
|
||||
icon="add"
|
||||
disabled={{#unless canEditCharacter _id}}true{{/unless}}>
|
||||
</paper-icon-button>
|
||||
</div>
|
||||
<div class="bottom list">
|
||||
@@ -76,29 +78,31 @@
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</paper-shadow></div>
|
||||
<!--Notes-->
|
||||
{{#each notes}}
|
||||
<div>
|
||||
<paper-shadow class="card" hero-id="main" {{detailHero}}>
|
||||
<div class="top {{colorClass}} noteTop subhead"
|
||||
hero-id="toolbar" {{detailHero}}
|
||||
layout horizontal center>
|
||||
{{name}}
|
||||
</div>
|
||||
<div class="bottom text">{{description}}</div>
|
||||
<div class="bottom">{{#markdown}}{{description}}{{/markdown}}</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="fab-buffer"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{#if canEditCharacter _id}}
|
||||
<paper-fab id="addNote"
|
||||
class="floatyButton"
|
||||
icon="add"
|
||||
title="Add"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
<paper-fab id="addNote"
|
||||
class="floatyButton"
|
||||
icon="add"
|
||||
title="Add"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
hero-id="main"></paper-fab>
|
||||
{{/if}}
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -41,7 +41,7 @@ Template.journal.helpers({
|
||||
return Levels.find({charId: charId, classId: this._id}, {sort: {value: 1}});
|
||||
},
|
||||
nextLevelXP: function(){
|
||||
var currentLevel = this.level();
|
||||
var currentLevel = Characters.calculate.level(this._id);
|
||||
if (currentLevel < 20){
|
||||
return XP_TABLE[currentLevel];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template name="noteDialog">
|
||||
{{#with note}}
|
||||
{{#baseDialog title=name class=colorClass startEditing=../startEditing}}
|
||||
<div class="pre-wrap">{{description}}</div>
|
||||
<div>{{#markdown}}{{description}}{{/markdown}}</div>
|
||||
{{else}}
|
||||
{{> noteDialogEdit}}
|
||||
{{/baseDialog}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template name="backgroundDialog">
|
||||
{{#baseDialog title=title class=colorClass hideColor="true" hideDelete="true" startEditing=startEditing}}
|
||||
<div class="pre-wrap">{{evaluateString charId value}}</div>
|
||||
{{#baseDialog title=title class=colorClass hideColor="true" hideDelete="true"}}
|
||||
<div>{{#markdown}}{{evaluateString charId value}}{{/markdown}}</div>
|
||||
{{> proficiencyViewList charId=charId parentId=charId parentGroup="background"}}
|
||||
{{else}}
|
||||
{{> textDialogEdit}}
|
||||
|
||||
@@ -1,18 +1,36 @@
|
||||
<template name="personaDetailsDialog">
|
||||
{{#baseDialog title=name class="deep-purple white-text" hideColor="true" hideDelete="true" startEditing=startEditing}}
|
||||
{{alignment}} {{gender}} {{race}}
|
||||
{{#with char}}
|
||||
<div>{{alignment}} {{gender}} {{race}}</div>
|
||||
<core-image style="width: 350px; height: 350px; margin-top: 8px;"
|
||||
sizing="cover"
|
||||
hero-id="image" hero
|
||||
src={{picture}}></core-image>
|
||||
{{/with}}
|
||||
{{else}}
|
||||
{{> personaDetailsEdit}}
|
||||
{{#with char}}
|
||||
{{> personaDetailsEdit}}
|
||||
{{/with}}
|
||||
{{/baseDialog}}
|
||||
</template>
|
||||
|
||||
<template name="personaDetailsEdit">
|
||||
<!--Name-->
|
||||
<paper-input id="nameInput" label="Name" floatinglabel value={{name}}></paper-input><br>
|
||||
<!--Alignment-->
|
||||
<paper-input id="alignmentInput" label="Alignment" floatinglabel value={{alignment}}></paper-input><br>
|
||||
<!--Gender-->
|
||||
<paper-input id="genderInput" label="Gender" floatinglabel value={{gender}}></paper-input><br>
|
||||
<!--Race-->
|
||||
<paper-input id="raceInput" label="Race" floatinglabel value={{race}}></paper-input><br>
|
||||
<div layout horizontal center-justified>
|
||||
<div flex style="max-width: 350px;" layout vertical>
|
||||
<!--Name-->
|
||||
<paper-input id="nameInput" label="Name" floatinglabel value={{name}}></paper-input>
|
||||
<!--Alignment-->
|
||||
<paper-input id="alignmentInput" label="Alignment" floatinglabel value={{alignment}}></paper-input>
|
||||
<!--Gender-->
|
||||
<paper-input id="genderInput" label="Gender" floatinglabel value={{gender}}></paper-input>
|
||||
<!--Race-->
|
||||
<paper-input id="raceInput" label="Race" floatinglabel value={{race}}></paper-input>
|
||||
<!--Picture-->
|
||||
<paper-input id="pictureInput" label="Picture URL" floatinglabel value={{picture}}></paper-input>
|
||||
<core-image style="height:350px; width: 100%; margin-top: 8px;"
|
||||
sizing="cover"
|
||||
hero-id="image" hero
|
||||
src={{picture}}></core-image>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,21 +2,34 @@ Template.personaDetailsEdit.onRendered(function(){
|
||||
updatePolymerInputs(this);
|
||||
});
|
||||
|
||||
Template.personaDetailsDialog.helpers({
|
||||
char: function() {
|
||||
return Characters.findOne(
|
||||
this._id,
|
||||
{fields: {name: 1, alignment: 1, gender: 1, race: 1, picture: 1}}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Template.personaDetailsEdit.events({
|
||||
"change #nameInput": function(event){
|
||||
var input = event.currentTarget.value;
|
||||
Characters.update(this.charId, {$set: {name: input}});
|
||||
Characters.update(this._id, {$set: {name: input}});
|
||||
},
|
||||
"change #alignmentInput": function(event){
|
||||
var input = event.currentTarget.value;
|
||||
Characters.update(this.charId, {$set: {alignment: input}});
|
||||
Characters.update(this._id, {$set: {alignment: input}});
|
||||
},
|
||||
"change #genderInput": function(event){
|
||||
var input = event.currentTarget.value;
|
||||
Characters.update(this.charId, {$set: {gender: input}});
|
||||
Characters.update(this._id, {$set: {gender: input}});
|
||||
},
|
||||
"change #raceInput": function(event){
|
||||
var input = event.currentTarget.value;
|
||||
Characters.update(this.charId, {$set: {race: input}});
|
||||
Characters.update(this._id, {$set: {race: input}});
|
||||
},
|
||||
"change #pictureInput": function(event){
|
||||
var input = event.currentTarget.value;
|
||||
Characters.update(this._id, {$set: {picture: input}});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,14 +3,45 @@
|
||||
<div id="persona" class="scroll-y" fit>
|
||||
<div class="column-container">
|
||||
{{#with characterDetails}}
|
||||
{{#containerCardHelper this}}{{alignment}} {{gender}} {{race}}{{/containerCardHelper}}
|
||||
<div>
|
||||
<paper-shadow class="card"
|
||||
hero-id="main" {{detailHero "details" _id}}>
|
||||
{{#unless picture}}
|
||||
<div class="top subhead characterField {{colorClass}}"
|
||||
hero-id="toolbar" {{detailHero "details" _id}}>
|
||||
<div class="subhead" flex
|
||||
hero-id="title" {{detailHero "details" _id}}>
|
||||
{{name}}
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<core-image class="characterField clickable"
|
||||
style="height:350px; width: 100%;
|
||||
background-color: #e8e8e8;"
|
||||
sizing="cover"
|
||||
hero-id="image" {{detailHero "details" _id}}
|
||||
src={{picture}}></core-image>
|
||||
{{/unless}}
|
||||
<div class="bottom">
|
||||
{{#if picture}}
|
||||
<div class="title" hero-id="title" {{detailHero "details" _id}}>
|
||||
{{name}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="subhead">
|
||||
{{alignment}} {{gender}} {{race}}
|
||||
</div>
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
{{/with}}
|
||||
{{> containerCard characterField "description" "Description"}}
|
||||
{{> containerCard characterField "personality" "Personality Traits"}}
|
||||
{{> containerCard characterField "ideals" "Ideals"}}
|
||||
{{> containerCard characterField "bonds" "Bonds"}}
|
||||
{{> containerCard characterField "flaws" "Flaws"}}
|
||||
{{> containerCard characterField "backstory" "Background"}}
|
||||
<div>{{> containerCard characterField "description" "Description"}}</div>
|
||||
<div>{{> containerCard characterField "personality" "Personality Traits"}}</div>
|
||||
<div>{{> containerCard characterField "ideals" "Ideals"}}</div>
|
||||
<div>{{> containerCard characterField "bonds" "Bonds"}}</div>
|
||||
<div>{{> containerCard characterField "flaws" "Flaws"}}</div>
|
||||
<div>{{> containerCard characterField "backstory" "Background"}}</div>
|
||||
<div>
|
||||
<paper-shadow class="card">
|
||||
<div class="white top subhead">
|
||||
Languages
|
||||
@@ -21,6 +52,7 @@
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,6 +72,6 @@
|
||||
{{title}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom text">{{> UI.contentBlock}}</div>
|
||||
<div class="bottom">{{#markdown}}{{> UI.contentBlock}}{{/markdown}}</div>
|
||||
</paper-shadow>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -11,12 +11,12 @@ Template.persona.helpers({
|
||||
characterDetails: function(){
|
||||
var char = Characters.findOne(
|
||||
this._id,
|
||||
{fields: {name: 1, gender: 1, alignment: 1, race:1}}
|
||||
{fields: {name: 1, gender: 1, alignment: 1, race:1, picture: 1}}
|
||||
);
|
||||
char.field = "details";
|
||||
char.title = char.name;
|
||||
char.color = "d";
|
||||
char.topClass = "characterField";
|
||||
char.startEditing = true;
|
||||
return char;
|
||||
},
|
||||
characterField: function(field, title){
|
||||
@@ -40,7 +40,7 @@ Template.persona.helpers({
|
||||
|
||||
Template.persona.events({
|
||||
"tap .characterField": function(event){
|
||||
if (this.field === "details"){
|
||||
if (this.field == "details"){
|
||||
this.charId = Template.parentData()._id;
|
||||
GlobalUI.setDetail({
|
||||
template: "personaDetailsDialog",
|
||||
@@ -58,6 +58,7 @@ Template.persona.events({
|
||||
field: this.field,
|
||||
title: this.title,
|
||||
color: this.color,
|
||||
startEditing: true,
|
||||
},
|
||||
heroId: this._id + this.field,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template name="textDialog">
|
||||
{{#baseDialog title=title class=colorClass hideColor="true" hideDelete="true" startEditing=startEditing}}
|
||||
<div class="pre-wrap">{{evaluateString charId value}}</div>
|
||||
<div>{{#markdown}}{{evaluateString charId value}}{{/markdown}}</div>
|
||||
{{else}}
|
||||
{{> textDialogEdit}}
|
||||
{{/baseDialog}}
|
||||
|
||||
@@ -9,24 +9,32 @@
|
||||
</template>
|
||||
|
||||
<template name="spellDetails">
|
||||
<div class="caption">
|
||||
<div class="body2">
|
||||
Level {{level}} {{school}}, {{preparedString}}
|
||||
</div>
|
||||
<div class="vertMargin">
|
||||
<div style="margin: 16px 0 16px 0;">
|
||||
{{#if castingTime}}
|
||||
<div>
|
||||
<span class="body2">Casting Time: </span><span>{{castingTime}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if range}}
|
||||
<div>
|
||||
<span class="body2">Range: </span><span>{{range}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if getComponents}}
|
||||
<div>
|
||||
<span class="body2">Components: </span><span>{{getComponents}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if duration}}
|
||||
<div>
|
||||
<span class="body2">Duration: </span><span>{{duration}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||
<div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
|
||||
{{> attacksViewList charId=charId parentId=_id}}
|
||||
</template>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
<hr class="vertMargin">
|
||||
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||
<div>{{#markdown}}{{evaluateString charId description}}{{/markdown}}</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<!--Name-->
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template name="spells">
|
||||
<div fit>
|
||||
<div id="spells" class="scroll-y" fit>
|
||||
<div style="padding: 4px;"
|
||||
<div style="padding: 4px;"
|
||||
layout horizontal start wrap>
|
||||
{{#if hasSlots}}
|
||||
<paper-shadow class="card"
|
||||
@@ -72,6 +72,7 @@
|
||||
<core-tooltip label="Change prepared spells"
|
||||
position="left">
|
||||
<paper-icon-button class="prepSpells"
|
||||
disabled={{#unless canEditCharacter charId}}true{{/unless}}
|
||||
icon="book">
|
||||
</paper-icon-button>
|
||||
</core-tooltip>
|
||||
@@ -91,7 +92,7 @@
|
||||
<div class="tall spell item"
|
||||
hero-id="main" {{detailHero}}
|
||||
layout horizontal center>
|
||||
<core-icon icon="social:whatshot"
|
||||
<core-icon icon="social:whatshot"
|
||||
style="color: {{hexColor color}};
|
||||
margin-right: 16px;"
|
||||
></core-icon>
|
||||
@@ -143,4 +144,4 @@
|
||||
</core-tooltip>
|
||||
{{/fabMenu}}
|
||||
{{/if}}
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -84,39 +84,35 @@ Template.spells.helpers({
|
||||
},
|
||||
cantCast: function(level, char){
|
||||
for (var i = level; i <= 9; i++){
|
||||
if (char.attributeValue("level" + i + "SpellSlots") > 0){
|
||||
if (Characters.calculate.attributeValue(char._id, "level" + i + "SpellSlots") > 0){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
baseSlots: function(char){
|
||||
return char.attributeBase("level" + this.level + "SpellSlots");
|
||||
},
|
||||
slots: function(char){
|
||||
return char.attributeValue("level" + this.level + "SpellSlots");
|
||||
},
|
||||
showSlots: function(char){
|
||||
return this.level && char.attributeBase("level" + this.level + "SpellSlots");
|
||||
return this.level && Characters.calculate.attributeBase(
|
||||
char._id, "level" + this.level + "SpellSlots"
|
||||
);
|
||||
},
|
||||
hasSlots: function(){
|
||||
for (var i = 1; i <= 9; i += 1){
|
||||
if (this.attributeBase("level" + i + "SpellSlots")){
|
||||
if (Characters.calculate.attributeBase(this._id, "level" + i + "SpellSlots")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
slotBubbles: function(char){
|
||||
var baseSlots = char.attributeBase("level" + this.level + "SpellSlots");
|
||||
var currentSlots = char.attributeValue("level" + this.level + "SpellSlots");
|
||||
var baseSlots = Characters.calculate.attributeBase(char._id, "level" + this.level + "SpellSlots");
|
||||
var currentSlots = Characters.calculate.attributeValue(char._id, "level" + this.level + "SpellSlots");
|
||||
var slotsUsed = baseSlots - currentSlots;
|
||||
var bubbles = [];
|
||||
var i;
|
||||
for (i = 0; i < currentSlots; i++){
|
||||
bubbles.push({
|
||||
icon: "radio-button-on",
|
||||
disabled: i !== currentSlots - 1, //last full slot not disabled
|
||||
disabled: i !== currentSlots - 1 || !canEditCharacter(char._id), //last full slot not disabled
|
||||
attribute: "level" + this.level + "SpellSlots",
|
||||
charId: char._id,
|
||||
});
|
||||
@@ -124,7 +120,7 @@ Template.spells.helpers({
|
||||
for (i = 0; i < slotsUsed; i++){
|
||||
bubbles.push({
|
||||
icon: "radio-button-off",
|
||||
disabled: i !== 0, //first empty slot not disabled
|
||||
disabled: i !== 0 || !canEditCharacter(char._id), //first empty slot not disabled
|
||||
attribute: "level" + this.level + "SpellSlots",
|
||||
charId: char._id,
|
||||
});
|
||||
@@ -143,15 +139,15 @@ Template.spells.events({
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (event.currentTarget.icon === "radio-button-off"){
|
||||
if (
|
||||
char.attributeValue(this.attribute) <
|
||||
char.attributeBase(this.attribute)
|
||||
Characters.calculate.attributeValue(char._id, this.attribute) <
|
||||
Characters.calculate.attributeBase(char._id, this.attribute)
|
||||
){
|
||||
modifier = {$inc: {}};
|
||||
modifier.$inc[this.attribute + ".adjustment"] = 1;
|
||||
Characters.update(this.charId, modifier, {validate: false});
|
||||
}
|
||||
} else {
|
||||
if (char.attributeValue(this.attribute) > 0){
|
||||
if (Characters.calculate.attributeValue(char._id, this.attribute) > 0){
|
||||
modifier = {$inc: {}};
|
||||
modifier.$inc[this.attribute + ".adjustment"] = -1;
|
||||
Characters.update(this.charId, modifier, {validate: false});
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<template name="abilityMiniCard">
|
||||
<paper-shadow class="card abilityMiniCard clickable"
|
||||
<div>
|
||||
<paper-shadow class="card abilityMiniCard clickable"
|
||||
hero-id="main" {{detailHero ability ../_id}}
|
||||
layout horizontal>
|
||||
<div class="left white-text {{color}}"
|
||||
hero-id="toolbar" {{detailHero ability ../_id}}>
|
||||
<div class="display1">{{../attributeValue ability}}</div>
|
||||
<div class="title">{{../abilityMod ability}}</div>
|
||||
<div class="display1">{{characterCalculate "attributeValue" ../_id ability}}</div>
|
||||
<div class="title">{{abilityMod}}</div>
|
||||
</div>
|
||||
<div class="right subhead" layout horizontal center>
|
||||
{{title}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Template.abilityMiniCard.helpers({
|
||||
abilityMod: function() {
|
||||
return signedString(
|
||||
Characters.calculate.abilityMod(
|
||||
Template.parentData()._id, this.ability
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -1,9 +1,11 @@
|
||||
Template.addTHPDialog.events({
|
||||
"tap #addButton": function(event, instance){
|
||||
var max = +instance.find("#quantityInput").value;
|
||||
if (!max || max < 0) max = 0;
|
||||
TemporaryHitPoints.insert({
|
||||
charId: this.charId,
|
||||
name: instance.find("#nameInput").value,
|
||||
maximum: +instance.find("#quantityInput").value,
|
||||
maximum: max,
|
||||
deleteOnZero: !!instance.find("#deleteWhenZeroCheckbox").checked,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -106,10 +106,8 @@ Template.attributeDialogView.helpers({
|
||||
return a || b || c;
|
||||
},
|
||||
adjustment: function(){
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) return;
|
||||
var value = char.attributeValue(this.statName);
|
||||
var base = char.attributeBase(this.statName);
|
||||
var value = Characters.calculate.attributeValue(this.charId, this.statName);
|
||||
var base = Characters.calculate.attributeBase(this.charId, this.statName);
|
||||
return value - base;
|
||||
},
|
||||
baseEffects: function(){
|
||||
@@ -138,14 +136,10 @@ Template.attributeDialogView.helpers({
|
||||
);
|
||||
},
|
||||
attributeBase: function(){
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) throw "character is " + char;
|
||||
return char.attributeBase(this.statName);
|
||||
return Characters.calculate.attributeBase(this.charId, this.statName);
|
||||
},
|
||||
attributeValue: function() {
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) throw "character is " + char;
|
||||
return char.attributeValue(this.statName);
|
||||
return Characters.calculate.attributeValue(this.charId, this.statName);
|
||||
},
|
||||
sourceName: function(){
|
||||
if (this.parent.group === "racial"){
|
||||
|
||||
@@ -2,27 +2,27 @@
|
||||
<table class="carryCapacityTable strengthTable">
|
||||
<tr>
|
||||
<td>Encumbered</td>
|
||||
<td>>{{evaluate charId "strength * 5"}}lbs</td>
|
||||
<td>>{{evaluate charId "strength * 5 * carryMultiplier"}}lbs</td>
|
||||
<td class="caption">Variant rule, encumbered characters move 10 feet slower</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Heavily encumbered</td>
|
||||
<td>>{{evaluate charId "strength * 10"}}lbs</td>
|
||||
<td>>{{evaluate charId "strength * 10 * carryMultiplier"}}lbs</td>
|
||||
<td class="caption">
|
||||
Variant rule, heavily encumbered characters move 20 feet slower and have disadvantage on ability checks, attack rolls, and saving thows that use Strength, Dexterity, or Constitution
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Over Encumbered</td>
|
||||
<td>>{{evaluate charId "strength * 15"}}lbs</td>
|
||||
<td>>{{evaluate charId "strength * 15 * carryMultiplier"}}lbs</td>
|
||||
<td class="caption">
|
||||
Characters that can only just lift, push or drag their current load can only move at 5 feet.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Push, drag or lift maximum</td>
|
||||
<td>{{evaluate charId "strength * 30"}}lbs</td>
|
||||
<td>{{evaluate charId "strength * 30 * carryMultiplier"}}lbs</td>
|
||||
<td class="caption"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
<template name="healthCard">
|
||||
<paper-shadow class="card container healthCard"
|
||||
hero-id="main" {{detailHero "hitPoints" _id}}
|
||||
<paper-shadow class="card container healthCard"
|
||||
hero-id="main" {{detailHero "hitPoints" _id}}
|
||||
layout horizontal wrap>
|
||||
<div class="green white-text subhead left"
|
||||
<div class="green white-text subhead left"
|
||||
hero-id="toolbar" {{detailHero "hitPoints" _id}}
|
||||
layout vertical center center-justified>
|
||||
<div class="hitPointTitle clickable">Hit Points</div>
|
||||
<paper-icon-button class="white54" id="addTempHP" icon="add"></paper-icon-button>
|
||||
<paper-icon-button class="white54"
|
||||
id="addTempHP"
|
||||
icon="add"
|
||||
disabled={{#unless canEditCharacter _id}}true{{/unless}}>
|
||||
</paper-icon-button>
|
||||
</div>
|
||||
<div class="right" flex layout vertical center-justified style="min-width: 180px;">
|
||||
<div layout horizontal>
|
||||
<paper-diff-slider id="hitPointSlider"
|
||||
value={{attributeValue "hitPoints"}}
|
||||
max={{attributeBase "hitPoints"}}
|
||||
editable pin
|
||||
role="slider"
|
||||
></paper-diff-slider>
|
||||
value={{characterCalculate "attributeValue" _id "hitPoints"}}
|
||||
max={{characterCalculate "attributeBase" _id "hitPoints"}}
|
||||
editable pin
|
||||
disabled={{#unless canEditCharacter _id}}true{{/unless}}
|
||||
role="slider">
|
||||
</paper-diff-slider>
|
||||
</div>
|
||||
{{#each tempHitPoints}}
|
||||
<div>
|
||||
@@ -28,16 +33,28 @@
|
||||
role="slider"
|
||||
flex
|
||||
></paper-diff-slider>
|
||||
{{#unless left}}{{#unless deleteOnZero}}
|
||||
{{#unless left}}
|
||||
<paper-icon-button class="deleteTHP" icon="delete"></paper-icon-button>
|
||||
{{/unless}}{{/unless}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
<div class="caption">
|
||||
{{#if multipliers.immunities.length}} <div>Immune: {{#each multipliers.immunities}} {{name}} {{/each}}</div>{{/if}}
|
||||
{{#if multipliers.resistances.length}}<div>Resistance: {{#each multipliers.resistances}} {{name}} {{/each}}</div>{{/if}}
|
||||
{{#if multipliers.weaknesses.length}} <div>Weakness: {{#each multipliers.weaknesses}} {{name}} {{/each}}</div>{{/if}}
|
||||
{{#if multipliers.immunities.length}}
|
||||
<div>
|
||||
Immune: {{#each multipliers.immunities}} {{name}} {{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if multipliers.resistances.length}}
|
||||
<div>
|
||||
Resistance: {{#each multipliers.resistances}} {{name}} {{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if multipliers.weaknesses.length}}
|
||||
<div>
|
||||
Weakness: {{#each multipliers.weaknesses}} {{name}} {{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if showDeathSave}}
|
||||
{{#with deathSaveObject}}
|
||||
|
||||
@@ -3,7 +3,7 @@ Template.healthCard.helpers({
|
||||
return TemporaryHitPoints.find({charId: this._id});
|
||||
},
|
||||
showDeathSave: function(){
|
||||
return this.attributeValue("hitPoints") <= 0;
|
||||
return Characters.calculate.attributeValue(this._id, "hitPoints") <= 0;
|
||||
},
|
||||
deathSaveObject: function(){
|
||||
var char = Characters.findOne(this._id, {fields: {deathSave: 1}});
|
||||
@@ -27,21 +27,20 @@ Template.healthCard.helpers({
|
||||
return this.fail >= 3;
|
||||
},
|
||||
multipliers: function(){
|
||||
var char = Characters.findOne(this._id, {fields: {_id: 1}});
|
||||
var multipliers = [
|
||||
{name: "Acid", value: char.attributeValue("acidMultiplier", 1)},
|
||||
{name: "Bludgeoning", value: char.attributeValue("bludgeoningMultiplier", 1)},
|
||||
{name: "Cold", value: char.attributeValue("coldMultiplier", 1)},
|
||||
{name: "Fire", value: char.attributeValue("fireMultiplier", 1)},
|
||||
{name: "Force", value: char.attributeValue("forceMultiplier", 1)},
|
||||
{name: "Lightning", value: char.attributeValue("lightningMultiplier", 1)},
|
||||
{name: "Necrotic", value: char.attributeValue("necroticMultiplier", 1)},
|
||||
{name: "Piercing", value: char.attributeValue("piercingMultiplier", 1)},
|
||||
{name: "Poison", value: char.attributeValue("poisonMultiplier", 1)},
|
||||
{name: "Psychic", value: char.attributeValue("psychicMultiplier", 1)},
|
||||
{name: "Radiant", value: char.attributeValue("radiantMultiplier", 1)},
|
||||
{name: "Slashing", value: char.attributeValue("slashingMultiplier", 1)},
|
||||
{name: "Thunder", value: char.attributeValue("thunderMultiplier", 1)},
|
||||
{name: "Acid", value: Characters.calculate.attributeValue(this._id, "acidMultiplier")},
|
||||
{name: "Bludgeoning", value: Characters.calculate.attributeValue(this._id, "bludgeoningMultiplier")},
|
||||
{name: "Cold", value: Characters.calculate.attributeValue(this._id, "coldMultiplier")},
|
||||
{name: "Fire", value: Characters.calculate.attributeValue(this._id, "fireMultiplier")},
|
||||
{name: "Force", value: Characters.calculate.attributeValue(this._id, "forceMultiplier")},
|
||||
{name: "Lightning", value: Characters.calculate.attributeValue(this._id, "lightningMultiplier")},
|
||||
{name: "Necrotic", value: Characters.calculate.attributeValue(this._id, "necroticMultiplier")},
|
||||
{name: "Piercing", value: Characters.calculate.attributeValue(this._id, "piercingMultiplier")},
|
||||
{name: "Poison", value: Characters.calculate.attributeValue(this._id, "poisonMultiplier")},
|
||||
{name: "Psychic", value: Characters.calculate.attributeValue(this._id, "psychicMultiplier")},
|
||||
{name: "Radiant", value: Characters.calculate.attributeValue(this._id, "radiantMultiplier")},
|
||||
{name: "Slashing", value: Characters.calculate.attributeValue(this._id, "slashingMultiplier")},
|
||||
{name: "Thunder", value: Characters.calculate.attributeValue(this._id, "thunderMultiplier")},
|
||||
];
|
||||
multipliers = _.groupBy(multipliers, "value");
|
||||
return {
|
||||
@@ -55,7 +54,8 @@ Template.healthCard.helpers({
|
||||
Template.healthCard.events({
|
||||
"change #hitPointSlider": function(event){
|
||||
var value = event.currentTarget.value;
|
||||
var adjustment = value - this.attributeBase("hitPoints");
|
||||
var base = Characters.calculate.attributeBase(this._id, "hitPoints")
|
||||
var adjustment = value - base;
|
||||
Characters.update(this._id, {$set: {"hitPoints.adjustment": adjustment}});
|
||||
//reset the death saves if we are gaining HP
|
||||
if (value > 0)
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<template name="hitDice">
|
||||
{{#if ../attributeBase name}}
|
||||
<paper-shadow class="card hit-dice" hero-id="main"
|
||||
{{detailHero name ../_id}}
|
||||
{{#if characterCalculate "attributeBase" ../_id name}}
|
||||
<div>
|
||||
<paper-shadow class="card hit-dice" hero-id="main"
|
||||
{{detailHero name ../_id}}
|
||||
layout horizontal>
|
||||
<div class="left green display1 white-text"
|
||||
<div class="left green display1 white-text"
|
||||
hero-id="toolbar" {{detailHero name ../_id}}
|
||||
layout horizontal>
|
||||
<div>
|
||||
<paper-icon-button class="resourceUp"
|
||||
icon="arrow-drop-up"
|
||||
<paper-icon-button class="resourceUp"
|
||||
icon="arrow-drop-up"
|
||||
disabled={{cantIncrement}}>
|
||||
</paper-icon-button>
|
||||
<paper-icon-button class="resourceDown"
|
||||
@@ -18,10 +19,10 @@
|
||||
</div>
|
||||
<div class="resourceValue" layout vertical center>
|
||||
<div>
|
||||
{{../attributeValue name}}
|
||||
{{characterCalculate "attributeValue" ../_id name}}
|
||||
</div>
|
||||
<div class="title white-text">
|
||||
d{{diceNum}} {{../abilityMod "constitution"}}
|
||||
d{{diceNum}} {{conMod}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,5 +30,6 @@
|
||||
Hit Dice
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
Template.hitDice.helpers({
|
||||
cantIncrement: function(){
|
||||
var valueSmallerThanBase = this.char.attributeValue(this.name) <
|
||||
this.char.attributeBase(this.name);
|
||||
return !valueSmallerThanBase;
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
var base = Characters.calculate.attributeBase(this.char._id, this.name);
|
||||
return value >= base || !canEditCharacter(this.char._id);
|
||||
},
|
||||
cantDecrement: function(){
|
||||
var valuePositive = this.char.attributeValue(this.name) > 0;
|
||||
return !valuePositive;
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
return value <= 0 || !canEditCharacter(this.char._id);
|
||||
},
|
||||
conMod: function(){
|
||||
return signedString(
|
||||
Characters.calculate.abilityMod(this.char._id, "constitution")
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Template.hitDice.events({
|
||||
"tap .resourceUp": function(event){
|
||||
if (this.char.attributeValue(this.name) < this.char.attributeBase(this.name)){
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
var base = Characters.calculate.attributeBase(this.char._id, this.name);
|
||||
if (value < base){
|
||||
var modifier = {$inc: {}};
|
||||
modifier.$inc[this.name + ".adjustment"] = 1;
|
||||
Characters.update(this.char._id, modifier, {validate: false});
|
||||
}
|
||||
},
|
||||
"tap .resourceDown": function(event){
|
||||
if (this.char.attributeValue(this.name) > 0){
|
||||
var value = Characters.calculate.attributeValue(this.char._id, this.name);
|
||||
if (value > 0){
|
||||
var modifier = {$inc: {}};
|
||||
modifier.$inc[this.name + ".adjustment"] = -1;
|
||||
Characters.update(this.char._id, modifier, {validate: false});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- needs name, char, and skillName -->
|
||||
<!-- needs name, charId, and skillName -->
|
||||
<template name="skillDialog">
|
||||
{{#baseDialog title=name class=color hideEdit=true}}
|
||||
{{> skillDialogView}}
|
||||
@@ -8,7 +8,7 @@
|
||||
<template name="skillDialogView">
|
||||
<div layout vertical center>
|
||||
<div class="display2">
|
||||
{{char.skillMod skillName}}
|
||||
{{characterCalculate "skillMod" charId skillName}}
|
||||
</div>
|
||||
<div class="subhead">
|
||||
<core-icon icon="{{profIcon}}" class="black54"></core-icon>
|
||||
@@ -25,9 +25,9 @@
|
||||
<table class="summaryTable">
|
||||
<tr>
|
||||
<td>{{abilityName}}</td>
|
||||
<td>{{char.abilityMod ability}}</td>
|
||||
<td>{{characterCalculate "abilityMod" charId ability}}</td>
|
||||
</tr>
|
||||
{{#if char.proficiency skillName}}
|
||||
{{#if characterCalculate "proficiency" charId skillName}}
|
||||
<tr>
|
||||
<td>{{proficiencyValue}}</td>
|
||||
<td>{{signedString profBonus}}</td>
|
||||
@@ -59,7 +59,7 @@
|
||||
{{/each}}
|
||||
<tr class="body2">
|
||||
<td>Total</td>
|
||||
<td>{{char.skillMod skillName}}</td>
|
||||
<td>{{characterCalculate "skillMod" charId skillName}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -106,9 +106,7 @@ Template.skillDialogView.helpers({
|
||||
return a || b || c;
|
||||
},
|
||||
profIcon: function(){
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) return;
|
||||
var prof = char.proficiency(this.skillName);
|
||||
var prof = Characters.calculate.proficiency(this.charId, this.skillName);
|
||||
if (prof > 0 && prof < 1) return "image:brightness-2";
|
||||
if (prof === 1) return "image:brightness-1";
|
||||
if (prof > 1) return "av:album";
|
||||
@@ -123,13 +121,13 @@ Template.skillDialogView.helpers({
|
||||
profBonus: function(){
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) return;
|
||||
return char.proficiency(this.skillName) *
|
||||
char.attributeValue("proficiencyBonus");
|
||||
var prof = Characters.calculate.proficiency(this.charId, this.skillName);
|
||||
var proficiencyBonus =
|
||||
Characters.calculate.attributeValue(this.charId, "proficiencyBonus");
|
||||
return prof * proficiencyBonus;
|
||||
},
|
||||
proficiencyValue: function(){
|
||||
var char = Characters.findOne(this.charId);
|
||||
if (!char) return;
|
||||
var prof = char.proficiency(this.skillName);
|
||||
var prof = Characters.calculate.proficiency(this.charId, this.skillName);
|
||||
if (prof == 0.5) return "Half Proficiency";
|
||||
if (prof == 1) return "Proficient";
|
||||
if (prof == 2) return "Double Proficiency";
|
||||
@@ -199,22 +197,15 @@ Template.skillDialogView.helpers({
|
||||
return skill.ability;
|
||||
},
|
||||
abilityName: function(){
|
||||
var opts = {fields: {}};
|
||||
opts.fields[this.skillName] = 1;
|
||||
var char = Characters.findOne(this.charId, opts);
|
||||
if (!char) return;
|
||||
var skill = char[this.skillName];
|
||||
var skill = Characters.calculate.getField(this.charId, this.skillName);
|
||||
if (!skill) return;
|
||||
var ability = skill.ability;
|
||||
return abilities[ability] && abilities[ability].name;
|
||||
},
|
||||
char: function(){
|
||||
return Characters.findOne(this.charId, {fields:{_id: 1}});
|
||||
},
|
||||
sourceName: function(){
|
||||
if (this.parent.collection === "Characters"){
|
||||
if (this.parent.group === "racial"){
|
||||
return Characters.findOne(this.charId, {fields:{race: 1}}).race || "Race";
|
||||
return Characters.calculate.getField(this.charId, "race") || "Race";
|
||||
}
|
||||
if (this.parent.group === "background"){
|
||||
return "Background";
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
{{#if failSkill}}
|
||||
<div class="fail skill-mod">fail</div>
|
||||
{{else}}
|
||||
<div class="{{advantage}} skill-mod">{{../skillMod skill}}</div>
|
||||
<div class="{{advantage}} skill-mod">
|
||||
{{skillMod}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div flex>
|
||||
{{name}}
|
||||
@@ -16,7 +18,7 @@
|
||||
*
|
||||
{{/if}}
|
||||
{{#if showPassive}}
|
||||
({{../passiveSkill skill}})
|
||||
({{characterCalculate "passiveSkill" ../_id skill}})
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
Template.skillRow.helpers({
|
||||
skillMod: function() {
|
||||
return signedString(
|
||||
Characters.calculate.skillMod(
|
||||
Template.parentData()._id, this.skill
|
||||
)
|
||||
);
|
||||
},
|
||||
profIcon: function(){
|
||||
var prof = Template.parentData(1).proficiency(this.skill);
|
||||
var charId = Template.parentData()._id;
|
||||
var prof = Characters.calculate.proficiency(charId, this.skill);
|
||||
if (prof > 0 && prof < 1) return "image:brightness-2";
|
||||
if (prof === 1) return "image:brightness-1";
|
||||
if (prof > 1) return "av:album";
|
||||
return "radio-button-off";
|
||||
},
|
||||
failSkill: function(){
|
||||
var charId = Template.parentData(1)._id;
|
||||
var charId = Template.parentData()._id;
|
||||
return Effects.find({
|
||||
charId: charId,
|
||||
stat: this.skill,
|
||||
@@ -16,12 +24,13 @@ Template.skillRow.helpers({
|
||||
}).count();
|
||||
},
|
||||
advantage: function(){
|
||||
var advantage = Template.parentData(1).advantage(this.skill);
|
||||
var charId = Template.parentData()._id;
|
||||
var advantage = Characters.calculate.advantage(charId, this.skill);
|
||||
if (advantage > 0) return "advantage";
|
||||
if (advantage < 0) return "disadvantage";
|
||||
},
|
||||
conditionalCount: function(){
|
||||
var charId = Template.parentData(1)._id;
|
||||
var charId = Template.parentData()._id;
|
||||
return Effects.find({
|
||||
charId: charId,
|
||||
stat: this.skill,
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
{{>hitDice name="d10HitDice" diceNum="10" char=this}}
|
||||
{{>hitDice name="d12HitDice" diceNum="12" char=this}}
|
||||
<!--Saving Throws-->
|
||||
<div>
|
||||
<paper-shadow class="card">
|
||||
<div class="top white subhead">
|
||||
Saving Throws
|
||||
@@ -40,7 +41,9 @@
|
||||
{{> skillRow name="Charisma" skill="charismaSave"}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
<!--Skills-->
|
||||
<div>
|
||||
<paper-shadow class="card">
|
||||
<div class="top white subhead">
|
||||
Skills
|
||||
@@ -66,22 +69,25 @@
|
||||
{{> skillRow name="Survival" skill="survival"}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="statCard">
|
||||
<div>
|
||||
<paper-shadow class="card statCard clickable" hero-id="main" {{detailHero stat ../_id}} layout horizontal>
|
||||
<div class="left display1 white-text {{color}}"
|
||||
hero-id="toolbar" {{detailHero stat ../_id}}>
|
||||
{{#if isSkill}}
|
||||
{{../skillMod stat}}
|
||||
{{prefix}}{{skillMod}}
|
||||
{{else}}
|
||||
{{prefix}}{{../attributeValue stat}}
|
||||
{{prefix}}{{characterCalculate "attributeValue" ../_id stat}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="right subhead" flex horizontal layout center>
|
||||
{{name}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -67,6 +67,12 @@ Template.stats.events({
|
||||
},
|
||||
});
|
||||
|
||||
Template.stats.helpers({
|
||||
|
||||
Template.statCard.helpers({
|
||||
skillMod: function() {
|
||||
return signedString(
|
||||
Characters.calculate.skillMod(
|
||||
Template.parentData()._id, this.stat
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,7 +13,10 @@ Template.characterSideList.helpers({
|
||||
{owner: userId},
|
||||
]
|
||||
},
|
||||
{fields: {name: 1}}
|
||||
{
|
||||
fields: {name: 1},
|
||||
sort: {name: 1},
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -45,6 +45,15 @@
|
||||
</div>
|
||||
<div class="bottom text">Lawful Good Human</div>
|
||||
</paper-shadow>
|
||||
<paper-shadow class="card characterCard ssWizard clickable"
|
||||
z="2">
|
||||
<div class="top subhead deep-purple white-text">
|
||||
<div class="subhead" flex>
|
||||
Starter Set Wizard
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom text">Chaotic Good High Elf</div>
|
||||
</paper-shadow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,9 @@ Template.intro.events({
|
||||
"tap .ssArcher": function() {
|
||||
Router.go("/character/yBWwt5XQTTHZiRQxq");
|
||||
},
|
||||
"tap .ssWizard": function() {
|
||||
Router.go("/character/KxHKskm22fS2Xogah");
|
||||
},
|
||||
"tap .guideButton": function() {
|
||||
Router.go("/guide");
|
||||
},
|
||||
|
||||
@@ -41,4 +41,3 @@
|
||||
<!--custom components-->
|
||||
<link rel="import" href="/custom_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||
<link rel="import" href="/custom_components/paper-diff-slider/paper-diff-slider.html">
|
||||
<link rel="import" href="/custom_components/swipe-detect/swipe-detect.html">
|
||||
@@ -4,6 +4,9 @@
|
||||
</core-toolbar>
|
||||
<div fit layout vertical center center-justified>
|
||||
<paper-spinner class="bigSpinner" active></paper-spinner>
|
||||
<div class="subhead">{{randomHint}}</div>
|
||||
<div class="subhead"
|
||||
style="margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
text-align: center;">{{randomHint}}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
<template name="notFound">
|
||||
<div layout vertical center center-justified fit>
|
||||
<h2>The data for the page you requested could not be found.</h2>
|
||||
<core-toolbar class="app-grey white-text">
|
||||
<core-icon-button icon="menu" core-drawer-toggle></core-icon-button>
|
||||
</core-toolbar>
|
||||
<div layout vertical center center-justified fit
|
||||
style="padding: 16px; text-align: center;">
|
||||
<h2 style="margin-bottom: 12px;">The data for the page you requested could not be found.</h2>
|
||||
{{#if currentUser}}
|
||||
<h2>It might not exist, or you might not have permission to view it.</h2>
|
||||
<h3>It might not exist, or you might not have permission to view it.</h3>
|
||||
{{else}}
|
||||
<h2>Perhaps you need to sign in first:</h2>
|
||||
<h3>Perhaps you need to sign in first:</h3>
|
||||
{{atForm}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
@@ -13,22 +13,22 @@
|
||||
role="button"
|
||||
tabindex="0"
|
||||
icon="delete"
|
||||
aria-label="Delete Feature"
|
||||
noink></paper-icon-button>
|
||||
aria-label="Delete Feature">
|
||||
</paper-icon-button>
|
||||
{{/unless}}
|
||||
{{#unless hideColor}}
|
||||
{{> colorDropdown}}
|
||||
{{/unless}}
|
||||
<paper-icon-button id="doneEditingButton"
|
||||
icon="done"
|
||||
aria-label="Delete Feature"
|
||||
noink></paper-icon-button>
|
||||
aria-label="Delete Feature">
|
||||
</paper-icon-button>
|
||||
{{else}}
|
||||
{{#if showEdit}}
|
||||
<paper-icon-button id="editButton"
|
||||
icon="create"
|
||||
aria-label="Delete Feature"
|
||||
noink></paper-icon-button>
|
||||
aria-label="Delete Feature">
|
||||
</paper-icon-button>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
@@ -9,20 +9,11 @@ Template.baseDialog.onRendered(function(){
|
||||
|
||||
Template.baseDialog.helpers({
|
||||
editing: function(){
|
||||
return Template.instance().editing.get();
|
||||
return Template.instance().editing.get() && canEditCharacter(Template.parentData().charId);
|
||||
},
|
||||
showEdit: function() {
|
||||
if (this.hideEdit) return false;
|
||||
var charId = Template.parentData().charId;
|
||||
var userId = Meteor.userId();
|
||||
if (!userId) return false;
|
||||
if (charId){
|
||||
var char = Characters.findOne(charId);
|
||||
if (char)
|
||||
return char.owner === userId ||
|
||||
_.contains(char.writers, userId);
|
||||
}
|
||||
return true;
|
||||
return canEditCharacter(Template.parentData().charId);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
45
rpg-docs/config.vulcanize
Normal file
45
rpg-docs/config.vulcanize
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"imports": [
|
||||
"/components/core-animated-pages/core-animated-pages.html",
|
||||
"/components/core-animated-pages/transitions/cross-fade.html",
|
||||
"/components/core-animated-pages/transitions/hero-transition.html",
|
||||
"/components/core-animated-pages/transitions/slide-from-right.html",
|
||||
"/components/core-icons/av-icons.html",
|
||||
"/components/core-icons/core-icons.html",
|
||||
"/components/core-icons/editor-icons.html",
|
||||
"/components/core-icons/image-icons.html",
|
||||
"/components/core-icons/social-icons.html",
|
||||
"/components/core-image/core-image.html",
|
||||
"/components/core-item/core-item.html",
|
||||
"/components/core-menu/core-menu.html",
|
||||
"/components/core-scaffold/core-scaffold.html",
|
||||
"/components/core-transition/core-transition.html",
|
||||
|
||||
"/components/paper-button/paper-button.html",
|
||||
"/components/paper-checkbox/paper-checkbox.html",
|
||||
"/components/paper-dialog/paper-action-dialog.html",
|
||||
"/components/paper-dialog/paper-dialog.html",
|
||||
"/components/paper-dialog/paper-dialog-transition.html",
|
||||
"/components/paper-dropdown/paper-dropdown.html",
|
||||
"/components/paper-fab/paper-fab.html",
|
||||
"/components/paper-fab-menu/paper-fab-menu.html",
|
||||
"/components/paper-icon-button/paper-icon-button.html",
|
||||
"/components/paper-input/paper-autogrow-textarea.html",
|
||||
"/components/paper-input/paper-input.html",
|
||||
"/components/paper-input/paper-input-decorator.html",
|
||||
"/components/paper-item/paper-item.html",
|
||||
"/components/paper-menu-button/paper-menu-button.html",
|
||||
"/components/paper-radio-button/paper-radio-button.html",
|
||||
"/components/paper-radio-group/paper-radio-group.html",
|
||||
"/components/paper-shadow/paper-shadow.html",
|
||||
"/components/paper-spinner/paper-spinner.html",
|
||||
"/components/paper-slider/paper-slider.html",
|
||||
"/components/paper-tabs/paper-tabs.html",
|
||||
"/components/paper-toast/paper-toast.html",
|
||||
"/components/paper-toggle-button/paper-toggle-button.html",
|
||||
|
||||
"/custom_components/paper-dropdown-menu/paper-dropdown-menu.html",
|
||||
"/custom_components/paper-diff-slider/paper-diff-slider.html",
|
||||
"/custom_components/swipe-detect/swipe-detect.html"
|
||||
]
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
//evaluates a calculation string
|
||||
evaluate = function(charId, string){
|
||||
if (!string) return string;
|
||||
var char = Characters.findOne(charId, {fields: {_id: 1}});
|
||||
string = string.replace(/\b[a-z]+\b/gi, function(sub){
|
||||
//fields
|
||||
if (Schemas.Character.schema(sub)){
|
||||
return char.fieldValue(sub);
|
||||
return Characters.calculate.fieldValue(charId, sub);
|
||||
}
|
||||
//ability modifiers
|
||||
var abilityMods = [
|
||||
@@ -19,7 +18,7 @@ evaluate = function(charId, string){
|
||||
if (_.contains(abilityMods, sub)){
|
||||
var slice = sub.slice(0, -3);
|
||||
try {
|
||||
return char.abilityMod(slice);
|
||||
return Characters.calculate.abilityMod(charId, slice);
|
||||
} catch (e){
|
||||
return sub;
|
||||
}
|
||||
@@ -33,7 +32,7 @@ evaluate = function(charId, string){
|
||||
}
|
||||
//character level
|
||||
if (sub.toUpperCase() === "LEVEL"){
|
||||
return char.level();
|
||||
return Characters.calculate.level(charId);
|
||||
}
|
||||
return sub;
|
||||
});
|
||||
@@ -41,7 +40,6 @@ evaluate = function(charId, string){
|
||||
var result = math.eval(string);
|
||||
return result;
|
||||
} catch (e){
|
||||
console.log("Failed to evaluate ", string);
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
preventLoop = function(inputFunction){
|
||||
var self = this;
|
||||
if (!_.isFunction(inputFunction)){
|
||||
throw new Meteor.Error(
|
||||
"Not a function",
|
||||
@@ -9,23 +10,26 @@ preventLoop = function(inputFunction){
|
||||
//if we try to visit the same argument twice before resolving its value
|
||||
//we are in a dependency loop and need to GTFO
|
||||
var visitedArgs = [];
|
||||
return function(argument){
|
||||
var value;
|
||||
return function(){
|
||||
var result;
|
||||
var hash = _.reduce(arguments, function(memo, arg) {
|
||||
return memo + arg;
|
||||
}, "");
|
||||
//we're still evaluating this attribute, must be in a loop
|
||||
if (_.contains(visitedArgs, argument)) {
|
||||
if (_.contains(visitedArgs, hash)) {
|
||||
console.warn("dependency loop detected");
|
||||
return NaN;
|
||||
} else {
|
||||
//push this skill to the list of visited skills
|
||||
//push this hash to the list of visited hashes
|
||||
//we can't visit it again unless it returns first
|
||||
visitedArgs.push(argument);
|
||||
visitedArgs.push(hash);
|
||||
}
|
||||
try {
|
||||
value = inputFunction.call(this, argument);
|
||||
result = inputFunction.apply(this, arguments);
|
||||
} finally{
|
||||
//this argument returns or fails, pull it from the array
|
||||
visitedArgs = _.without(visitedArgs, argument);
|
||||
//this hash returns or fails, pull it from the array
|
||||
visitedArgs = _.without(visitedArgs, hash);
|
||||
}
|
||||
return value;
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
Meteor.methods({
|
||||
"getUserId": function(username){
|
||||
if (!username) return;
|
||||
regex = new RegExp("^" + username + "$", "i")
|
||||
var user = Meteor.users.findOne(
|
||||
{$or: [{username: username}, {"emails.address": username}]}
|
||||
{$or: [
|
||||
{username: username},
|
||||
{"emails.address": regex},
|
||||
{"services.google.email": regex},
|
||||
]}
|
||||
);
|
||||
return user && user._id;
|
||||
}
|
||||
|
||||
60
rpg-docs/lib/memoize/memoize.js
Normal file
60
rpg-docs/lib/memoize/memoize.js
Normal file
@@ -0,0 +1,60 @@
|
||||
Tracker.memoize = function(func, hasher){
|
||||
var memoize = function(key) {
|
||||
var cache = memoize.cache;
|
||||
var address = "" + (hasher ? hasher.apply(this, arguments) : key);
|
||||
if (!_.has(cache, address)) {
|
||||
cache[address] = new CacheObject(func, address, arguments, cache, this);
|
||||
}
|
||||
return cache[address].get();
|
||||
};
|
||||
memoize.cache = {};
|
||||
return memoize;
|
||||
};
|
||||
|
||||
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() {
|
||||
Tracker.autorun(function(computation) {
|
||||
//if this isn't the first run and nobody is listening,
|
||||
//delete itself from cache and stop the computation
|
||||
if (!computation.firstRun && !self.dep.hasDependents()){
|
||||
computation.stop();
|
||||
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;
|
||||
//tell the dependents that we've changed
|
||||
self.dep.changed();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
CacheObject.prototype.get = function() {
|
||||
//if there is an active computation, track dependents
|
||||
if (Tracker.active) this.dep.depend();
|
||||
return this.currentValue;
|
||||
};
|
||||
@@ -98,9 +98,11 @@ trackEncumbranceConditions = function(charId, templateInstance) {
|
||||
});
|
||||
var character = Characters.findOne(
|
||||
charId,
|
||||
{fields: {strength: 1, "settings": 1}}
|
||||
{fields: {"settings": 1}}
|
||||
);
|
||||
var strength = character.attributeValue("strength");
|
||||
var strength = Characters.calculate.attributeValue(charId, "strength");
|
||||
var carryMultiplier = Characters.calculate
|
||||
.attributeValue(charId, "carryMultiplier");
|
||||
var give = function(condition) {
|
||||
Meteor.call("giveCondition", charId, condition);
|
||||
};
|
||||
@@ -108,11 +110,11 @@ trackEncumbranceConditions = function(charId, templateInstance) {
|
||||
Meteor.call("removeCondition", charId, condition);
|
||||
};
|
||||
//variant encumbrance rules
|
||||
if (weight > strength * 10 &&
|
||||
if (weight > strength * 10 * carryMultiplier &&
|
||||
character.settings.useVariantEncumbrance) {
|
||||
give("encumbered2");
|
||||
remove("encumbered");
|
||||
} else if (weight > strength * 5 &&
|
||||
} else if (weight > strength * 5 * carryMultiplier &&
|
||||
character.settings.useVariantEncumbrance){
|
||||
give("encumbered");
|
||||
remove("encumbered2");
|
||||
@@ -121,11 +123,11 @@ trackEncumbranceConditions = function(charId, templateInstance) {
|
||||
remove("encumbered2");
|
||||
}
|
||||
//normal encumbrance rules
|
||||
if (weight > strength * 30 &&
|
||||
if (weight > strength * 30 * carryMultiplier &&
|
||||
character.settings.useStandardEncumbrance){
|
||||
give("encumbered4");
|
||||
remove("encumbered3");
|
||||
} else if (weight > strength * 15 &&
|
||||
} else if (weight > strength * 15 * carryMultiplier &&
|
||||
character.settings.useStandardEncumbrance) {
|
||||
give("encumbered3");
|
||||
remove("encumbered4");
|
||||
|
||||
8
rpg-docs/packages/useraccounts-polymer-1.0/.travis.yml
vendored
Normal file
8
rpg-docs/packages/useraccounts-polymer-1.0/.travis.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
sudo: required
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
before_install:
|
||||
- "curl -L http://git.io/ejPSng | /bin/sh"
|
||||
env:
|
||||
- TEST_COMMAND=meteor
|
||||
21
rpg-docs/packages/useraccounts-polymer-1.0/LICENSE
vendored
Normal file
21
rpg-docs/packages/useraccounts-polymer-1.0/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 splendido
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
48
rpg-docs/packages/useraccounts-polymer-1.0/README.md
vendored
Normal file
48
rpg-docs/packages/useraccounts-polymer-1.0/README.md
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
[](https://travis-ci.org/meteor-useraccounts/polymer)
|
||||
useraccounts:polymer
|
||||
=====================================
|
||||
|
||||
WORK IN PROGRESS - let us know about any problem you might encounter ;)
|
||||
|
||||
## TODOs
|
||||
|
||||
Add the following input types:
|
||||
|
||||
- checkbox input
|
||||
- select input
|
||||
- radio input
|
||||
|
||||
Find the proper solution for inheriting AT events for paper-button elements
|
||||
|
||||
|
||||
|
||||
This package depends on [useraccounts:core](https://atmospherejs.com/useraccounts/core)
|
||||
|
||||
Learn more [here](http://useraccounts.meteor.com) or have a look at the full [documentation](https://github.com/meteor-useraccounts/core).
|
||||
|
||||
|
||||
## Bring Your Own Polymer
|
||||
|
||||
Adding this package with `meteor add useraccounts:polymer` does not add any other packages providing Polymer .This is to let you choose the flavour you prefer! Or using an Atmosphere package, or straight up with bower!
|
||||
|
||||
|
||||
## ADD theses imports manually
|
||||
|
||||
This package does not automatically add the imports for the elements needed. If you don't have them imported already you should copy/paste these imports :
|
||||
|
||||
```HTML
|
||||
|
||||
<link rel="import" href="bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="bower_components/paper-checkbox/paper-checkbox.html">
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Anyone is welcome to contribute. Fork, make your changes, and then submit a pull request.
|
||||
|
||||
Thanks to all those who have contributed code changes to [this package](https://github.com/meteor-useraccounts/unstyled/graphs/contributors) as well as to the [core package](https://github.com/meteor-useraccounts/core/graphs/contributors) and all who have helped by submitting bug reports and feature ideas.
|
||||
7
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_error.html
vendored
Normal file
7
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_error.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<template name="atError">
|
||||
<div class="at-error" horizontal center-justified layout>
|
||||
{{#each error}}
|
||||
<p>{{errorText}}</p>
|
||||
{{/each}}
|
||||
</div>
|
||||
</template>
|
||||
2
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_error.js
vendored
Normal file
2
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_error.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atError.helpers(AccountsTemplates.atErrorHelpers);
|
||||
39
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_form.html
vendored
Normal file
39
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_form.html
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<template name="atForm">
|
||||
{{#unless hide}}
|
||||
<div class="at-form">
|
||||
{{#if showTitle}}
|
||||
{{> atTitle}}
|
||||
{{/if}}
|
||||
{{#if showOauthServices}}
|
||||
{{> atOauth}}
|
||||
{{/if}}
|
||||
{{#if showServicesSeparator}}
|
||||
{{> atSep}}
|
||||
{{/if}}
|
||||
{{#if showError}}
|
||||
{{> atError}}
|
||||
{{/if}}
|
||||
{{#if showResult}}
|
||||
{{> atResult}}
|
||||
{{/if}}
|
||||
{{#if showMessage}}
|
||||
{{> atMessage}}
|
||||
{{/if}}
|
||||
{{#if showPwdForm}}
|
||||
{{> atPwdForm}}
|
||||
{{/if}}
|
||||
{{#if showTermsLink}}
|
||||
{{> atTermsLink}}
|
||||
{{/if}}
|
||||
{{#if showSignInLink}}
|
||||
{{> atSigninLink}}
|
||||
{{/if}}
|
||||
{{#if showSignUpLink}}
|
||||
{{> atSignupLink}}
|
||||
{{/if}}
|
||||
{{#if showResendVerificationEmailLink}}
|
||||
{{> atResendVerificationEmailLink}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
</template>
|
||||
2
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_form.js
vendored
Normal file
2
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_form.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atForm.helpers(AccountsTemplates.atFormHelpers);
|
||||
81
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_input.html
vendored
Normal file
81
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_input.html
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<template name="atInput">
|
||||
{{> Template.dynamic template=templateName}}
|
||||
</template>
|
||||
|
||||
<template name="atTextInput">
|
||||
<div class="at-input pure-control-group{{#if isValidating}}validating{{/if}} {{#if hasError}}has-error{{/if}} {{#if hasSuccess}}has-success{{/if}} {{#if feedback}}has-feedback{{/if}}">
|
||||
<!-- {{#if showLabels}}
|
||||
<label for="at-field-{{_id}}">
|
||||
{{displayName}} {{#unless required}}{{optionalText}}{{/unless}}
|
||||
</label>
|
||||
{{/if}}
|
||||
<input type="{{type}}" id="at-field-{{_id}}" name="at-field-{{_id}}" placeholder="{{placeholder}}" autocapitalize="none" autocorrect="off">
|
||||
{{#if hasIcon}}
|
||||
<span class="{{iconClass}}"></span>
|
||||
{{/if}}
|
||||
{{#if hasError}}
|
||||
<span>{{errorText}}</span>
|
||||
{{/if}}
|
||||
</div> -->
|
||||
|
||||
{{#if showLabels}}
|
||||
<paper-input-decorator label=" {{displayName}} {{#unless required}}{{optionalText}}{{/unless}}" error="{{errorText}}" floatinglabel="" layout="" vertical="" isInvalid="{{#if hasError}} true {{/if}}">
|
||||
<input type="{{type}}" id="at-field-{{_id}}" is="core-input" name="at-field-{{_id}}" placeholder="{{placeholder}}" autocapitalize="none" autocorrect="off">
|
||||
</paper-input-decorator>
|
||||
{{else}}
|
||||
|
||||
<paper-input-decorator error="{{errorText}}" isInvalid="{{#if hasError}} true {{/if}}">
|
||||
<input type="{{type}}" id="at-field-{{_id}}" is="core-input" name="at-field-{{_id}}" placeholder="{{placeholder}}" autocapitalize="none" autocorrect="off">
|
||||
</paper-input-decorator>
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if hasIcon}}
|
||||
<core-icon icon="{{iconClass}}"></core-icon>
|
||||
{{/if}}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
|
||||
<template name="atCheckboxInput">
|
||||
<div class="at-input">
|
||||
<core-label horizontal layout>
|
||||
<div flex>{{displayName}}</div>
|
||||
<paper-checkbox type="{{type}}" id="at-field-{{_id}}" name="at-field-{{_id}}" {{disabled}} for></paper-checkbox>
|
||||
</core-label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="atSelectInput">
|
||||
<div class="at-input">
|
||||
<core-label>
|
||||
<div for="at-field-{{_id}}">{{displayName}}</div>
|
||||
<core-selector id="at-field-{{_id}}" name="at-field-{{_id}}" valueattr="value" for horizontal layout center justified>
|
||||
{{#each values}}
|
||||
<div value="{{value}}">{{text}}</div>
|
||||
{{/each}}
|
||||
</core-selector>
|
||||
</core-label>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<template name="atRadioInput">
|
||||
<div class="at-input">
|
||||
<label>{{displayName}}</label>
|
||||
</div>
|
||||
<paper-radio-group role="radiogroup" vertical layout>
|
||||
{{#each values}}
|
||||
<paper-radio-button id="at-field-{{id}}-choice-{{value}}" name="t-field-{{id}}" label="{{text}}" value={{value}} toggles role="radio" tabindex="0" aria-checked="true" aria-label="{{text}}" class="core-selected"></paper-radio-button>
|
||||
{{/each}}
|
||||
</paper-radio-group>
|
||||
</template>
|
||||
|
||||
<template name="atHiddenInput">
|
||||
<input type="hidden" id="at-field-{{_id}}" name="at-field-{{_id}}">
|
||||
</template>
|
||||
25
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_input.js
vendored
Normal file
25
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_input.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
_.each(AccountsTemplates.atInputRendered, function(callback){
|
||||
Template.atInput.onRendered(callback);
|
||||
Template.atHiddenInput.onRendered(callback);
|
||||
});
|
||||
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atInput.helpers(AccountsTemplates.atInputHelpers);
|
||||
|
||||
// Simply 'inherites' events from AccountsTemplates
|
||||
Template.atInput.events(AccountsTemplates.atInputEvents);
|
||||
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atTextInput.helpers(AccountsTemplates.atInputHelpers);
|
||||
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atCheckboxInput.helpers(AccountsTemplates.atInputHelpers);
|
||||
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atSelectInput.helpers(AccountsTemplates.atInputHelpers);
|
||||
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atRadioInput.helpers(AccountsTemplates.atInputHelpers);
|
||||
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atHiddenInput.helpers(AccountsTemplates.atInputHelpers);
|
||||
5
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_message.html
vendored
Normal file
5
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_message.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<template name="atMessage">
|
||||
<div class="at-message">
|
||||
{{message}}
|
||||
</div>
|
||||
</template>
|
||||
2
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_message.js
vendored
Normal file
2
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_message.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// Simply 'inherites' helpers from AccountsTemplates
|
||||
Template.atMessage.helpers(AccountsTemplates.atMessageHelpers);
|
||||
4
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_nav_button.html
vendored
Normal file
4
rpg-docs/packages/useraccounts-polymer-1.0/lib/at_nav_button.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<template name="atNavButton">
|
||||
<!-- <a id="at-nav-button">{{text}}</a> -->
|
||||
<paper-button id="at-nav-button" raised>{{text}}</paper-button>
|
||||
</template>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user