Compare commits
111 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89f03c7601 | ||
|
|
9d2eb14c0c | ||
|
|
7b3cb54983 | ||
|
|
a09bad2fed | ||
|
|
afd897edfe | ||
|
|
efc79cb6e7 | ||
|
|
35efe39ea7 | ||
|
|
4f1376a666 | ||
|
|
78b1d71b9d | ||
|
|
1323d8006c | ||
|
|
87d722adaf | ||
|
|
90e511eb00 | ||
|
|
5b8c25f5de | ||
|
|
2fbc54fee8 | ||
|
|
a064ae3fe8 | ||
|
|
ba9b518d7e | ||
|
|
2f729070b2 | ||
|
|
7aedb9451c | ||
|
|
c6886dd49e | ||
|
|
038ce490e4 | ||
|
|
52bef57637 | ||
|
|
29e9f8c8dc | ||
|
|
fea02811ff | ||
|
|
73cee52fff | ||
|
|
b58c006ed4 | ||
|
|
ef44f6c1a5 | ||
|
|
f455cea43f | ||
|
|
e4083bc744 | ||
|
|
baffafb62a | ||
|
|
4143929667 | ||
|
|
18286d1b9c | ||
|
|
9f51567162 | ||
|
|
66d8a3bfbf | ||
|
|
a9648c10cc | ||
|
|
679292373c | ||
|
|
ae416458b5 | ||
|
|
0ff4a887ea | ||
|
|
955794b5c0 | ||
|
|
b0ac1dcc29 | ||
|
|
83150bc527 | ||
|
|
061f1fd0a5 | ||
|
|
e40dd196e6 | ||
|
|
5dbb59ef80 | ||
|
|
49e25d7304 | ||
|
|
85df0257e2 | ||
|
|
b88bb95928 | ||
|
|
2122e543d5 | ||
|
|
a71519aaa7 | ||
|
|
2404845d51 | ||
|
|
bf032bcdf3 | ||
|
|
ff8ae89722 | ||
|
|
80ca7307ce | ||
|
|
a539b0bc6c | ||
|
|
c6b3cad9c8 | ||
|
|
95b7b66390 | ||
|
|
43c4122fe3 | ||
|
|
3f4dcc146a | ||
|
|
e4600decd0 | ||
|
|
f6df716870 | ||
|
|
b99da301cd | ||
|
|
0a01885300 | ||
|
|
5cb1515235 | ||
|
|
7430c2c795 | ||
|
|
39f7548b8d | ||
|
|
c4a8c4b7ba | ||
|
|
263aba596c | ||
|
|
f98ed0b659 | ||
|
|
6159ce0e88 | ||
|
|
e9509a3a24 | ||
|
|
aa069fd885 | ||
|
|
99a64667c6 | ||
|
|
e05fa064d5 | ||
|
|
b95636a8a3 | ||
|
|
bd6c7cd106 | ||
|
|
6b1ff343c2 | ||
|
|
9e7e027fe9 | ||
|
|
79e0f917df | ||
|
|
4bddf8d5d3 | ||
|
|
57159d6cfe | ||
|
|
56957e0ef0 | ||
|
|
31e7b8d610 | ||
|
|
e0209df270 | ||
|
|
40500517af | ||
|
|
c1222ad51d | ||
|
|
07890269fc | ||
|
|
895a099b9b | ||
|
|
21dfc5d086 | ||
|
|
fada0f5136 | ||
|
|
dce20375b5 | ||
|
|
6926693e9d | ||
|
|
b1e23eba9a | ||
|
|
012aad5ae9 | ||
|
|
6ec9f09b6a | ||
|
|
b76ac23713 | ||
|
|
245867dae6 | ||
|
|
1352bd1178 | ||
|
|
a5ebe4f452 | ||
|
|
e94b35564b | ||
|
|
663102718d | ||
|
|
7e4c8a21aa | ||
|
|
0536a6ab01 | ||
|
|
e7f0bb5e05 | ||
|
|
1a1ee142c0 | ||
|
|
e6487c9416 | ||
|
|
7cd353894c | ||
|
|
49a98aec96 | ||
|
|
8ec3b74299 | ||
|
|
6aeb6635a7 | ||
|
|
638209719e | ||
|
|
690eea4f29 | ||
|
|
ad43a1d331 |
56
.jscsrc
Normal file
56
.jscsrc
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"requireOperatorBeforeLineBreak": true,
|
||||||
|
"requireCamelCaseOrUpperCaseIdentifiers": true,
|
||||||
|
"maximumLineLength": {
|
||||||
|
"value": 80,
|
||||||
|
"allowComments": true,
|
||||||
|
"allowRegex": true
|
||||||
|
},
|
||||||
|
"validateIndentation": "\t",
|
||||||
|
"validateQuoteMarks": "\"",
|
||||||
|
|
||||||
|
"disallowMultipleLineStrings": true,
|
||||||
|
"disallowMixedSpacesAndTabs": "smart",
|
||||||
|
"disallowTrailingWhitespace": true,
|
||||||
|
"disallowSpaceAfterPrefixUnaryOperators": true,
|
||||||
|
"disallowMultipleVarDecl": true,
|
||||||
|
"disallowNewlineBeforeBlockStatements": true,
|
||||||
|
"disallowKeywordsOnNewLine": ["else"],
|
||||||
|
|
||||||
|
"requireSpaceAfterKeywords": [
|
||||||
|
"if",
|
||||||
|
"else",
|
||||||
|
"for",
|
||||||
|
"while",
|
||||||
|
"do",
|
||||||
|
"switch",
|
||||||
|
"return",
|
||||||
|
"try",
|
||||||
|
"catch"
|
||||||
|
],
|
||||||
|
"requireSpaceBeforeBinaryOperators": [
|
||||||
|
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
|
||||||
|
"&=", "|=", "^=", "+=",
|
||||||
|
|
||||||
|
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
|
||||||
|
"|", "^", "&&", "||", "===", "==", ">=",
|
||||||
|
"<=", "<", ">", "!=", "!=="
|
||||||
|
],
|
||||||
|
"requireSpaceAfterBinaryOperators": true,
|
||||||
|
"requireSpacesInConditionalExpression": true,
|
||||||
|
"requireSpacesInForStatement": true,
|
||||||
|
"requireTrailingComma": {
|
||||||
|
"ignoreSingleValue": true,
|
||||||
|
"ignoreSingleLine": true
|
||||||
|
},
|
||||||
|
"requireLineFeedAtFileEnd": true,
|
||||||
|
"disallowSpacesInAnonymousFunctionExpression": {
|
||||||
|
"beforeOpeningRoundBrace": true
|
||||||
|
},
|
||||||
|
"disallowSpacesInsideObjectBrackets": "all",
|
||||||
|
"disallowSpacesInsideArrayBrackets": "all",
|
||||||
|
"disallowSpacesInsideParentheses": true,
|
||||||
|
|
||||||
|
"disallowMultipleLineBreaks": true,
|
||||||
|
"disallowNewlineBeforeBlockStatements": true
|
||||||
|
}
|
||||||
3
rpg-docs/.gitignore
vendored
3
rpg-docs/.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
.meteor/local
|
.meteor/local
|
||||||
.meteor/meteorite
|
.meteor/meteorite
|
||||||
public/components
|
public/components
|
||||||
nohup.out
|
nohup.out
|
||||||
|
dump
|
||||||
@@ -16,5 +16,14 @@ differential:vulcanize
|
|||||||
matb33:collection-hooks
|
matb33:collection-hooks
|
||||||
zimme:collection-softremovable
|
zimme:collection-softremovable
|
||||||
momentjs:moment
|
momentjs:moment
|
||||||
mike:mocha
|
|
||||||
dburles:mongo-collection-instances
|
dburles:mongo-collection-instances
|
||||||
|
percolate:migrations
|
||||||
|
ecwyne:mathjs
|
||||||
|
useraccounts:polymer
|
||||||
|
accounts-google
|
||||||
|
splendido:accounts-meld
|
||||||
|
email
|
||||||
|
fourseven:scss@2.1.1
|
||||||
|
wolves:bourbon
|
||||||
|
meteorhacks:subs-manager
|
||||||
|
meteorhacks:kadira
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
accounts-base@1.2.0
|
accounts-base@1.2.0
|
||||||
|
accounts-google@1.0.4
|
||||||
|
accounts-oauth@1.1.5
|
||||||
accounts-password@1.1.1
|
accounts-password@1.1.1
|
||||||
accounts-ui@1.1.5
|
accounts-ui@1.1.5
|
||||||
accounts-ui-unstyled@1.1.7
|
accounts-ui-unstyled@1.1.7
|
||||||
aldeed:collection2@2.3.3
|
aldeed:collection2@2.3.3
|
||||||
aldeed:simple-schema@1.3.2
|
aldeed:simple-schema@1.3.3
|
||||||
amplify@1.0.0
|
|
||||||
autoupdate@1.2.1
|
autoupdate@1.2.1
|
||||||
base64@1.0.3
|
base64@1.0.3
|
||||||
binary-heap@1.0.3
|
binary-heap@1.0.3
|
||||||
@@ -18,11 +19,14 @@ dburles:collection-helpers@1.0.3
|
|||||||
dburles:mongo-collection-instances@0.3.3
|
dburles:mongo-collection-instances@0.3.3
|
||||||
ddp@1.1.0
|
ddp@1.1.0
|
||||||
deps@1.0.7
|
deps@1.0.7
|
||||||
differential:vulcanize@0.0.4
|
differential:vulcanize@0.0.5
|
||||||
|
ecwyne:mathjs@0.25.0
|
||||||
ejson@1.0.6
|
ejson@1.0.6
|
||||||
email@1.0.6
|
email@1.0.6
|
||||||
fastclick@1.0.3
|
fastclick@1.0.3
|
||||||
|
fourseven:scss@2.1.1
|
||||||
geojson-utils@1.0.3
|
geojson-utils@1.0.3
|
||||||
|
google@1.1.5
|
||||||
html-tools@1.0.4
|
html-tools@1.0.4
|
||||||
htmljs@1.0.4
|
htmljs@1.0.4
|
||||||
http@1.1.0
|
http@1.1.0
|
||||||
@@ -43,20 +47,24 @@ less@1.0.14
|
|||||||
livedata@1.0.13
|
livedata@1.0.13
|
||||||
localstorage@1.0.3
|
localstorage@1.0.3
|
||||||
logging@1.0.7
|
logging@1.0.7
|
||||||
matb33:collection-hooks@0.7.11
|
matb33:collection-hooks@0.7.13
|
||||||
meteor@1.1.6
|
meteor@1.1.6
|
||||||
meteor-platform@1.2.2
|
meteor-platform@1.2.2
|
||||||
mike:mocha@0.5.2
|
meteorhacks:kadira@2.21.0
|
||||||
|
meteorhacks:meteorx@1.3.1
|
||||||
|
meteorhacks:subs-manager@1.3.0
|
||||||
minifiers@1.1.5
|
minifiers@1.1.5
|
||||||
minimongo@1.0.8
|
minimongo@1.0.8
|
||||||
mobile-status-bar@1.0.3
|
mobile-status-bar@1.0.3
|
||||||
momentjs:moment@2.10.0
|
momentjs:moment@2.10.3
|
||||||
mongo@1.1.0
|
mongo@1.1.0
|
||||||
|
mongo-livedata@1.0.8
|
||||||
npm-bcrypt@0.7.8_2
|
npm-bcrypt@0.7.8_2
|
||||||
|
oauth@1.1.4
|
||||||
|
oauth2@1.1.3
|
||||||
observe-sequence@1.0.6
|
observe-sequence@1.0.6
|
||||||
ordered-dict@1.0.3
|
ordered-dict@1.0.3
|
||||||
practicalmeteor:chai@1.9.2_3
|
percolate:migrations@0.7.5
|
||||||
practicalmeteor:loglevel@1.1.0_3
|
|
||||||
random@1.0.3
|
random@1.0.3
|
||||||
reactive-dict@1.1.0
|
reactive-dict@1.1.0
|
||||||
reactive-var@1.0.5
|
reactive-var@1.0.5
|
||||||
@@ -66,20 +74,21 @@ routepolicy@1.0.5
|
|||||||
service-configuration@1.0.4
|
service-configuration@1.0.4
|
||||||
session@1.1.0
|
session@1.1.0
|
||||||
sha@1.0.3
|
sha@1.0.3
|
||||||
|
softwarerero:accounts-t9n@1.0.9
|
||||||
spacebars@1.0.6
|
spacebars@1.0.6
|
||||||
spacebars-compiler@1.0.6
|
spacebars-compiler@1.0.6
|
||||||
|
splendido:accounts-emails-field@1.2.0
|
||||||
|
splendido:accounts-meld@1.3.0
|
||||||
srp@1.0.3
|
srp@1.0.3
|
||||||
templating@1.1.1
|
templating@1.1.1
|
||||||
tracker@1.0.7
|
tracker@1.0.7
|
||||||
ui@1.0.6
|
ui@1.0.6
|
||||||
underscore@1.0.3
|
underscore@1.0.3
|
||||||
url@1.0.4
|
url@1.0.4
|
||||||
velocity:core@0.4.5
|
useraccounts:core@1.9.1
|
||||||
velocity:html-reporter@0.3.2
|
useraccounts:polymer@1.9.1
|
||||||
velocity:node-soft-mirror@0.3.1
|
|
||||||
velocity:shim@0.1.0
|
|
||||||
velocity:test-proxy@0.0.4
|
|
||||||
webapp@1.2.0
|
webapp@1.2.0
|
||||||
webapp-hashing@1.0.3
|
webapp-hashing@1.0.3
|
||||||
|
wolves:bourbon@1.0.0
|
||||||
zimme:collection-behaviours@1.0.4
|
zimme:collection-behaviours@1.0.4
|
||||||
zimme:collection-softremovable@1.0.4
|
zimme:collection-softremovable@1.0.4
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ Schemas.Instance = new SimpleSchema({
|
|||||||
//an instance is a single flow of time all parties in an instance are in-sync time wise
|
//an instance is a single flow of time all parties in an instance are in-sync time wise
|
||||||
});
|
});
|
||||||
|
|
||||||
Instances.attachSchema(Schemas.Instance);
|
Instances.attachSchema(Schemas.Instance);
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ Schemas.Party = new SimpleSchema({
|
|||||||
//each party can only be in a single instance at a time
|
//each party can only be in a single instance at a time
|
||||||
});
|
});
|
||||||
|
|
||||||
Parties.attachSchema(Schemas.Party);
|
Parties.attachSchema(Schemas.Party);
|
||||||
|
|||||||
@@ -5,29 +5,32 @@ Actions = new Mongo.Collection("actions");
|
|||||||
*/
|
*/
|
||||||
Schemas.Action = new SimpleSchema({
|
Schemas.Action = new SimpleSchema({
|
||||||
charId: {
|
charId: {
|
||||||
type: String,
|
type: String,
|
||||||
regEx: SimpleSchema.RegEx.Id
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String, trim: false
|
type: String,
|
||||||
|
trim: false,
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
type: String, trim: false
|
type: String,
|
||||||
|
trim: false,
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
allowedValues: ["action, bonus, reaction, free"],
|
allowedValues: ["action, bonus, reaction, free"],
|
||||||
defaultValue: "action"
|
defaultValue: "action",
|
||||||
},
|
},
|
||||||
//the immediate impact of doing this action (eg. -1 rages)
|
//the immediate impact of doing this action (eg. -1 rages)
|
||||||
adjustments: {
|
adjustments: {
|
||||||
type: [Schemas.Adjustment], defaultValue: []
|
type: [Schemas.Adjustment],
|
||||||
}
|
defaultValue: [],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Actions.attachSchema(Schemas.Action);
|
Actions.attachSchema(Schemas.Action);
|
||||||
|
|
||||||
Actions.attachBehaviour('softRemovable');
|
Actions.attachBehaviour("softRemovable");
|
||||||
makeChild(Actions);
|
makeChild(Actions);
|
||||||
|
|
||||||
Actions.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Actions.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
|
|||||||
@@ -5,68 +5,69 @@ Attacks = new Mongo.Collection("attacks");
|
|||||||
*/
|
*/
|
||||||
Schemas.Attack = new SimpleSchema({
|
Schemas.Attack = new SimpleSchema({
|
||||||
charId: {
|
charId: {
|
||||||
type: String,
|
type: String,
|
||||||
regEx: SimpleSchema.RegEx.Id
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
defaultValue: "New Attack",
|
defaultValue: "New Attack",
|
||||||
trim: false
|
trim: false,
|
||||||
},
|
},
|
||||||
details: {
|
details: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true,
|
optional: true,
|
||||||
trim: false
|
trim: false,
|
||||||
},
|
},
|
||||||
attackBonus: {
|
attackBonus: {
|
||||||
type: String,
|
type: String,
|
||||||
defaultValue: "strengthMod + proficiencyBonus",
|
defaultValue: "strengthMod + proficiencyBonus",
|
||||||
optional: true,
|
|
||||||
trim: false
|
|
||||||
},
|
|
||||||
damageBonus: {
|
|
||||||
type: String,
|
|
||||||
defaultValue: "strengthMod",
|
|
||||||
optional: true,
|
|
||||||
trim: false
|
|
||||||
},
|
|
||||||
damageDice: {
|
|
||||||
type: String,
|
|
||||||
optional: true,
|
optional: true,
|
||||||
defaultValue: "1d8",
|
trim: false,
|
||||||
allowedValues: DAMAGE_DICE
|
},
|
||||||
|
damage: {
|
||||||
|
type: String,
|
||||||
|
defaultValue: "1d8 + {strengthMod}",
|
||||||
|
optional: true,
|
||||||
|
trim: false,
|
||||||
},
|
},
|
||||||
damageType: {
|
damageType: {
|
||||||
type: String,
|
type: String,
|
||||||
allowedValues: ["bludgeoning", "piercing", "slashing", "acid", "cold", "fire", "force", "lightning", "necrotic",
|
allowedValues: [
|
||||||
"poison", "psychic", "radiant", "thunder"],
|
"bludgeoning",
|
||||||
defaultValue: "slashing"
|
"piercing",
|
||||||
},
|
"slashing",
|
||||||
//indicates what the attack originated from
|
"acid",
|
||||||
type: {
|
"cold",
|
||||||
type: String,
|
"fire",
|
||||||
defaultValue: "editable",
|
"force",
|
||||||
allowedValues: ["editable", "feature", "class", "buff", "equipment", "racial", "inate"]
|
"lightning",
|
||||||
|
"necrotic",
|
||||||
|
"poison",
|
||||||
|
"psychic",
|
||||||
|
"radiant",
|
||||||
|
"thunder",
|
||||||
|
],
|
||||||
|
defaultValue: "slashing",
|
||||||
},
|
},
|
||||||
//the id of the feature, buff or item that created this effect
|
//the id of the feature, buff or item that created this effect
|
||||||
parent: {
|
parent: {
|
||||||
type: Schemas.Parent
|
type: Schemas.Parent
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
type: String,
|
type: String,
|
||||||
allowedValues: _.pluck(colorOptions, "key"),
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
defaultValue: "q"
|
defaultValue: "q",
|
||||||
},
|
},
|
||||||
enabled: {
|
enabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
defaultValue: true
|
defaultValue: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Attacks.attachSchema(Schemas.Attack);
|
Attacks.attachSchema(Schemas.Attack);
|
||||||
|
|
||||||
Attacks.attachBehaviour('softRemovable');
|
Attacks.attachBehaviour("softRemovable");
|
||||||
makeChild(Attacks, ['name', 'enabled']); //children of lots of things
|
makeChild(Attacks, ["name", "enabled"]); //children of lots of things
|
||||||
|
|
||||||
Attacks.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Attacks.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Attacks.deny(CHARACTER_SUBSCHEMA_DENY);
|
Attacks.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -1,27 +1,51 @@
|
|||||||
Buffs = new Mongo.Collection("buffs");
|
Buffs = new Mongo.Collection("buffs");
|
||||||
|
|
||||||
//buffs are temporary once applied and store things which expire and their expiry time
|
|
||||||
Schemas.Buff = new SimpleSchema({
|
Schemas.Buff = new SimpleSchema({
|
||||||
//buff id
|
charId: {
|
||||||
_id: {
|
|
||||||
type: String,
|
type: String,
|
||||||
regEx: SimpleSchema.RegEx.Id,
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
autoValue: function(){
|
|
||||||
if(!this.isSet) return Random.id();
|
|
||||||
}},
|
|
||||||
charId: {
|
|
||||||
type: String,
|
|
||||||
regEx: SimpleSchema.RegEx.Id
|
|
||||||
},
|
},
|
||||||
//expiry time
|
name: {
|
||||||
expiry: { type: Number, optional: true},
|
type: String,
|
||||||
duration: { type: Number }
|
trim: false,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
trim: false,
|
||||||
|
},
|
||||||
|
enabled: {
|
||||||
|
type: Boolean,
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: [
|
||||||
|
"inate",
|
||||||
|
"custom",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"lifeTime.total": {
|
||||||
|
type: Number,
|
||||||
|
defaultValue: 0, //0 is infinite
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
"lifeTime.spent": {
|
||||||
|
type: Number,
|
||||||
|
defaultValue: 0,
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Buffs.attachSchema(Schemas.Buff);
|
Buffs.attachSchema(Schemas.Buff);
|
||||||
|
|
||||||
Buffs.attachBehaviour('softRemovable');
|
Buffs.attachBehaviour("softRemovable");
|
||||||
makeParent(Buffs, 'name'); //parents of effects and attacks
|
makeParent(Buffs, ["name", "enabled"]); //parents of effects
|
||||||
|
|
||||||
Buffs.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Buffs.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Buffs.deny(CHARACTER_SUBSCHEMA_DENY);
|
Buffs.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -3,18 +3,16 @@ Characters = new Mongo.Collection("characters");
|
|||||||
|
|
||||||
Schemas.Character = new SimpleSchema({
|
Schemas.Character = new SimpleSchema({
|
||||||
//strings
|
//strings
|
||||||
name: { type: String, defaultValue: "", trim: false},
|
name: {type: String, defaultValue: "", trim: false},
|
||||||
alignment: { type: String, defaultValue: "", trim: false},
|
alignment: {type: String, defaultValue: "", trim: false},
|
||||||
gender: { type: String, defaultValue: "", trim: false},
|
gender: {type: String, defaultValue: "", trim: false},
|
||||||
race: { type: String, defaultValue: "", trim: false},
|
race: {type: String, defaultValue: "", trim: false},
|
||||||
description: { type: String, defaultValue: "", trim: false},
|
description: {type: String, defaultValue: "", trim: false},
|
||||||
personality: { type: String, defaultValue: "", trim: false},
|
personality: {type: String, defaultValue: "", trim: false},
|
||||||
ideals: { type: String, defaultValue: "", trim: false},
|
ideals: {type: String, defaultValue: "", trim: false},
|
||||||
bonds: { type: String, defaultValue: "", trim: false},
|
bonds: {type: String, defaultValue: "", trim: false},
|
||||||
flaws: { type: String, defaultValue: "", trim: false},
|
flaws: {type: String, defaultValue: "", trim: false},
|
||||||
backstory: { type: String, defaultValue: "", trim: false},
|
backstory: {type: String, defaultValue: "", trim: false},
|
||||||
proficiencies:{ type: String, defaultValue: "", trim: false},
|
|
||||||
languages: { type: String, defaultValue: "", trim: false},
|
|
||||||
|
|
||||||
//attributes
|
//attributes
|
||||||
//ability scores
|
//ability scores
|
||||||
@@ -75,142 +73,191 @@ Schemas.Character = new SimpleSchema({
|
|||||||
slashingMultiplier: {type: Schemas.Attribute},
|
slashingMultiplier: {type: Schemas.Attribute},
|
||||||
thunderMultiplier: {type: Schemas.Attribute},
|
thunderMultiplier: {type: Schemas.Attribute},
|
||||||
|
|
||||||
|
|
||||||
//skills
|
//skills
|
||||||
//saves
|
//saves
|
||||||
strengthSave: {type: Schemas.Skill},
|
strengthSave: {type: Schemas.Skill},
|
||||||
"strengthSave.ability": { type: String, defaultValue: "strength" },
|
"strengthSave.ability": {type: String, defaultValue: "strength"},
|
||||||
|
|
||||||
dexteritySave: {type: Schemas.Skill},
|
dexteritySave: {type: Schemas.Skill},
|
||||||
"dexteritySave.ability": { type: String, defaultValue: "dexterity" },
|
"dexteritySave.ability": {type: String, defaultValue: "dexterity"},
|
||||||
|
|
||||||
constitutionSave:{type: Schemas.Skill},
|
constitutionSave:{type: Schemas.Skill},
|
||||||
"constitutionSave.ability": { type: String, defaultValue: "constitution" },
|
"constitutionSave.ability": {type: String, defaultValue: "constitution"},
|
||||||
|
|
||||||
intelligenceSave:{type: Schemas.Skill},
|
intelligenceSave:{type: Schemas.Skill},
|
||||||
"intelligenceSave.ability": { type: String, defaultValue: "intelligence" },
|
"intelligenceSave.ability": {type: String, defaultValue: "intelligence"},
|
||||||
|
|
||||||
wisdomSave: {type: Schemas.Skill},
|
wisdomSave: {type: Schemas.Skill},
|
||||||
"wisdomSave.ability": { type: String, defaultValue: "wisdom" },
|
"wisdomSave.ability": {type: String, defaultValue: "wisdom"},
|
||||||
|
|
||||||
charismaSave: {type: Schemas.Skill},
|
charismaSave: {type: Schemas.Skill},
|
||||||
"charismaSave.ability": { type: String, defaultValue: "charisma" },
|
"charismaSave.ability": {type: String, defaultValue: "charisma"},
|
||||||
|
|
||||||
|
|
||||||
//skill skills
|
//skill skills
|
||||||
acrobatics: {type: Schemas.Skill},
|
acrobatics: {type: Schemas.Skill},
|
||||||
"acrobatics.ability": { type: String, defaultValue: "dexterity" },
|
"acrobatics.ability": {type: String, defaultValue: "dexterity"},
|
||||||
|
|
||||||
animalHandling: {type: Schemas.Skill},
|
animalHandling: {type: Schemas.Skill},
|
||||||
"animalHandling.ability": { type: String, defaultValue: "wisdom" },
|
"animalHandling.ability": {type: String, defaultValue: "wisdom"},
|
||||||
|
|
||||||
arcana: {type: Schemas.Skill},
|
arcana: {type: Schemas.Skill},
|
||||||
"arcana.ability": { type: String, defaultValue: "intelligence" },
|
"arcana.ability": {type: String, defaultValue: "intelligence"},
|
||||||
|
|
||||||
athletics: {type: Schemas.Skill},
|
athletics: {type: Schemas.Skill},
|
||||||
"athletics.ability": { type: String, defaultValue: "strength" },
|
"athletics.ability": {type: String, defaultValue: "strength"},
|
||||||
|
|
||||||
deception: {type: Schemas.Skill},
|
deception: {type: Schemas.Skill},
|
||||||
"deception.ability": { type: String, defaultValue: "charisma" },
|
"deception.ability": {type: String, defaultValue: "charisma"},
|
||||||
|
|
||||||
history: {type: Schemas.Skill},
|
history: {type: Schemas.Skill},
|
||||||
"history.ability": { type: String, defaultValue: "intelligence" },
|
"history.ability": {type: String, defaultValue: "intelligence"},
|
||||||
|
|
||||||
insight: {type: Schemas.Skill},
|
insight: {type: Schemas.Skill},
|
||||||
"insight.ability": { type: String, defaultValue: "wisdom" },
|
"insight.ability": {type: String, defaultValue: "wisdom"},
|
||||||
|
|
||||||
intimidation: {type: Schemas.Skill},
|
intimidation: {type: Schemas.Skill},
|
||||||
"intimidation.ability": { type: String, defaultValue: "charisma" },
|
"intimidation.ability": {type: String, defaultValue: "charisma"},
|
||||||
|
|
||||||
investigation: {type: Schemas.Skill},
|
investigation: {type: Schemas.Skill},
|
||||||
"investigation.ability": { type: String, defaultValue: "intelligence" },
|
"investigation.ability": {type: String, defaultValue: "intelligence"},
|
||||||
|
|
||||||
medicine: {type: Schemas.Skill},
|
medicine: {type: Schemas.Skill},
|
||||||
"medicine.ability": { type: String, defaultValue: "wisdom" },
|
"medicine.ability": {type: String, defaultValue: "wisdom"},
|
||||||
|
|
||||||
nature: {type: Schemas.Skill},
|
nature: {type: Schemas.Skill},
|
||||||
"nature.ability": { type: String, defaultValue: "intelligence" },
|
"nature.ability": {type: String, defaultValue: "intelligence"},
|
||||||
|
|
||||||
perception: {type: Schemas.Skill},
|
perception: {type: Schemas.Skill},
|
||||||
"perception.ability": { type: String, defaultValue: "wisdom" },
|
"perception.ability": {type: String, defaultValue: "wisdom"},
|
||||||
|
|
||||||
performance: {type: Schemas.Skill},
|
performance: {type: Schemas.Skill},
|
||||||
"performance.ability": { type: String, defaultValue: "charisma" },
|
"performance.ability": {type: String, defaultValue: "charisma"},
|
||||||
|
|
||||||
persuasion: {type: Schemas.Skill},
|
persuasion: {type: Schemas.Skill},
|
||||||
"persuasion.ability": { type: String, defaultValue: "charisma" },
|
"persuasion.ability": {type: String, defaultValue: "charisma"},
|
||||||
|
|
||||||
religion: {type: Schemas.Skill},
|
religion: {type: Schemas.Skill},
|
||||||
"religion.ability": { type: String, defaultValue: "intelligence" },
|
"religion.ability": {type: String, defaultValue: "intelligence"},
|
||||||
|
|
||||||
sleightOfHand: {type: Schemas.Skill},
|
sleightOfHand: {type: Schemas.Skill},
|
||||||
"sleightOfHand.ability": { type: String, defaultValue: "dexterity" },
|
"sleightOfHand.ability": {type: String, defaultValue: "dexterity"},
|
||||||
|
|
||||||
stealth: {type: Schemas.Skill},
|
stealth: {type: Schemas.Skill},
|
||||||
"stealth.ability": { type: String, defaultValue: "dexterity" },
|
"stealth.ability": {type: String, defaultValue: "dexterity"},
|
||||||
|
|
||||||
survival: {type: Schemas.Skill},
|
survival: {type: Schemas.Skill},
|
||||||
"survival.ability": { type: String, defaultValue: "wisdom" },
|
"survival.ability": {type: String, defaultValue: "wisdom"},
|
||||||
|
|
||||||
|
|
||||||
//Mechanical Skills
|
//Mechanical Skills
|
||||||
initiative: {type: Schemas.Skill},
|
initiative: {type: Schemas.Skill},
|
||||||
"initiative.ability": { type: String, defaultValue: "dexterity" },
|
"initiative.ability": {type: String, defaultValue: "dexterity"},
|
||||||
|
|
||||||
dexterityArmor: {type: Schemas.Skill},
|
dexterityArmor: {type: Schemas.Skill},
|
||||||
"dexterityArmor.ability": { type: String, defaultValue: "dexterity" },
|
"dexterityArmor.ability": {type: String, defaultValue: "dexterity"},
|
||||||
|
|
||||||
//mechanics
|
//mechanics
|
||||||
deathSave: { type: Schemas.DeathSave },
|
deathSave: {type: Schemas.DeathSave},
|
||||||
|
|
||||||
//permissions
|
//permissions
|
||||||
owner: { type: String, regEx: SimpleSchema.RegEx.Id },
|
party: {type: String, regEx: SimpleSchema.RegEx.Id, optional: true},
|
||||||
readers: { type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: [] },
|
owner: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||||
writers: { type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: [] },
|
readers: {type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: []},
|
||||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"},
|
writers: {type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: []},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
|
},
|
||||||
//TODO add per-character settings
|
//TODO add per-character settings
|
||||||
"settings.experiencesInc": {type: Number, defaultValue: 20}, //how many experiences to load at a time in XP table
|
//how many experiences to load at a time in XP table
|
||||||
|
"settings.experiencesInc": {type: Number, defaultValue: 20},
|
||||||
|
//slowed down by carrying too much?
|
||||||
|
"settings.useVariantEncumbrance": {type: Boolean, defaultValue: false},
|
||||||
|
"settings.useStandardEncumbrance": {type: Boolean, defaultValue: true},
|
||||||
|
//hide spellcasting
|
||||||
|
"settings.hideSpellcasting": {type: Boolean, defaultValue: false},
|
||||||
});
|
});
|
||||||
|
|
||||||
Characters.attachSchema(Schemas.Character);
|
Characters.attachSchema(Schemas.Character);
|
||||||
|
|
||||||
var attributeBase = function(charId, statName){
|
var attributeBase = function(charId, statName){
|
||||||
check(statName, String);
|
check(statName, String);
|
||||||
var effects = Effects.find({charId: charId, stat: statName, enabled: true}).fetch();
|
//if it's a damage multiplier, we treat it specially
|
||||||
effects = _.groupBy(effects, "operation");
|
if (_.contains(DAMAGE_MULTIPLIERS, statName)){
|
||||||
var value = _.contains(DAMAGE_MULTIPLIERS, statName)? 1 : 0;
|
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){
|
||||||
|
return 0.5;
|
||||||
|
} else if (!resistCount && vulnCount){
|
||||||
|
return 2;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = 0;
|
||||||
|
|
||||||
//start with the highest base value
|
//start with the highest base value
|
||||||
_.each(effects.base, function(effect){
|
Effects.find(
|
||||||
var efv = evaluateEffect(charId, effect)
|
{charId: charId, stat: statName, enabled: true, operation: "base"}
|
||||||
|
).forEach(function(effect){
|
||||||
|
var efv = evaluateEffect(charId, effect);
|
||||||
if (efv > value){
|
if (efv > value){
|
||||||
value = efv;
|
value = efv;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//add all the add values
|
//add all the add values
|
||||||
_.each(effects.add, function(effect){
|
Effects.find(
|
||||||
|
{charId: charId, stat: statName, enabled: true, operation: "add"}
|
||||||
|
).forEach(function(effect){
|
||||||
value += evaluateEffect(charId, effect);
|
value += evaluateEffect(charId, effect);
|
||||||
});
|
});
|
||||||
|
|
||||||
//multiply all the mul values
|
//multiply all the mul values
|
||||||
_.each(effects.mul, function(effect){
|
Effects.find(
|
||||||
|
{charId: charId, stat: statName, enabled: true, operation: "mul"}
|
||||||
|
).forEach(function(effect){
|
||||||
value *= evaluateEffect(charId, effect);
|
value *= evaluateEffect(charId, effect);
|
||||||
});
|
});
|
||||||
|
|
||||||
//ensure value is >= all mins
|
//ensure value is >= all mins
|
||||||
_.each(effects.min, function(effect){
|
Effects.find(
|
||||||
|
{charId: charId, stat: statName, enabled: true, operation: "min"}
|
||||||
|
).forEach(function(effect){
|
||||||
var min = evaluateEffect(charId, effect);
|
var min = evaluateEffect(charId, effect);
|
||||||
value = value > min? value : min;
|
value = value > min ? value : min;
|
||||||
});
|
});
|
||||||
|
|
||||||
//ensure value is <= all maxes
|
//ensure value is <= all maxes
|
||||||
_.each(effects.max, function(effect){
|
Effects.find(
|
||||||
|
{charId: charId, stat: statName, enabled: true, operation: "max"}
|
||||||
|
).forEach(function(effect){
|
||||||
var max = evaluateEffect(charId, effect);
|
var max = evaluateEffect(charId, effect);
|
||||||
value = value < max? value : max;
|
value = value < max ? value : max;
|
||||||
});
|
});
|
||||||
return value;
|
return value;
|
||||||
}
|
};
|
||||||
|
|
||||||
//functions and calculated values.
|
//functions and calculated values.
|
||||||
//These functions can only rely on this._id since no other
|
//These functions can only rely on this._id since no other
|
||||||
@@ -223,16 +270,24 @@ Characters.helpers({
|
|||||||
fieldSelector[fieldName] = 1;
|
fieldSelector[fieldName] = 1;
|
||||||
var char = Characters.findOne(this._id, {fields: fieldSelector});
|
var char = Characters.findOne(this._id, {fields: fieldSelector});
|
||||||
var field = char[fieldName];
|
var field = char[fieldName];
|
||||||
if(field === undefined){
|
if (field === undefined){
|
||||||
throw new Meteor.Error("getField failed",
|
throw new Meteor.Error(
|
||||||
"getField could not find field " + fieldName + " in character "+ char._id);
|
"getField failed",
|
||||||
|
"getField could not find field " +
|
||||||
|
fieldName +
|
||||||
|
" in character " +
|
||||||
|
char._id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return field;
|
return field;
|
||||||
},
|
},
|
||||||
//returns the value of a field
|
//returns the value of a field
|
||||||
fieldValue : function(fieldName){
|
fieldValue : function(fieldName){
|
||||||
if(!Schemas.Character.schema(fieldName)){
|
if (!Schemas.Character.schema(fieldName)){
|
||||||
throw new Meteor.Error("Field not found", "Character's schema does not contain a field called: " + fieldName);
|
throw new Meteor.Error(
|
||||||
|
"Field not found",
|
||||||
|
"Character's schema does not contain a field called: " + fieldName
|
||||||
|
);
|
||||||
}
|
}
|
||||||
//duck typing to get the right value function
|
//duck typing to get the right value function
|
||||||
//.ability implies skill
|
//.ability implies skill
|
||||||
@@ -270,7 +325,7 @@ Characters.helpers({
|
|||||||
var ability = this.attributeValue(skill.ability);
|
var ability = this.attributeValue(skill.ability);
|
||||||
|
|
||||||
//base modifier
|
//base modifier
|
||||||
var mod = +getMod(ability)
|
var mod = +getMod(ability);
|
||||||
|
|
||||||
//multiply proficiency bonus by largest value in proficiency array
|
//multiply proficiency bonus by largest value in proficiency array
|
||||||
var prof = this.proficiency(skillName);
|
var prof = this.proficiency(skillName);
|
||||||
@@ -279,7 +334,9 @@ Characters.helpers({
|
|||||||
mod += prof * this.attributeValue("proficiencyBonus");
|
mod += prof * this.attributeValue("proficiencyBonus");
|
||||||
|
|
||||||
//apply all effects
|
//apply all effects
|
||||||
var rawEffects = Effects.find({charId: charId, stat: skillName, enabled: true}).fetch();
|
var rawEffects = Effects.find(
|
||||||
|
{charId: charId, stat: skillName, enabled: true}
|
||||||
|
).fetch();
|
||||||
var effects = _.groupBy(rawEffects, "operation");
|
var effects = _.groupBy(rawEffects, "operation");
|
||||||
_.forEach(effects.add, function(effect){
|
_.forEach(effects.add, function(effect){
|
||||||
mod += evaluateEffect(charId, effect);
|
mod += evaluateEffect(charId, effect);
|
||||||
@@ -289,11 +346,11 @@ Characters.helpers({
|
|||||||
});
|
});
|
||||||
_.forEach(effects.min, function(effect){
|
_.forEach(effects.min, function(effect){
|
||||||
var min = evaluateEffect(charId, effect);
|
var min = evaluateEffect(charId, effect);
|
||||||
mod = mod > min? mod : min;
|
mod = mod > min ? mod : min;
|
||||||
});
|
});
|
||||||
_.forEach(effects.max, function(effect){
|
_.forEach(effects.max, function(effect){
|
||||||
var max = evaluateEffect(charId, effect);
|
var max = evaluateEffect(charId, effect);
|
||||||
mod = mod < max? mod : max;
|
mod = mod < max ? mod : max;
|
||||||
});
|
});
|
||||||
return signedString(mod);
|
return signedString(mod);
|
||||||
}),
|
}),
|
||||||
@@ -302,12 +359,12 @@ Characters.helpers({
|
|||||||
var charId = this._id;
|
var charId = this._id;
|
||||||
//return largest value in proficiency array
|
//return largest value in proficiency array
|
||||||
var prof = 0;
|
var prof = 0;
|
||||||
Effects.find({charId: charId, stat: skillName, enabled: true}).forEach(function(effect){
|
Proficiencies.find(
|
||||||
if(effect.operation === "proficiency"){
|
{charId: charId, name: skillName, enabled: true}
|
||||||
var newProf = evaluateEffect(charId, effect);
|
).forEach(function(proficiency){
|
||||||
if (newProf > prof){
|
var newProf = proficiency.value;
|
||||||
prof = newProf;
|
if (newProf > prof){
|
||||||
}
|
prof = newProf;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return prof;
|
return prof;
|
||||||
@@ -317,10 +374,12 @@ Characters.helpers({
|
|||||||
if (_.isString(skillName)){
|
if (_.isString(skillName)){
|
||||||
var skill = this.getField(skillName);
|
var skill = this.getField(skillName);
|
||||||
}
|
}
|
||||||
var charId = this._id
|
var charId = this._id;
|
||||||
var mod = +this.skillMod(skillName);
|
var mod = +this.skillMod(skillName);
|
||||||
var value = 10 + mod;
|
var value = 10 + mod;
|
||||||
Effects.find({charId: charId, stat: skillName, enabled: true, operation: "passiveAdd"}).forEach(function(effect){
|
Effects.find(
|
||||||
|
{charId: charId, stat: skillName, enabled: true, operation: "passiveAdd"}
|
||||||
|
).forEach(function(effect){
|
||||||
value += evaluateEffect(charId, effect);
|
value += evaluateEffect(charId, effect);
|
||||||
});
|
});
|
||||||
return value;
|
return value;
|
||||||
@@ -328,11 +387,15 @@ Characters.helpers({
|
|||||||
},
|
},
|
||||||
|
|
||||||
advantage: function(skillName){
|
advantage: function(skillName){
|
||||||
var charId = this._id
|
var charId = this._id;
|
||||||
var advantage = Effects.find({charId: charId, stat: skillName, enabled: true, operation: "advantage"}).count();
|
var advantage = Effects.find(
|
||||||
var disadvantage = Effects.find({charId: charId, stat: skillName, enabled: true, operation: "disadvantage"}).count();
|
{charId: charId, stat: skillName, enabled: true, operation: "advantage"}
|
||||||
if(advantage && !disadvantage) return 1;
|
).count();
|
||||||
if(disadvantage && !advantage) return -1;
|
var disadvantage = Effects.find(
|
||||||
|
{charId: charId, stat: skillName, enabled: true, operation: "disadvantage"}
|
||||||
|
).count();
|
||||||
|
if (advantage && !disadvantage) return 1;
|
||||||
|
if (disadvantage && !advantage) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -347,15 +410,12 @@ Characters.helpers({
|
|||||||
|
|
||||||
xpLevel: function(){
|
xpLevel: function(){
|
||||||
var xp = this.experience();
|
var xp = this.experience();
|
||||||
var xpTable = [0, 300, 900, 2700, 6500, 14000, 23000, 34000, 48000, 64000,
|
for (var i = 0; i < 19; i++){
|
||||||
85000, 100000, 120000, 140000, 165000, 195000, 225000, 265000,
|
if (xp < XP_TABLE[i]){
|
||||||
305000, 355000];
|
|
||||||
for(var i = 0; i < 19; i++){
|
|
||||||
if(xp < xpTable[i]){
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
if(xp > 355000) return 20;
|
if (xp > 355000) return 20;
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -363,22 +423,25 @@ Characters.helpers({
|
|||||||
var level = 0;
|
var level = 0;
|
||||||
Classes.find({charId: this._id}).forEach(function(cls){
|
Classes.find({charId: this._id}).forEach(function(cls){
|
||||||
level += cls.level;
|
level += cls.level;
|
||||||
})
|
});
|
||||||
return level;
|
return level;
|
||||||
},
|
},
|
||||||
|
|
||||||
experience: function(){
|
experience: function(){
|
||||||
var xp = 0;
|
var xp = 0;
|
||||||
Experiences.find({charId: this._id}, {fields: {value: 1}}).forEach(function(e){
|
Experiences.find(
|
||||||
|
{charId: this._id},
|
||||||
|
{fields: {value: 1}}
|
||||||
|
).forEach(function(e){
|
||||||
xp += e.value;
|
xp += e.value;
|
||||||
})
|
});
|
||||||
return xp;
|
return xp;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//clean up all data related to that character before removing it
|
//clean up all data related to that character before removing it
|
||||||
Characters.after.remove(function (userId, character) {
|
Characters.after.remove(function(userId, character) {
|
||||||
if(Meteor.isServer){
|
if (Meteor.isServer){
|
||||||
Actions .remove({charId: character._id});
|
Actions .remove({charId: character._id});
|
||||||
Attacks .remove({charId: character._id});
|
Attacks .remove({charId: character._id});
|
||||||
Buffs .remove({charId: character._id});
|
Buffs .remove({charId: character._id});
|
||||||
@@ -395,25 +458,25 @@ Characters.after.remove(function (userId, character) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Characters.allow({
|
Characters.allow({
|
||||||
insert: function (userId, doc) {
|
insert: function(userId, doc) {
|
||||||
// the user must be logged in, and the document must be owned by the user
|
// the user must be logged in, and the document must be owned by the user
|
||||||
return (userId && doc.owner === userId);
|
return (userId && doc.owner === userId);
|
||||||
},
|
},
|
||||||
update: function (userId, doc, fields, modifier) {
|
update: function(userId, doc, fields, modifier) {
|
||||||
// can only change documents you have write access to
|
// can only change documents you have write access to
|
||||||
return doc.owner === userId ||
|
return doc.owner === userId ||
|
||||||
_.contains(doc.writers, userId);
|
_.contains(doc.writers, userId);
|
||||||
},
|
},
|
||||||
remove: function (userId, doc) {
|
remove: function(userId, doc) {
|
||||||
// can only remove your own documents
|
// can only remove your own documents
|
||||||
return doc.owner === userId;
|
return doc.owner === userId;
|
||||||
},
|
},
|
||||||
fetch: ["owner", "writers"]
|
fetch: ["owner", "writers"],
|
||||||
});
|
});
|
||||||
|
|
||||||
Characters.deny({
|
Characters.deny({
|
||||||
update: function (userId, docs, fields, modifier) {
|
update: function(userId, docs, fields, modifier) {
|
||||||
// can't change owners
|
// can't change owners
|
||||||
return _.contains(fields, 'owner');
|
return _.contains(fields, "owner");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,21 +8,25 @@ Schemas.Class = new SimpleSchema({
|
|||||||
type: Date,
|
type: Date,
|
||||||
autoValue: function() {
|
autoValue: function() {
|
||||||
if (this.isInsert) {
|
if (this.isInsert) {
|
||||||
return new Date;
|
return new Date();
|
||||||
} else if (this.isUpsert) {
|
} else if (this.isUpsert) {
|
||||||
return {$setOnInsert: new Date};
|
return {$setOnInsert: new Date()};
|
||||||
} else {
|
} else {
|
||||||
this.unset();
|
this.unset();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
},
|
},
|
||||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Classes.attachSchema(Schemas.Class);
|
Classes.attachSchema(Schemas.Class);
|
||||||
|
|
||||||
Classes.attachBehaviour('softRemovable');
|
Classes.attachBehaviour("softRemovable");
|
||||||
makeParent(Classes, 'name'); //parents of effects and attacks
|
makeParent(Classes, "name"); //parents of effects and attacks
|
||||||
|
|
||||||
Classes.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Classes.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Classes.deny(CHARACTER_SUBSCHEMA_DENY);
|
Classes.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -7,33 +7,39 @@ Effects = new Mongo.Collection("effects");
|
|||||||
Schemas.Effect = new SimpleSchema({
|
Schemas.Effect = new SimpleSchema({
|
||||||
charId: {
|
charId: {
|
||||||
type: String,
|
type: String,
|
||||||
regEx: SimpleSchema.RegEx.Id
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true, //TODO make necessary if there is no owner
|
optional: true, //TODO make necessary if there is no owner
|
||||||
trim: false
|
trim: false,
|
||||||
},
|
},
|
||||||
operation: {
|
operation: {
|
||||||
type: String,
|
type: String,
|
||||||
defaultValue: "add",
|
defaultValue: "add",
|
||||||
allowedValues: ["base", "proficiency","add","mul","min","max","advantage","disadvantage","passiveAdd","fail","conditional"]
|
allowedValues: [
|
||||||
|
"base",
|
||||||
|
"proficiency",
|
||||||
|
"add",
|
||||||
|
"mul",
|
||||||
|
"min",
|
||||||
|
"max",
|
||||||
|
"advantage",
|
||||||
|
"disadvantage",
|
||||||
|
"passiveAdd",
|
||||||
|
"fail",
|
||||||
|
"conditional",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: Number,
|
type: Number,
|
||||||
decimal: true,
|
decimal: true,
|
||||||
optional: true
|
optional: true,
|
||||||
},
|
},
|
||||||
calculation: {
|
calculation: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true,
|
optional: true,
|
||||||
trim: false
|
trim: false,
|
||||||
},
|
|
||||||
//indicates what the effect originated from
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
defaultValue: "editable",
|
|
||||||
allowedValues: ["editable", "feature", "class", "buff", "equipment", "racial", "inate"]
|
|
||||||
},
|
},
|
||||||
//the thing that created this effect
|
//the thing that created this effect
|
||||||
parent: {
|
parent: {
|
||||||
@@ -42,69 +48,69 @@ Schemas.Effect = new SimpleSchema({
|
|||||||
//which stat the effect is applied to
|
//which stat the effect is applied to
|
||||||
stat: {
|
stat: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true
|
optional: true,
|
||||||
},
|
},
|
||||||
enabled: {
|
enabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
defaultValue: true
|
defaultValue: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Effects.attachSchema(Schemas.Effect);
|
Effects.attachSchema(Schemas.Effect);
|
||||||
|
|
||||||
if(Meteor.isServer) Characters.after.insert(function (userId, char) {
|
if (Meteor.isServer) Characters.after.insert(function(userId, char) {
|
||||||
Effects.insert({
|
Effects.insert({
|
||||||
charId: char._id,
|
charId: char._id,
|
||||||
type: "inate",
|
|
||||||
name: "Constitution modifier for each level",
|
name: "Constitution modifier for each level",
|
||||||
stat: "hitPoints",
|
stat: "hitPoints",
|
||||||
operation: "add",
|
operation: "add",
|
||||||
calculation: "level * constitutionMod",
|
calculation: "level * constitutionMod",
|
||||||
parent: {
|
parent: {
|
||||||
id: char._id,
|
id: char._id,
|
||||||
collection: "Characters"
|
collection: "Characters",
|
||||||
}
|
group: "Inate",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
Effects.insert({
|
Effects.insert({
|
||||||
charId: char._id,
|
charId: char._id,
|
||||||
type: "inate",
|
|
||||||
name: "Proficiency bonus by level",
|
name: "Proficiency bonus by level",
|
||||||
stat: "proficiencyBonus",
|
stat: "proficiencyBonus",
|
||||||
operation: "add",
|
operation: "add",
|
||||||
calculation: "floor(level / 4 + 1.75)",
|
calculation: "floor(level / 4 + 1.75)",
|
||||||
parent: {
|
parent: {
|
||||||
id: char._id,
|
id: char._id,
|
||||||
collection: "Characters"
|
collection: "Characters",
|
||||||
}
|
group: "Inate",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
Effects.insert({
|
Effects.insert({
|
||||||
charId: char._id,
|
charId: char._id,
|
||||||
type: "inate",
|
|
||||||
name: "Dexterity Armor Bonus",
|
name: "Dexterity Armor Bonus",
|
||||||
stat: "armor",
|
stat: "armor",
|
||||||
operation: "add",
|
operation: "add",
|
||||||
calculation: "dexterityArmor",
|
calculation: "dexterityArmor",
|
||||||
parent: {
|
parent: {
|
||||||
id: char._id,
|
id: char._id,
|
||||||
collection: "Characters"
|
collection: "Characters",
|
||||||
}
|
group: "Inate",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
Effects.insert({
|
Effects.insert({
|
||||||
charId: char._id,
|
charId: char._id,
|
||||||
type: "inate",
|
|
||||||
name: "Natural Armor",
|
name: "Natural Armor",
|
||||||
stat: "armor",
|
stat: "armor",
|
||||||
operation: "base",
|
operation: "base",
|
||||||
value: 10,
|
value: 10,
|
||||||
parent: {
|
parent: {
|
||||||
id: char._id,
|
id: char._id,
|
||||||
collection: "Characters"
|
collection: "Characters",
|
||||||
}
|
group: "Inate",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Effects.attachBehaviour('softRemovable');
|
Effects.attachBehaviour("softRemovable");
|
||||||
makeChild(Effects, ['name', 'enabled']); //children of lots of things
|
makeChild(Effects, ["enabled"]); //children of lots of things
|
||||||
|
|
||||||
Effects.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Effects.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Effects.deny(CHARACTER_SUBSCHEMA_DENY);
|
Effects.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -9,19 +9,19 @@ Schemas.Experience = new SimpleSchema({
|
|||||||
type: Date,
|
type: Date,
|
||||||
autoValue: function() {
|
autoValue: function() {
|
||||||
if (this.isInsert) {
|
if (this.isInsert) {
|
||||||
return new Date;
|
return new Date();
|
||||||
} else if (this.isUpsert) {
|
} else if (this.isUpsert) {
|
||||||
return {$setOnInsert: new Date};
|
return {$setOnInsert: new Date()};
|
||||||
} else {
|
} else {
|
||||||
this.unset();
|
this.unset();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Experiences.attachSchema(Schemas.Experience);
|
Experiences.attachSchema(Schemas.Experience);
|
||||||
|
|
||||||
Experiences.attachBehaviour('softRemovable');
|
Experiences.attachBehaviour("softRemovable");
|
||||||
|
|
||||||
Experiences.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Experiences.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Experiences.deny(CHARACTER_SUBSCHEMA_DENY);
|
Experiences.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -6,10 +6,17 @@ Schemas.Feature = new SimpleSchema({
|
|||||||
description: {type: String, optional: true, trim: false},
|
description: {type: String, optional: true, trim: false},
|
||||||
uses: {type: String, optional: true, trim: false},
|
uses: {type: String, optional: true, trim: false},
|
||||||
used: {type: Number, defaultValue: 0},
|
used: {type: Number, defaultValue: 0},
|
||||||
reset: {type: String, allowedValues: ["manual", "longRest", "shortRest"], defaultValue: "manual"},
|
reset: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: ["manual", "longRest", "shortRest"],
|
||||||
|
defaultValue: "manual",
|
||||||
|
},
|
||||||
enabled: {type: Boolean, defaultValue: true},
|
enabled: {type: Boolean, defaultValue: true},
|
||||||
alwaysEnabled:{type: Boolean, defaultValue: true},
|
alwaysEnabled:{type: Boolean, defaultValue: true},
|
||||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"}
|
color: {type: String,
|
||||||
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Features.attachSchema(Schemas.Feature);
|
Features.attachSchema(Schemas.Feature);
|
||||||
@@ -20,11 +27,11 @@ Features.helpers({
|
|||||||
},
|
},
|
||||||
usesValue: function(){
|
usesValue: function(){
|
||||||
return evaluate(this.charId, this.uses);
|
return evaluate(this.charId, this.uses);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Features.attachBehaviour('softRemovable');
|
Features.attachBehaviour("softRemovable");
|
||||||
makeParent(Features, ['name', 'enabled']); //parents of effects and attacks
|
makeParent(Features, ["name", "enabled"]); //parents of effects and attacks
|
||||||
|
|
||||||
Features.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Features.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Features.deny(CHARACTER_SUBSCHEMA_DENY);
|
Features.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ Schemas.Note = new SimpleSchema({
|
|||||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||||
name: {type: String, trim: false},
|
name: {type: String, trim: false},
|
||||||
description: {type: String, optional: true, trim: false},
|
description: {type: String, optional: true, trim: false},
|
||||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"}
|
color: {
|
||||||
|
type: String,
|
||||||
|
allowedValues:_.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Notes.attachSchema(Schemas.Note);
|
Notes.attachSchema(Schemas.Note);
|
||||||
|
|
||||||
Notes.attachBehaviour('softRemovable');
|
Notes.attachBehaviour("softRemovable");
|
||||||
|
|
||||||
Notes.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Notes.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Notes.deny(CHARACTER_SUBSCHEMA_DENY);
|
Notes.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -2,25 +2,35 @@ Proficiencies = new Mongo.Collection("proficiencies");
|
|||||||
|
|
||||||
Schemas.Proficiency = new SimpleSchema({
|
Schemas.Proficiency = new SimpleSchema({
|
||||||
charId: {
|
charId: {
|
||||||
type: String,
|
|
||||||
regEx: SimpleSchema.RegEx.Id
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
type: String,
|
||||||
trim: false
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
trim: false,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Number,
|
||||||
|
allowedValues: [0, 0.5, 1, 2],
|
||||||
|
defaultValue: 1,
|
||||||
|
decimal: true,
|
||||||
},
|
},
|
||||||
//indicates what type of thing proficiency originated from
|
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
defaultValue: "editable",
|
allowedValues: ["skill", "save", "weapon", "armor", "tool", "language"],
|
||||||
allowedValues: ["editable", "feature", "buff", "equipment", "inate"]
|
defaultValue: "skill",
|
||||||
|
},
|
||||||
|
enabled: {
|
||||||
|
type: Boolean,
|
||||||
|
defaultValue: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Proficiencies.attachSchema(Schemas.Proficiency);
|
Proficiencies.attachSchema(Schemas.Proficiency);
|
||||||
|
|
||||||
Proficiencies.attachBehaviour('softRemovable');
|
Proficiencies.attachBehaviour("softRemovable");
|
||||||
makeChild(Proficiencies);
|
makeChild(Proficiencies);
|
||||||
|
|
||||||
Proficiencies.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Proficiencies.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
Proficiencies.deny(CHARACTER_SUBSCHEMA_DENY);
|
Proficiencies.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ Schemas.SpellLists = new SimpleSchema({
|
|||||||
saveDC: {type: String, optional: true, trim: false},
|
saveDC: {type: String, optional: true, trim: false},
|
||||||
attackBonus: {type: String, optional: true, trim: false},
|
attackBonus: {type: String, optional: true, trim: false},
|
||||||
maxPrepared: {type: String, optional: true, trim: false},
|
maxPrepared: {type: String, optional: true, trim: false},
|
||||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"},
|
color: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
|
},
|
||||||
"settings.showUnprepared": {type: Boolean, defaultValue: true},
|
"settings.showUnprepared": {type: Boolean, defaultValue: true},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -16,14 +20,17 @@ SpellLists.attachSchema(Schemas.SpellLists);
|
|||||||
SpellLists.helpers({
|
SpellLists.helpers({
|
||||||
numPrepared: function(){
|
numPrepared: function(){
|
||||||
var num = 0;
|
var num = 0;
|
||||||
Spells.find({charId: this.charId, listId: this._id, prepared: 1}, {fields: {prepareCost: 1}}).forEach(function(spell){
|
Spells.find(
|
||||||
|
{charId: this.charId, listId: this._id, prepared: 1},
|
||||||
|
{fields: {prepareCost: 1}}
|
||||||
|
).forEach(function(spell){
|
||||||
num += spell.prepareCost;
|
num += spell.prepareCost;
|
||||||
});
|
});
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
SpellLists.attachBehaviour('softRemovable');
|
SpellLists.attachBehaviour("softRemovable");
|
||||||
makeParent(SpellLists); //parents of spells
|
makeParent(SpellLists); //parents of spells
|
||||||
|
|
||||||
SpellLists.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
SpellLists.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
|
|||||||
@@ -2,25 +2,65 @@ Spells = new Mongo.Collection("spells");
|
|||||||
|
|
||||||
Schemas.Spell = new SimpleSchema({
|
Schemas.Spell = new SimpleSchema({
|
||||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||||
prepared: {type: String, defaultValue: "prepared", allowedValues: ["prepared","unprepared","always"]},
|
prepared: {
|
||||||
name: {type: String, trim: false, defaultValue: "New Spell"},
|
type: String,
|
||||||
description: {type: String, optional: true, trim: false},
|
defaultValue: "prepared",
|
||||||
castingTime: {type: String, optional: true, defaultValue: "action", trim: false},
|
allowedValues: ["prepared", "unprepared", "always"],
|
||||||
range: {type: String, optional: true, trim: false},
|
},
|
||||||
duration: {type: String, optional: true, trim: false, defaultValue: "Instantaneous"},
|
name: {
|
||||||
"components.verbal": {type: Boolean, defaultValue: false},
|
type: String,
|
||||||
"components.somatic": {type: Boolean, defaultValue: false},
|
trim: false,
|
||||||
"components.material": {type: String, optional: true},
|
defaultValue: "New Spell",
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
trim: false,
|
||||||
|
},
|
||||||
|
castingTime: {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
defaultValue: "action",
|
||||||
|
trim: false,
|
||||||
|
},
|
||||||
|
range: {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
trim: false,
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
trim: false,
|
||||||
|
defaultValue: "Instantaneous",
|
||||||
|
},
|
||||||
|
"components.verbal": {type: Boolean, defaultValue: false},
|
||||||
|
"components.somatic": {type: Boolean, defaultValue: false},
|
||||||
"components.concentration": {type: Boolean, defaultValue: false},
|
"components.concentration": {type: Boolean, defaultValue: false},
|
||||||
ritual: {type: Boolean, defaultValue: false},
|
"components.material": {type: String, optional: true},
|
||||||
level: {type: Number, defaultValue: 1},
|
ritual: {
|
||||||
school: {type: String, defaultValue: "Abjuration", allowedValues: magicSchools},
|
type: Boolean,
|
||||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"}
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
level: {
|
||||||
|
type: Number,
|
||||||
|
defaultValue: 1,
|
||||||
|
},
|
||||||
|
school: {
|
||||||
|
type: String,
|
||||||
|
defaultValue: "Abjuration",
|
||||||
|
allowedValues: magicSchools,
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Spells.attachSchema(Schemas.Spell);
|
Spells.attachSchema(Schemas.Spell);
|
||||||
|
|
||||||
Spells.attachBehaviour('softRemovable');
|
Spells.attachBehaviour("softRemovable");
|
||||||
makeChild(Spells); //children of spell lists
|
makeChild(Spells); //children of spell lists
|
||||||
|
|
||||||
Spells.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Spells.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
|
|||||||
@@ -5,21 +5,21 @@
|
|||||||
Schemas.Adjustment = new SimpleSchema({
|
Schemas.Adjustment = new SimpleSchema({
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true
|
optional: true,
|
||||||
},
|
},
|
||||||
//which stat the adjustment is applied to
|
//which stat the adjustment is applied to
|
||||||
stat: {
|
stat: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true
|
optional: true,
|
||||||
},
|
},
|
||||||
//the value added to the stat
|
//the value added to the stat
|
||||||
value: {
|
value: {
|
||||||
type: Number,
|
type: Number,
|
||||||
decimal: true,
|
decimal: true,
|
||||||
optional: true
|
optional: true,
|
||||||
},
|
},
|
||||||
calculation: {
|
calculation: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true
|
optional: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ Schemas.Attribute = new SimpleSchema({
|
|||||||
//should be zero after reset
|
//should be zero after reset
|
||||||
adjustment: {
|
adjustment: {
|
||||||
type: Number,
|
type: Number,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
},
|
},
|
||||||
reset: {
|
reset: {
|
||||||
type: String,
|
type: String,
|
||||||
defaultValue: "longRest",
|
defaultValue: "longRest",
|
||||||
allowedValues: ["longRest", "shortRest"]
|
allowedValues: ["longRest", "shortRest"],
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,20 +3,20 @@ Schemas.DeathSave = new SimpleSchema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 3,
|
max: 3,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
},
|
},
|
||||||
fail: {
|
fail: {
|
||||||
type: Number,
|
type: Number,
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 3,
|
max: 3,
|
||||||
defaultValue: 0
|
defaultValue: 0,
|
||||||
},
|
},
|
||||||
canDeathSave: {
|
canDeathSave: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
defaultValue: true
|
defaultValue: true,
|
||||||
},
|
},
|
||||||
stable: {
|
stable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
defaultValue: false
|
defaultValue: false,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Schemas.Skill = new SimpleSchema({
|
Schemas.Skill = new SimpleSchema({
|
||||||
//attribute name that this skill used as base mod for roll
|
//attribute name that this skill used as base mod for roll
|
||||||
ability: { type: String, defaultValue: "" },
|
ability: {type: String, defaultValue: ""},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Schemas.TemporaryHitPoints = new SimpleSchema({
|
|||||||
} else {
|
} else {
|
||||||
this.unset();
|
this.unset();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -29,11 +29,13 @@ TemporaryHitPoints.helpers({
|
|||||||
});
|
});
|
||||||
|
|
||||||
//remove the temporary hit points when they hit zero
|
//remove the temporary hit points when they hit zero
|
||||||
TemporaryHitPoints.after.update(function (userId, thp, fieldNames, modifier, options) {
|
TemporaryHitPoints.after.update(
|
||||||
if(thp.used >= thp.maximum && thp.deleteOnZero){
|
function(userId, thp, fieldNames, modifier, options){
|
||||||
TemporaryHitPoints.remove(thp._id);
|
if (thp.used >= thp.maximum && thp.deleteOnZero){
|
||||||
}
|
TemporaryHitPoints.remove(thp._id);
|
||||||
}, {fetchPrevious: false});
|
}
|
||||||
|
}, {fetchPrevious: false}
|
||||||
|
);
|
||||||
|
|
||||||
TemporaryHitPoints.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
TemporaryHitPoints.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
TemporaryHitPoints.deny(CHARACTER_SUBSCHEMA_DENY);
|
TemporaryHitPoints.deny(CHARACTER_SUBSCHEMA_DENY);
|
||||||
|
|||||||
@@ -2,39 +2,55 @@
|
|||||||
Containers = new Mongo.Collection("containers");
|
Containers = new Mongo.Collection("containers");
|
||||||
|
|
||||||
Schemas.Container = new SimpleSchema({
|
Schemas.Container = new SimpleSchema({
|
||||||
name: { type: String, trim: false },
|
name: {type: String, trim: false},
|
||||||
charId: { type: String, regEx: SimpleSchema.RegEx.Id},
|
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||||
isCarried: { type: Boolean },
|
isCarried: {type: Boolean},
|
||||||
weight: {type: Number, min: 0, defaultValue: 0, decimal: true},
|
weight: {type: Number, min: 0, defaultValue: 0, decimal: true},
|
||||||
value: {type: Number, min: 0, defaultValue: 0, decimal: true},
|
value: {type: Number, min: 0, defaultValue: 0, decimal: true},
|
||||||
description:{type: String, optional: true, trim: false},
|
description:{type: String, optional: true, trim: false},
|
||||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"}
|
color: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Containers.attachSchema(Schemas.Container);
|
Containers.attachSchema(Schemas.Container);
|
||||||
|
|
||||||
Containers.helpers({
|
Containers.helpers({
|
||||||
totalValue: function(){
|
contentsValue: function(){
|
||||||
var value = this.value;
|
var value = 0;
|
||||||
Items.find({"parent.id": this._id}, {fields: {quantity: 1, value: 1}}).forEach(function(item){
|
Items.find(
|
||||||
|
{"parent.id": this._id},
|
||||||
|
{fields: {quantity: 1, value: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
value += item.totalValue();
|
value += item.totalValue();
|
||||||
});
|
});
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
totalWeight: function(){
|
totalValue: function(){
|
||||||
var weight = this.weight;
|
return this.contentsValue() + this.value;
|
||||||
Items.find({"parent.id": this._id}, {fields: {quantity: 1, weight: 1}}).forEach(function(item){
|
},
|
||||||
|
contentsWeight: function(){
|
||||||
|
var weight = 0;
|
||||||
|
Items.find(
|
||||||
|
{"parent.id": this._id},
|
||||||
|
{fields: {quantity: 1, weight: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
weight += item.totalWeight();
|
weight += item.totalWeight();
|
||||||
});
|
});
|
||||||
return weight;
|
return weight;
|
||||||
},
|
},
|
||||||
|
totalWeight: function(){
|
||||||
|
return this.contentsWeight() + this.weight;
|
||||||
|
},
|
||||||
moveToCharacter: function(characterId){
|
moveToCharacter: function(characterId){
|
||||||
if(this.charId === characterId) return;
|
if (this.charId === characterId) return;
|
||||||
Items.update(this._id, {$set: {charId: characterId}});
|
Items.update(this._id, {$set: {charId: characterId}});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Containers.attachBehaviour('softRemovable');
|
Containers.attachBehaviour("softRemovable");
|
||||||
makeParent(Containers); //parents of items
|
makeParent(Containers); //parents of items
|
||||||
|
|
||||||
Containers.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Containers.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Items = new Mongo.Collection('items');
|
Items = new Mongo.Collection("items");
|
||||||
|
|
||||||
Schemas.Item = new SimpleSchema({
|
Schemas.Item = new SimpleSchema({
|
||||||
name: {type: String, defaultValue: "New Item", trim: false},
|
name: {type: String, defaultValue: "New Item", trim: false},
|
||||||
@@ -10,11 +10,166 @@ Schemas.Item = new SimpleSchema({
|
|||||||
value: {type: Number, min: 0, defaultValue: 0, decimal: true},
|
value: {type: Number, min: 0, defaultValue: 0, decimal: true},
|
||||||
enabled: {type: Boolean, defaultValue: false},
|
enabled: {type: Boolean, defaultValue: false},
|
||||||
requiresAttunement: {type: Boolean, defaultValue: false},
|
requiresAttunement: {type: Boolean, defaultValue: false},
|
||||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"}
|
"settings.showIncrement": {type: Boolean, defaultValue: false},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: _.pluck(colorOptions, "key"),
|
||||||
|
defaultValue: "q",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Items.attachSchema(Schemas.Item);
|
Items.attachSchema(Schemas.Item);
|
||||||
|
|
||||||
|
var checkMovePermission = function(itemId, parent) {
|
||||||
|
var item = Items.findOne(itemId);
|
||||||
|
if (!item)
|
||||||
|
throw new Meteor.Error("No such item",
|
||||||
|
"An item could not be found to move");
|
||||||
|
//handle permissions
|
||||||
|
var permission = Meteor.call("canWriteCharacter", item.charId);
|
||||||
|
if (!permission){
|
||||||
|
throw new Meteor.Error("Access denied",
|
||||||
|
"Not permitted to move items from this character");
|
||||||
|
}
|
||||||
|
if (parent.collection === "Characters"){
|
||||||
|
permission = Meteor.call("canWriteCharacter", parent.id);
|
||||||
|
if (!permission){
|
||||||
|
throw new Meteor.Error("Access denied",
|
||||||
|
"Not permitted to move items to this character");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var parentCollectionObject = global[parent.collection];
|
||||||
|
var parentObject = null;
|
||||||
|
if (parentCollectionObject)
|
||||||
|
parentObject = parentCollectionObject.findOne(
|
||||||
|
parent.id, {fields: {_id: 1, charId: 1}}
|
||||||
|
);
|
||||||
|
if (!parentObject) throw new Meteor.Error(
|
||||||
|
"Invalid parent",
|
||||||
|
"The destination parent " + parent.id +
|
||||||
|
" does not exist in the collection " + parent.collection
|
||||||
|
);
|
||||||
|
if (parentObject.charId){
|
||||||
|
permission = Meteor.call("canWriteCharacter", parentObject.charId);
|
||||||
|
if (!permission){
|
||||||
|
throw new Meteor.Error("Access denied",
|
||||||
|
"Not permitted to move items to this character");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var moveItem = function(itemId, enable, parentCollection, parentId) {
|
||||||
|
var item = Items.findOne(itemId);
|
||||||
|
if (!item) return;
|
||||||
|
parentCollection = parentCollection || item.parent.collection;
|
||||||
|
parentId = parentId || item.parent.id;
|
||||||
|
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
checkMovePermission(itemId, {collection: parentCollection, id: parentId});
|
||||||
|
}
|
||||||
|
|
||||||
|
//update the item provided the update will actually change something
|
||||||
|
if (
|
||||||
|
item.parent.collection !== parentCollection ||
|
||||||
|
item.parent.id !== parentId ||
|
||||||
|
item.enabled !== enable
|
||||||
|
){
|
||||||
|
Items.update(
|
||||||
|
itemId,
|
||||||
|
{$set: {
|
||||||
|
"parent.collection": parentCollection,
|
||||||
|
"parent.id": parentId,
|
||||||
|
enabled: enable,
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
moveItemToParent: function(itemId, parent) {
|
||||||
|
check(itemId, String);
|
||||||
|
check(parent, {collection: String, id: String});
|
||||||
|
moveItem(itemId, false, parent.collection, parent.id);
|
||||||
|
},
|
||||||
|
moveItemToCharacter: function(itemId, charId) {
|
||||||
|
check(itemId, String);
|
||||||
|
check(charId, String);
|
||||||
|
moveItem(itemId, false, "Characters", charId);
|
||||||
|
},
|
||||||
|
moveItemToContainer: function(itemId, containerId) {
|
||||||
|
check(itemId, String);
|
||||||
|
check(containerId, String);
|
||||||
|
moveItem(itemId, false, "Containers", containerId);
|
||||||
|
},
|
||||||
|
equipItem: function(itemId, charId){
|
||||||
|
check(itemId, String);
|
||||||
|
check(charId, String);
|
||||||
|
moveItem(itemId, true, "Characters", charId);
|
||||||
|
},
|
||||||
|
unequipItem: function(itemId, charId){
|
||||||
|
check(itemId, String);
|
||||||
|
check(charId, String);
|
||||||
|
moveItem(itemId, false, "Characters", charId);
|
||||||
|
},
|
||||||
|
splitItemToParent: function(itemId, moveQuantity, parent){
|
||||||
|
check(itemId, String);
|
||||||
|
check(moveQuantity, Number);
|
||||||
|
check(parent, {id: String, collection: String});
|
||||||
|
|
||||||
|
//get the item
|
||||||
|
var item = Items.findOne(itemId);
|
||||||
|
if (!item) return;
|
||||||
|
|
||||||
|
//don't bother moving nothing
|
||||||
|
if (moveQuantity <= 0 || item.quantity <= 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//ensure we are only moving up to the current stack size
|
||||||
|
if (item.quantity < moveQuantity){
|
||||||
|
moveQuantity = this.quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
checkMovePermission(itemId, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//create a new item stack
|
||||||
|
var newStack = _.omit(EJSON.clone(item), "_id");
|
||||||
|
newStack.parent = parent;
|
||||||
|
newStack.quantity = moveQuantity;
|
||||||
|
|
||||||
|
//find out if we have an exact replica in the destination
|
||||||
|
var query = _.omit(newStack, ["parent", "quantity"]);
|
||||||
|
query["parent.collection"] = newStack.parent.collection;
|
||||||
|
query["parent.id"] = newStack.parent.id;
|
||||||
|
query._id = {$ne: itemId}; //make sure we don't join it to itself
|
||||||
|
var existingStack = Items.findOne(query);
|
||||||
|
if (existingStack){
|
||||||
|
//increase the existing stack's size
|
||||||
|
Items.update(
|
||||||
|
existingStack._id,
|
||||||
|
{$inc: {quantity: moveQuantity}}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
//insert the new stack
|
||||||
|
Items.insert(newStack, function(err, id){
|
||||||
|
if (err) throw err;
|
||||||
|
//copy the children also
|
||||||
|
Meteor.call("cloneChildren", item._id, {collection: "Items", id: id});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//reduce the old stack's size
|
||||||
|
var oldQuantity = item.quantity - moveQuantity;
|
||||||
|
if (oldQuantity === 0){
|
||||||
|
Items.remove(itemId);
|
||||||
|
} else {
|
||||||
|
Items.update(itemId, {$set: {quantity: oldQuantity}});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Items.helpers({
|
Items.helpers({
|
||||||
totalValue: function(){
|
totalValue: function(){
|
||||||
return this.value * this.quantity;
|
return this.value * this.quantity;
|
||||||
@@ -23,73 +178,21 @@ Items.helpers({
|
|||||||
return this.weight * this.quantity;
|
return this.weight * this.quantity;
|
||||||
},
|
},
|
||||||
pluralName: function(){
|
pluralName: function(){
|
||||||
if(this.plural && this.quantity !== 1){
|
if (this.plural && this.quantity !== 1){
|
||||||
return this.plural;
|
return this.plural;
|
||||||
} else{
|
} else {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
equip: function(characterId){
|
|
||||||
var charId = characterId || this.charId;
|
|
||||||
if(!charId || ! Characters.findOne(charId)) throw "Invalid character";
|
|
||||||
if(this.parent.collection === "Characters" && this.parent.id === charId && this.enabled) return;
|
|
||||||
Items.update(this._id, {$set: {"parent.collection": "Characters", "parent.id": charId, enabled: true}});
|
|
||||||
},
|
|
||||||
unequip: function(){
|
|
||||||
if(!this.enabled) return;
|
|
||||||
Items.update(this._id, {$set: {enabled: false}});
|
|
||||||
},
|
|
||||||
moveToContainer: function(containerId){
|
|
||||||
if( !containerId || !Containers.findOne(containerId) ) throw "Invalid container";
|
|
||||||
if(this.parent.collection === "Containers" && this.parent.id === containerId && !this.enabled) return;
|
|
||||||
Items.update(this._id, {$set: {"parent.collection": "Containers", "parent.id": containerId, enabled: false}});
|
|
||||||
},
|
|
||||||
moveToCharacter: function(characterId){
|
|
||||||
if(!characterId || ! Characters.findOne(characterId)) throw "Invalid character";
|
|
||||||
if(this.parent.collection === "Characters" && this.parent.id === characterId && !this.enabled) return;
|
|
||||||
Items.update(this._id, {$set: {"parent.collection": "Characters", "parent.id": characterId, charId: characterId, enabled: false}});
|
|
||||||
},
|
|
||||||
splitToParent: function(parent, moveQuantity){
|
|
||||||
check(parent, {id: String, collection: String});
|
|
||||||
check(moveQuantity, Number);
|
|
||||||
var parentCollection = Meteor.isClient? window[parent.collection] : global[parent.collection];
|
|
||||||
if(!parent.id || !parentCollection.findOne(parent.id)) throw "Invalid parent";
|
|
||||||
var oldStack = this;
|
|
||||||
//we can only move as much as we have, leaving 0 behind at worst
|
|
||||||
if(oldStack.quantity < moveQuantity) moveQuantity = oldStack.quantity;
|
|
||||||
var oldQuantity = oldStack.quantity - moveQuantity;
|
|
||||||
|
|
||||||
var newStack = _.pick(oldStack, Schemas.Item.objectKeys());
|
|
||||||
newStack.parent = parent;
|
|
||||||
newStack.quantity = moveQuantity;
|
|
||||||
|
|
||||||
var existingStack = Items.findOne(_.omit(newStack, "quantity"));
|
|
||||||
var updateStackSize = function(){
|
|
||||||
if(oldQuantity > 0){
|
|
||||||
Items.update(oldStack._id, {$set: {quantity: oldQuantity}});
|
|
||||||
} else {
|
|
||||||
Items.remove(oldStack._id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if(existingStack){
|
|
||||||
Items.update(existingStack._id, {$inc: {quantity: moveQuantity}}, {}, function(){
|
|
||||||
updateStackSize();
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
Items.insert(newStack, function(err, id){
|
|
||||||
if(err) throw err;
|
|
||||||
updateStackSize();
|
|
||||||
//copy the children also
|
|
||||||
Meteor.call("cloneChildren", oldStack._id, {collection: "Items", id: id});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Items.before.update(function(userId, doc, fieldNames, modifier, options){
|
Items.before.update(function(userId, doc, fieldNames, modifier, options){
|
||||||
if(
|
if (
|
||||||
modifier && modifier.$set && modifier.$set.enabled && //we are equipping this item
|
modifier && modifier.$set && modifier.$set.enabled && //we are equipping this item
|
||||||
!(modifier.$set["parent.collection"] === "Characters" && modifier.$set["parent.id"]) //and we haven't specified a character to equip to
|
!(
|
||||||
|
modifier.$set["parent.collection"] === "Characters" &&
|
||||||
|
modifier.$set["parent.id"]
|
||||||
|
) //and we haven"t specified a character to equip to
|
||||||
){
|
){
|
||||||
//equip it to the current character
|
//equip it to the current character
|
||||||
modifier.$set["parent.collection"] = "Characters";
|
modifier.$set["parent.collection"] = "Characters";
|
||||||
@@ -97,21 +200,21 @@ Items.before.update(function(userId, doc, fieldNames, modifier, options){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Items.attachBehaviour('softRemovable');
|
Items.attachBehaviour("softRemovable");
|
||||||
makeChild(Items); //children of containers
|
makeChild(Items); //children of containers
|
||||||
makeParent(Items, ['name', 'enabled']); //parents of effects and attacks
|
makeParent(Items, ["name", "enabled"]); //parents of effects and attacks
|
||||||
|
|
||||||
Items.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
Items.allow(CHARACTER_SUBSCHEMA_ALLOW);
|
||||||
|
|
||||||
//give characters default items
|
//give characters default items
|
||||||
Characters.after.insert(function (userId, char) {
|
Characters.after.insert(function(userId, char) {
|
||||||
if(Meteor.isServer){
|
if (Meteor.isServer){
|
||||||
var containerId = Containers.insert({
|
var containerId = Containers.insert({
|
||||||
name: "Coin Pouch",
|
name: "Coin Pouch",
|
||||||
charId: char._id,
|
charId: char._id,
|
||||||
isCarried: true,
|
isCarried: true,
|
||||||
description: "A sturdy pouch for coins",
|
description: "A sturdy pouch for coins",
|
||||||
color: "d"
|
color: "d",
|
||||||
});
|
});
|
||||||
Items.insert({
|
Items.insert({
|
||||||
name: "Gold piece",
|
name: "Gold piece",
|
||||||
@@ -123,8 +226,8 @@ Characters.after.insert(function (userId, char) {
|
|||||||
color: "n",
|
color: "n",
|
||||||
parent: {
|
parent: {
|
||||||
id: containerId,
|
id: containerId,
|
||||||
collection: "Containers"
|
collection: "Containers",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
Items.insert({
|
Items.insert({
|
||||||
name: "Silver piece",
|
name: "Silver piece",
|
||||||
@@ -136,8 +239,8 @@ Characters.after.insert(function (userId, char) {
|
|||||||
color: "q",
|
color: "q",
|
||||||
parent: {
|
parent: {
|
||||||
id: containerId,
|
id: containerId,
|
||||||
collection: "Containers"
|
collection: "Containers",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
Items.insert({
|
Items.insert({
|
||||||
name: "Copper piece",
|
name: "Copper piece",
|
||||||
@@ -149,8 +252,8 @@ Characters.after.insert(function (userId, char) {
|
|||||||
color: "s",
|
color: "s",
|
||||||
parent: {
|
parent: {
|
||||||
id: containerId,
|
id: containerId,
|
||||||
collection: "Containers"
|
collection: "Containers",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
27
rpg-docs/Model/Meta/ChangeLogs.js
Normal file
27
rpg-docs/Model/Meta/ChangeLogs.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
ChangeLogs = new Mongo.Collection("changeLogs");
|
||||||
|
|
||||||
|
Schemas.ChangeLog = new SimpleSchema({
|
||||||
|
version: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
changes: {
|
||||||
|
type: [String],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
ChangeLogs.attachSchema(Schemas.ChangeLog);
|
||||||
|
|
||||||
|
ChangeLogs.allow({
|
||||||
|
insert: function(userId, doc) {
|
||||||
|
var user = Meteor.users.findOne(userId);
|
||||||
|
if (user) return _.contains(user.roles, "admin");
|
||||||
|
},
|
||||||
|
update: function(userId, doc, fields, modifier) {
|
||||||
|
var user = Meteor.users.findOne(userId);
|
||||||
|
if (user) return _.contains(user.roles, "admin");
|
||||||
|
},
|
||||||
|
remove: function(userId, doc) {
|
||||||
|
var user = Meteor.users.findOne(userId);
|
||||||
|
if (user) return _.contains(user.roles, "admin");
|
||||||
|
},
|
||||||
|
});
|
||||||
79
rpg-docs/Model/Meta/Reports.js
Normal file
79
rpg-docs/Model/Meta/Reports.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
Reports = new Mongo.Collection("reports");
|
||||||
|
|
||||||
|
Schemas.Report = new SimpleSchema({
|
||||||
|
owner: {
|
||||||
|
type: String,
|
||||||
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
trim: false,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
trim: false,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: ["bug", "change", "feature", "general"],
|
||||||
|
defaultValue: "bug",
|
||||||
|
},
|
||||||
|
//the immediate impact of doing this action (eg. -1 rages)
|
||||||
|
severity: {
|
||||||
|
type: Number,
|
||||||
|
defaultValue: 5,
|
||||||
|
min: 1,
|
||||||
|
max: 10,
|
||||||
|
},
|
||||||
|
metaData: {
|
||||||
|
type: Object,
|
||||||
|
blackbox: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Reports.attachSchema(Schemas.Report);
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
insertReport: function(report) {
|
||||||
|
check(report, {
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
type: String,
|
||||||
|
severity: Number,
|
||||||
|
metaData: Object,
|
||||||
|
});
|
||||||
|
report.owner = this.userId;
|
||||||
|
var id = Reports.insert(report);
|
||||||
|
var user = Meteor.users.findOne(this.userId);
|
||||||
|
var sender = user &&
|
||||||
|
user.emails &&
|
||||||
|
user.emails[0] &&
|
||||||
|
user.emails[0].address ||
|
||||||
|
user.services &&
|
||||||
|
user.services.google &&
|
||||||
|
user.services.google.email ||
|
||||||
|
"reports@dicecloud.com";
|
||||||
|
var bodyText = "Report ID: " + id +
|
||||||
|
"\nSeverity: " + report.severity +
|
||||||
|
"\nType: " + report.type +
|
||||||
|
"\n\n" + report.description;
|
||||||
|
Email.send({
|
||||||
|
from: sender,
|
||||||
|
to: "stefan.zermatten@gmail.com",
|
||||||
|
subject: "DiceCloud feedback - " + report.title,
|
||||||
|
text: bodyText,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteReport: function(id) {
|
||||||
|
var user = Meteor.users.findOne(this.userId);
|
||||||
|
if (!_.contains(user.roles, "admin")){
|
||||||
|
throw new Meteor.Error(
|
||||||
|
"not admin",
|
||||||
|
"The user must be an administrator to delete feedback"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Reports.remove(id);
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,44 +1,23 @@
|
|||||||
Schema = {};
|
|
||||||
|
|
||||||
Schema.User = new SimpleSchema({
|
|
||||||
username: {
|
|
||||||
type: String,
|
|
||||||
regEx: /^[a-z0-9A-Z_]{3,15}$/,
|
|
||||||
optional: true
|
|
||||||
},
|
|
||||||
emails: {
|
|
||||||
type: [Object],
|
|
||||||
// this must be optional if you also use other login services like facebook,
|
|
||||||
// but if you use only accounts-password, then it can be required
|
|
||||||
optional: true
|
|
||||||
},
|
|
||||||
"emails.$.address": {
|
|
||||||
type: String,
|
|
||||||
regEx: SimpleSchema.RegEx.Email
|
|
||||||
},
|
|
||||||
"emails.$.verified": {
|
|
||||||
type: Boolean
|
|
||||||
},
|
|
||||||
createdAt: {
|
|
||||||
type: Date
|
|
||||||
},
|
|
||||||
services: {
|
|
||||||
type: Object,
|
|
||||||
optional: true,
|
|
||||||
blackbox: true
|
|
||||||
},
|
|
||||||
roles: {
|
|
||||||
type: [String],
|
|
||||||
optional: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Meteor.users.attachSchema(Schema.User);
|
|
||||||
|
|
||||||
Meteor.users.allow({
|
Meteor.users.allow({
|
||||||
update: function (userId, doc, fields, modifier) {
|
update: function(userId, doc, fields, modifier) {
|
||||||
return userId === doc._id &&
|
if (
|
||||||
fields.length === 1 &&
|
doc._id === userId &&
|
||||||
fields[0] === 'username';
|
_.contains(fields, "username") &&
|
||||||
|
_.contains(fields, "profile") &&
|
||||||
|
fields.length === 2 &&
|
||||||
|
_.keys(modifier).length === 1 &&
|
||||||
|
modifier.$set &&
|
||||||
|
modifier.$set["profile.username"] &&
|
||||||
|
modifier.$set.username &&
|
||||||
|
_.keys(modifier.$set).length === 2
|
||||||
|
){
|
||||||
|
var expectedUsername = modifier.$set["profile.username"];
|
||||||
|
expectedUsername = expectedUsername.toLowerCase().replace(/\s+/gm, "");
|
||||||
|
if (modifier.$set.username !== expectedUsername){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var foundUser = Meteor.call("getUserId", expectedUsername);
|
||||||
|
return !foundUser || foundUser === userId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,71 +1,96 @@
|
|||||||
Router.configure({
|
Router.configure({
|
||||||
loadingTemplate: 'loading',
|
loadingTemplate: "loading",
|
||||||
layoutTemplate: 'layout'
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
|
|
||||||
Router.map( function () {
|
Router.plugin("ensureSignedIn", {
|
||||||
/*
|
except: [
|
||||||
this.route('home', {
|
"home",
|
||||||
path: '/',
|
"atSignIn",
|
||||||
waitOn: function(){
|
"atSignUp",
|
||||||
return Meteor.subscribe("characterList", Meteor.userId());
|
"atForgotPassword",
|
||||||
},
|
"atResetPwd",
|
||||||
data: {
|
"atEnrollAccount",
|
||||||
characters: function(){
|
"atVerifyEmail",
|
||||||
return Characters.find({}, {fields: {_id: 1}});
|
"atResendVerificationEmail",
|
||||||
}
|
"loginButtons",
|
||||||
}
|
"notFound",
|
||||||
});*/ //add a home route and change characterList route
|
]
|
||||||
|
});
|
||||||
|
|
||||||
this.route('characterList', {
|
Router.plugin("dataNotFound", {notFoundTemplate: "notFound"});
|
||||||
path: '/',
|
|
||||||
waitOn: function(){
|
Router.map(function() {
|
||||||
return Meteor.subscribe("characterList", Meteor.userId());
|
this.route("/", {
|
||||||
|
name: "home",
|
||||||
|
onAfterAction: function() {
|
||||||
|
document.title = appName;
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
characters: function(){
|
|
||||||
return Characters.find({}, {fields: {_id: 1}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('characterSheet', {
|
this.route("characterList", {
|
||||||
path: '/character/:_id',
|
path: "/characterList",
|
||||||
|
waitOn: function(){
|
||||||
|
return subsManager.subscribe("characterList", Meteor.userId());
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
characters: function(){
|
||||||
|
return Characters.find({}, {fields: {_id: 1}});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onAfterAction: function() {
|
||||||
|
document.title = appName;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route("characterSheet", {
|
||||||
|
path: "/character/:_id",
|
||||||
waitOn: function(){
|
waitOn: function(){
|
||||||
return [
|
return [
|
||||||
Meteor.subscribe("singleCharacter", this.params._id, Meteor.userId()),
|
subsManager.subscribe("singleCharacter", this.params._id, Meteor.userId()),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
var data = Characters.findOne({_id: this.params._id}, {fields: {_id: 1, name: 1, color: 1}});
|
var data = Characters.findOne(
|
||||||
|
{_id: this.params._id},
|
||||||
|
{fields: {_id: 1, name: 1, color: 1, writers: 1, readers: 1}}
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
}
|
},
|
||||||
|
onAfterAction: function() {
|
||||||
|
var char = Characters.findOne({_id: this.params._id}, {fields: {name: 1}});
|
||||||
|
var name = char && char.name;
|
||||||
|
if (name){
|
||||||
|
document.title = name;
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('inventory', {
|
this.route("loading", {
|
||||||
path: '/inventory/:_id',
|
path: "/loading"
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route("profile", {
|
||||||
|
path: "/account",
|
||||||
|
onAfterAction: function() {
|
||||||
|
document.title = appName + " Account";
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route("/changelog", {
|
||||||
|
name: "changeLog",
|
||||||
|
waitOn: function() {
|
||||||
|
return [
|
||||||
|
subsManager.subscribe("changeLog"),
|
||||||
|
]
|
||||||
|
},
|
||||||
data: {
|
data: {
|
||||||
containers: function() {
|
changeLogs: function() {
|
||||||
var containers = Containers.find({owner: data._id}, {fields: {_id: 1}});
|
return ChangeLogs.find({}, {sort: {version: -1}});
|
||||||
return containers;
|
}
|
||||||
},
|
},
|
||||||
|
onAfterAction: function() {
|
||||||
}
|
document.title = appName;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
});
|
||||||
this.route('item', {
|
|
||||||
path: '/item/:_id',
|
|
||||||
data: function() {
|
|
||||||
var data = Items.findOne({_id: this.params._id});
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.route('loading', {
|
|
||||||
path: '/loading'
|
|
||||||
});
|
|
||||||
|
|
||||||
this.route('profile', {
|
|
||||||
path: '/account'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -13,10 +13,9 @@
|
|||||||
"tests"
|
"tests"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"polymer": "Polymer/polymer#~0.5.4",
|
"polymer": "Polymer/polymer#~0.5.5",
|
||||||
"core-elements": "Polymer/core-elements#~0.5.4",
|
"core-elements": "Polymer/core-elements#~0.5.5",
|
||||||
"paper-elements": "Polymer/paper-elements#~0.5.4",
|
"paper-elements": "Polymer/paper-elements#~0.5.5"
|
||||||
"paper-fab-menu": "cwdoh/paper-fab-menu"
|
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"core-component-page": "^0.5.0",
|
"core-component-page": "^0.5.0",
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ this.GlobalUI = (function() {
|
|||||||
return toast.show();
|
return toast.show();
|
||||||
};
|
};
|
||||||
|
|
||||||
GlobalUI.deletedToast = function(id, collection, itemName){
|
GlobalUI.deletedToast = function(id, collection, itemName) {
|
||||||
GlobalUI.toast({
|
GlobalUI.toast({
|
||||||
text: itemName? itemName + " deleted" : "Deleted item from" + collection,
|
text: itemName ? itemName + " deleted" : "Deleted item from" + collection,
|
||||||
template: "undoToast",
|
template: "undoToast",
|
||||||
data: {
|
data: {
|
||||||
id: id,
|
id: id,
|
||||||
collection: collection
|
collection: collection
|
||||||
@@ -23,7 +23,7 @@ this.GlobalUI = (function() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
GlobalUI.setDialog = function(opts){
|
GlobalUI.setDialog = function(opts) {
|
||||||
this.dialog = $("[global-dialog]")[0];
|
this.dialog = $("[global-dialog]")[0];
|
||||||
Session.set("global.ui.dialogHeader", opts.heading);
|
Session.set("global.ui.dialogHeader", opts.heading);
|
||||||
Session.set("global.ui.dialogData", opts.data);
|
Session.set("global.ui.dialogData", opts.data);
|
||||||
@@ -58,7 +58,7 @@ this.GlobalUI = (function() {
|
|||||||
Session.set("global.ui.detailShow", true);
|
Session.set("global.ui.detailShow", true);
|
||||||
};
|
};
|
||||||
|
|
||||||
//if setting the detail rather than showing it,
|
//if setting the detail rather than showing it,
|
||||||
//the template should contain the following in template.rendered
|
//the template should contain the following in template.rendered
|
||||||
//
|
//
|
||||||
//if (!this.alreadyRendered){
|
//if (!this.alreadyRendered){
|
||||||
@@ -69,30 +69,30 @@ this.GlobalUI = (function() {
|
|||||||
Session.set("global.ui.detailData", opts.data);
|
Session.set("global.ui.detailData", opts.data);
|
||||||
Session.set("global.ui.detailTemplate", opts.template);
|
Session.set("global.ui.detailTemplate", opts.template);
|
||||||
Session.set("global.ui.detailHeroId", opts.heroId);
|
Session.set("global.ui.detailHeroId", opts.heroId);
|
||||||
if(!!(window.history && window.history.pushState)){
|
if (window.history && window.history.pushState) {
|
||||||
history.replaceState({detail: "closed", opts: opts}, "Detail Dialog");
|
history.replaceState({detail: "closed", opts: opts}, "Detail Dialog");
|
||||||
history.pushState({detail: "opened", opts: opts}, "Detail Dialog");
|
history.pushState({detail: "opened", opts: opts}, "Detail Dialog");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var throttleBack = _.throttle(function(){
|
var throttleBack = _.throttle(function() {
|
||||||
history.back();
|
history.back();
|
||||||
}, 800, {trailing: false});
|
}, 800, {trailing: false});
|
||||||
|
|
||||||
GlobalUI.closeDetail = function(){
|
GlobalUI.closeDetail = function() {
|
||||||
if(!!(window.history && window.history.pushState)){
|
if (!!(window.history && window.history.pushState)) {
|
||||||
throttleBack();
|
throttleBack();
|
||||||
} else{
|
} else {
|
||||||
Session.set("global.ui.detailShow", false);
|
Session.set("global.ui.detailShow", false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
GlobalUI.popStateHandler = function(e){
|
GlobalUI.popStateHandler = function(e) {
|
||||||
var state = e.originalEvent.state;
|
var state = e.originalEvent.state;
|
||||||
if(state) {
|
if (state) {
|
||||||
if(state.detail === "closed"){
|
if (state.detail === "closed") {
|
||||||
Session.set("global.ui.detailShow", false);
|
Session.set("global.ui.detailShow", false);
|
||||||
} else if(state.detail === "opened"){
|
} else if (state.detail === "opened") {
|
||||||
var opts = state.opts;
|
var opts = state.opts;
|
||||||
Session.set("global.ui.detailData", opts.data);
|
Session.set("global.ui.detailData", opts.data);
|
||||||
Session.set("global.ui.detailTemplate", opts.template);
|
Session.set("global.ui.detailTemplate", opts.template);
|
||||||
@@ -115,22 +115,22 @@ Template.layout.helpers({
|
|||||||
globalDialogFullOnMobile: function() {
|
globalDialogFullOnMobile: function() {
|
||||||
return Session.get("global.ui.dialogFullOnMobile");
|
return Session.get("global.ui.dialogFullOnMobile");
|
||||||
},
|
},
|
||||||
globalDialogHeader: function(){
|
globalDialogHeader: function() {
|
||||||
return Session.get("global.ui.dialogHeader");
|
return Session.get("global.ui.dialogHeader");
|
||||||
},
|
},
|
||||||
globalDetailSelected: function(){
|
globalDetailSelected: function() {
|
||||||
return Session.get("global.ui.detailShow") ? 1 : 0;
|
return Session.get("global.ui.detailShow") ? 1 : 0;
|
||||||
},
|
},
|
||||||
globalDetailTemplate: function(){
|
globalDetailTemplate: function() {
|
||||||
return Session.get("global.ui.detailTemplate");
|
return Session.get("global.ui.detailTemplate");
|
||||||
},
|
},
|
||||||
globalDetailData: function(){
|
globalDetailData: function() {
|
||||||
return Session.get("global.ui.detailData");
|
return Session.get("global.ui.detailData");
|
||||||
},
|
},
|
||||||
globalToastTemplate: function(){
|
globalToastTemplate: function() {
|
||||||
return Session.get("global.ui.toastTemplate");
|
return Session.get("global.ui.toastTemplate");
|
||||||
},
|
},
|
||||||
globalToastData: function(){
|
globalToastData: function() {
|
||||||
return Session.get("global.ui.toastData");
|
return Session.get("global.ui.toastData");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -143,7 +143,7 @@ Template.layout.events({
|
|||||||
},
|
},
|
||||||
"core-animated-pages-transition-end [detail-pages]": function(e) {
|
"core-animated-pages-transition-end [detail-pages]": function(e) {
|
||||||
var detailOpened = Session.get("global.ui.detailShow");
|
var detailOpened = Session.get("global.ui.detailShow");
|
||||||
if(!detailOpened){
|
if (!detailOpened) {
|
||||||
Session.set("global.ui.detailData", null);
|
Session.set("global.ui.detailData", null);
|
||||||
Session.set("global.ui.detailTemplate", null);
|
Session.set("global.ui.detailTemplate", null);
|
||||||
Session.set("global.ui.detailHeroId", null);
|
Session.set("global.ui.detailHeroId", null);
|
||||||
@@ -151,14 +151,14 @@ Template.layout.events({
|
|||||||
},
|
},
|
||||||
"core-animated-pages-transition-prepare": function(e) {
|
"core-animated-pages-transition-prepare": function(e) {
|
||||||
var detailOpened = Session.get("global.ui.detailShow");
|
var detailOpened = Session.get("global.ui.detailShow");
|
||||||
if(detailOpened) {
|
if (detailOpened) {
|
||||||
//set up the transition
|
//set up the transition
|
||||||
} else {
|
} else {
|
||||||
//undo hack
|
//undo hack
|
||||||
$("#mainContentSection").removeClass("fake-selected");
|
$("#mainContentSection").removeClass("fake-selected");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tap #screenDim": function(e){
|
"tap #screenDim": function(e) {
|
||||||
GlobalUI.closeDetail();
|
GlobalUI.closeDetail();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
Template.registerHelper("canCast", function(){
|
Template.registerHelper("canCast", function() {
|
||||||
return Characters.find({_id: this._id, spells: {$size: 0}}).count() === 0;
|
return Characters.find({_id: this._id, spells: {$size: 0}}).count() === 0;
|
||||||
});
|
});
|
||||||
|
|||||||
6
rpg-docs/client/globalHelpers/canEditCharacter.js
Normal file
6
rpg-docs/client/globalHelpers/canEditCharacter.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Template.registerHelper("canEditCharacter", function(charId) {
|
||||||
|
var char = Characters.findOne(charId)
|
||||||
|
var userId = Meteor.userId();
|
||||||
|
return char.owner === userId ||
|
||||||
|
_.contains(char.writers, userId);
|
||||||
|
});
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
Template.registerHelper("colorClass", function(color){
|
Template.registerHelper("colorClass", function(color) {
|
||||||
return color? getColorClass(color) : getColorClass(this.color);
|
if (color) {
|
||||||
|
return getColorClass(color);
|
||||||
|
} else if (this.color) {
|
||||||
|
return getColorClass(this.color);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.registerHelper("hexColor", function(color){
|
Template.registerHelper("hexColor", function(color) {
|
||||||
return getHexColor(color);
|
return getHexColor(color);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
Template.registerHelper("detailHero", function(suffix, givenId){
|
Template.registerHelper("detailHero", function(suffix, givenId) {
|
||||||
var id = givenId || this._id;
|
var id = givenId || this._id;
|
||||||
if(suffix) id += suffix;
|
if (suffix) {
|
||||||
if ( Session.equals("global.ui.detailHeroId", id) ) {
|
id += suffix;
|
||||||
|
}
|
||||||
|
if (Session.equals("global.ui.detailHeroId", id)) {
|
||||||
return "hero";
|
return "hero";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
/*Template.registerHelper(function("effectList", */var disabled = function(charId, fieldName){
|
|
||||||
var obj = Characters.findOne(charId, {fields: {_id: 1}}).getField(fieldName);
|
|
||||||
var result = $("<div>");
|
|
||||||
if(_.has(obj, "conditional") && obj.conditional.length > 0){
|
|
||||||
_.each(obj.conditional, function(cond){
|
|
||||||
var c = $("<div>")
|
|
||||||
.append("* ")
|
|
||||||
.append(evaluateString(charId, cond.name));
|
|
||||||
result.append(c);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj.base > 0){
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append(obj.base))
|
|
||||||
.append("Base");
|
|
||||||
result.append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_.has(obj, "proficiency") && obj.proficiency.length > 0){
|
|
||||||
var highestProf = {};
|
|
||||||
_.each(obj.proficiency, function(prof, i){
|
|
||||||
var value = evaluateEffect(charId, prof)
|
|
||||||
if(i === 0 || value > highestProf.value){
|
|
||||||
highestProf.value = value;
|
|
||||||
highestProf.name = prof.name;
|
|
||||||
highestProf.calculation = prof.calculation;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append(highestProf.value).append(" x Proficiency Bonus"))
|
|
||||||
.append(highestProf.name);
|
|
||||||
result.append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_.has(obj, "add") && obj.add.length > 0){
|
|
||||||
_.each(obj.add, function(a){
|
|
||||||
var value = signedString(evaluateEffect(charId, a));
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append(value))
|
|
||||||
.append(a.name);
|
|
||||||
result.append(c);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_.has(obj, "mul") && obj.mul.length > 0){
|
|
||||||
_.each(obj.mul, function(a){
|
|
||||||
var value = signedString(evaluateEffect(charId, a));
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append("×").append(value))
|
|
||||||
.append(a.name);
|
|
||||||
result.append(c);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_.has(obj, "min") && obj.min.length > 0){
|
|
||||||
var highestMin = {};
|
|
||||||
_.each(obj.min, function(m, i){
|
|
||||||
var value = evaluateEffect(charId, m)
|
|
||||||
if(i === 0 || value > highestMin.value){
|
|
||||||
highestMin.value = value;
|
|
||||||
highestMin.name = m.name;
|
|
||||||
highestMin.calculation = m.calculation;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append(highestMin.value).append(" Minimum"))
|
|
||||||
.append(highestMin.name);
|
|
||||||
result.append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_.has(obj, "max") && obj.max.length > 0){
|
|
||||||
var lowestMax = {};
|
|
||||||
_.each(obj.max, function(m, i){
|
|
||||||
var value = evaluateEffect(charId, m)
|
|
||||||
if(i === 0 || value < lowestMax.value){
|
|
||||||
lowestMax.value = value;
|
|
||||||
lowestMax.name = m.name;
|
|
||||||
lowestMax.calculation = m.calculation;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append(lowestMax.value).append(" Maximum"))
|
|
||||||
.append(lowestMax.name);
|
|
||||||
result.append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj.base < 0){
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append(obj.base))
|
|
||||||
.append("Damage");
|
|
||||||
result.append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_.has(obj, "advantage") && obj.advantage.length > 0){
|
|
||||||
_.each(obj.advantage, function(adv){
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append("Advantage"))
|
|
||||||
.append(adv.name);
|
|
||||||
result.append(c);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_.has(obj, "disadvantage") && obj.disadvantage.length > 0){
|
|
||||||
_.each(obj.disadvantage, function(disadv){
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append("Disadvantage"))
|
|
||||||
.append(disadv.name);
|
|
||||||
result.append(c);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_.has(obj, "fail") && obj.fail.length > 0){
|
|
||||||
_.each(obj.fail, function(f){
|
|
||||||
var c = $("<div>")
|
|
||||||
.append($("<span>").addClass("auditValue").append("Fail"))
|
|
||||||
.append(f.name);
|
|
||||||
result.append(c);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
var string = result.html()
|
|
||||||
if (_.isString(string)) return Spacebars.SafeString(string);
|
|
||||||
return string;
|
|
||||||
};
|
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
Template.registerHelper("evaluate", function(charId, string){
|
Template.registerHelper("evaluate", function(charId, string) {
|
||||||
return evaluate(charId, string);
|
return evaluate(charId, string);
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.registerHelper("evaluateSigned", function(charId, string){
|
Template.registerHelper("evaluateSigned", function(charId, string) {
|
||||||
var number = evaluate(charId, string);
|
var number = evaluate(charId, string);
|
||||||
if(_.isFinite(number)){
|
if (_.isFinite(number)) {
|
||||||
return number > 0? "+" + number : "" + number;
|
return number > 0 ? "+" + number : "" + number;
|
||||||
} else{
|
} else {
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.registerHelper("evaluateSignedSpaced", function(charId, string){
|
Template.registerHelper("evaluateSignedSpaced", function(charId, string) {
|
||||||
var number = evaluate(charId, string);
|
var number = evaluate(charId, string);
|
||||||
if(_.isFinite(number)){
|
if (_.isFinite(number)) {
|
||||||
return number > 0? "+ " + number : "- " + (-1 * number);
|
return number > 0 ? "+ " + number : "- " + (-1 * number);
|
||||||
} else{
|
} else {
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.registerHelper("evaluateString", function(charId, string){
|
Template.registerHelper("evaluateString", function(charId, string) {
|
||||||
return evaluateString(charId, string);
|
return evaluateString(charId, string);
|
||||||
});
|
});
|
||||||
|
|||||||
27
rpg-docs/client/globalHelpers/openParentDialog.js
Normal file
27
rpg-docs/client/globalHelpers/openParentDialog.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
openParentDialog = function(parent, charId, heroId) {
|
||||||
|
var detail;
|
||||||
|
if (parent.collection === "Characters" && parent.group === "racial") {
|
||||||
|
detail = {
|
||||||
|
template: "raceDialog",
|
||||||
|
data: {charId: parent.id},
|
||||||
|
};
|
||||||
|
} else if (parent.collection === "Features") {
|
||||||
|
detail = {
|
||||||
|
template: "featureDialog",
|
||||||
|
data: {featureId: parent.id},
|
||||||
|
};
|
||||||
|
} else if (parent.collection === "Classes") {
|
||||||
|
detail = {
|
||||||
|
template: "classDialog",
|
||||||
|
data: {classId: parent.id},
|
||||||
|
};
|
||||||
|
} else if (parent.collection === "Items") {
|
||||||
|
detail = {
|
||||||
|
template: "itemDialog",
|
||||||
|
data: {itemId: parent.id},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
detail.heroId = heroId;
|
||||||
|
detail.charId = charId;
|
||||||
|
GlobalUI.setDetail(detail);
|
||||||
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Template.registerHelper("round", function(value, decimalPlaces){
|
Template.registerHelper("round", function(value, decimalPlaces) {
|
||||||
decimalPlaces = +decimalPlaces || 2;
|
decimalPlaces = +decimalPlaces || 2;
|
||||||
var num = +value;
|
var num = +value;
|
||||||
var tens = Math.pow(10, decimalPlaces)
|
var tens = Math.pow(10, decimalPlaces);
|
||||||
return Math.round(num * tens) / tens;
|
return Math.round(num * tens) / tens;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
Template.registerHelper("session", function(key){
|
Template.registerHelper("session", function(key) {
|
||||||
return Session.get(key);
|
return Session.get(key);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
Template.registerHelper("signedString", function(number){
|
Template.registerHelper("signedString", function(number) {
|
||||||
return number > 0? "+" + number : "" + number;
|
return number >= 0 ? "+" + number : "" + number;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,24 +1,63 @@
|
|||||||
Template.registerHelper("valueString", function(value){
|
Template.registerHelper("valueString", function(value) {
|
||||||
|
var intValue = Math.round(value * 100);
|
||||||
|
var cp = intValue % 10;
|
||||||
|
intValue -= cp;
|
||||||
|
cp = Math.round(cp);
|
||||||
|
sp = intValue % 100;
|
||||||
|
intValue -= sp;
|
||||||
|
sp = Math.round(sp / 10)
|
||||||
|
gp = Math.floor(value);
|
||||||
|
|
||||||
var resultArray = [];
|
var resultArray = [];
|
||||||
//sp
|
if (gp > 0) {
|
||||||
var gp = Math.floor(value);
|
resultArray.push(gp + "gp");
|
||||||
if(gp > 0) resultArray.push(gp + "gp");
|
}
|
||||||
//sp
|
if (sp > 0) {
|
||||||
var sp = Math.floor(10 * (value % 1));
|
resultArray.push(sp + "sp");
|
||||||
if(sp > 0) resultArray.push(sp + "sp");
|
}
|
||||||
//cp
|
if (cp > 0) {
|
||||||
var cp = 10 * ((value * 10) % 1);
|
resultArray.push(cp + "cp");
|
||||||
cp = Math.round(cp * 1000) / 1000;
|
}
|
||||||
if(cp > 0) resultArray.push(cp + "cp");
|
|
||||||
|
|
||||||
//build string with correct spacing
|
//build string with correct spacing
|
||||||
var result = "";
|
var result = "";
|
||||||
for(var i = 0; i < resultArray.length; i++){
|
for (var i = 0, l = resultArray.length; i < l; i++) {
|
||||||
//add a space between values
|
//add a space between values
|
||||||
if(i !== 0){
|
if (i !== 0) {
|
||||||
result += " ";
|
result += " ";
|
||||||
}
|
}
|
||||||
result += resultArray[i];
|
result += resultArray[i];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.registerHelper("longValueString", function(value) {
|
||||||
|
var resultArray = [];
|
||||||
|
//sp
|
||||||
|
var gp = Math.floor(value);
|
||||||
|
if (gp > 0) {
|
||||||
|
resultArray.push(gp + "gp");
|
||||||
|
}
|
||||||
|
//sp
|
||||||
|
var sp = Math.floor(10 * (value % 1));
|
||||||
|
if (sp > 0 || resultArray.length) {
|
||||||
|
resultArray.push(sp + "sp");
|
||||||
|
}
|
||||||
|
//cp
|
||||||
|
var cp = 10 * ((value * 10) % 1);
|
||||||
|
cp = Math.round(cp * 1000) / 1000;
|
||||||
|
if (cp > 0 || resultArray.length) {
|
||||||
|
resultArray.push(cp + "cp");
|
||||||
|
}
|
||||||
|
|
||||||
|
//build string with correct spacing
|
||||||
|
var result = "";
|
||||||
|
for (var i = 0; i < resultArray.length; i++) {
|
||||||
|
//add a space between values
|
||||||
|
if (i !== 0) {
|
||||||
|
result += " ";
|
||||||
|
}
|
||||||
|
result += resultArray[i];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|||||||
96
rpg-docs/client/style/cards.scss
Normal file
96
rpg-docs/client/style/cards.scss
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
@import "bourbon/bourbon";
|
||||||
|
|
||||||
|
$thickColumnWidth: 304px;
|
||||||
|
$thinColumnWidth: 240px;
|
||||||
|
|
||||||
|
//Column layouts of cards
|
||||||
|
.column-container {
|
||||||
|
@include column-fill(balance);
|
||||||
|
@include column-gap(8px);
|
||||||
|
@include column-width($thickColumnWidth);
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
&.thin-columns {
|
||||||
|
@include column-count(4);
|
||||||
|
@include column-width($thinColumnWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cards
|
||||||
|
.card {
|
||||||
|
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;
|
||||||
|
border-radius: 2px 2px 0 0;
|
||||||
|
&.white {
|
||||||
|
cursor: auto;
|
||||||
|
padding: 16px;
|
||||||
|
border-bottom: rgba(0,0,0,0.12) solid 1px;
|
||||||
|
}
|
||||||
|
paper-checkbox::shadow #ink[checked] {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
paper-checkbox::shadow #ink {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
paper-checkbox::shadow #checkbox.checked {
|
||||||
|
background-color: #ffffff;
|
||||||
|
background-color: rgba(255,255,255,0.27);
|
||||||
|
border-color: #ffffff;
|
||||||
|
border-color: rgba(255,255,255,0.27);
|
||||||
|
}
|
||||||
|
paper-checkbox::shadow #checkbox {
|
||||||
|
border-color: #ffffff;
|
||||||
|
border-color: rgba(255,255,255,0.54);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom {
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 0 0 2px 2px;
|
||||||
|
&.list {
|
||||||
|
padding: 0 0 16px 0;
|
||||||
|
.subhead {
|
||||||
|
color: rgba(0,0,0,0.54);
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.010em;
|
||||||
|
padding: 12px 16px 12px 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.text {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.left {
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 2px 0 0 2px;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 72px;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 0 2px 2px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* undo pointer cursor on detail box heading */
|
||||||
|
#globalDetail .card .top {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
37
rpg-docs/client/style/listItem.scss
Normal file
37
rpg-docs/client/style/listItem.scss
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
List items
|
||||||
|
*/
|
||||||
|
.item-slot {
|
||||||
|
background-color: rgb(232, 232, 232);
|
||||||
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
background: white;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
height: 40px;
|
||||||
|
margin: 1px 0 1px 0;
|
||||||
|
padding: 0 16px 0 16px;
|
||||||
|
position: relative;
|
||||||
|
transition: box-shadow 0.3s ease, opacity 0.5s ease-in-out;
|
||||||
|
&.small {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
&.tall {
|
||||||
|
height: 56px;
|
||||||
|
}
|
||||||
|
&.flexible {
|
||||||
|
height: auto;
|
||||||
|
padding-top: 16px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
&[hero], &:active{
|
||||||
|
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.37);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
core-icon, paper-icon-button {
|
||||||
|
color: #747474;
|
||||||
|
color: rgba(0,0,0,0.54);
|
||||||
|
}
|
||||||
|
}
|
||||||
74
rpg-docs/client/style/main.scss
Normal file
74
rpg-docs/client/style/main.scss
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
@import "bourbon/bourbon";
|
||||||
|
@import "colors";
|
||||||
|
|
||||||
|
//apply a natural box layout model to all elements
|
||||||
|
*, *:before, *:after {
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
root {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial;
|
||||||
|
margin: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-color: #E0E0E0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Horizontal rule
|
||||||
|
hr {
|
||||||
|
background-color: #444;
|
||||||
|
opacity: 0.12;
|
||||||
|
border-width: 0;
|
||||||
|
color: #444;
|
||||||
|
height: 1px;
|
||||||
|
line-height: 0;
|
||||||
|
margin: 16px -16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
//FABs
|
||||||
|
.floatyButton {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 24px;
|
||||||
|
right: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Buttons
|
||||||
|
paper-button {
|
||||||
|
color: #000;
|
||||||
|
color: rgba(0,0,0,0.87);
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.010;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Style shortcuts
|
||||||
|
.scroll-y {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clickable, core-item, paper-tab {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pre-wrap, .prewrap{
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padded {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullwidth {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fab-buffer {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
20
rpg-docs/client/style/shadowDom.css
Normal file
20
rpg-docs/client/style/shadowDom.css
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
.card .left paper-icon-button {
|
||||||
|
display: block;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0;
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card .left paper-icon-button[disabled] {
|
||||||
|
color: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card .left paper-icon-button /deep/ core-icon {
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*fix paper-dropdowns*/
|
||||||
|
body /deep/ core-menu {
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
}
|
||||||
18
rpg-docs/client/style/tables.scss
Normal file
18
rpg-docs/client/style/tables.scss
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
td {
|
||||||
|
padding: 8px;
|
||||||
|
&:nth-child(1) {
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.strengthTable{
|
||||||
|
width: 100%;
|
||||||
|
td{
|
||||||
|
&:nth-child(2) {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
&:nth-child(3) {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
root {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial;
|
|
||||||
margin: 0;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.core-narrow {
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body /deep/ core-menu {
|
|
||||||
overflow-x: hidden !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calculatedValue {
|
|
||||||
color: #021C33;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-spacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
background-color: #444;
|
|
||||||
opacity: 0.12;
|
|
||||||
border-width: 0;
|
|
||||||
color: #444;
|
|
||||||
height: 1px;
|
|
||||||
line-height: 0;
|
|
||||||
margin: 0 -16px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
paper-button {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 400;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: #000;
|
|
||||||
color: rgba(0,0,0,0.87);
|
|
||||||
letter-spacing: 0.010;
|
|
||||||
}
|
|
||||||
|
|
||||||
.listRow {
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
/*hack to stop flickering*/
|
|
||||||
-webkit-backface-visibility: hidden;
|
|
||||||
-webkit-transform: translateX(0);
|
|
||||||
/*stop divs breaking over divide*/
|
|
||||||
-webkit-column-break-inside: avoid;
|
|
||||||
page-break-inside: avoid;
|
|
||||||
break-inside: avoid;
|
|
||||||
/*Fixes extra margin at top of columns*/
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
font-size: 14px;
|
|
||||||
border-radius: 2px;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card.double {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card paper-button {
|
|
||||||
font-size: 14px;
|
|
||||||
letter-spacing: 0.01em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cardHeader {
|
|
||||||
height: 48px;
|
|
||||||
padding: 0 16px 0 16px;
|
|
||||||
align-content: center;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: rgba(0, 0, 0, 0.54);
|
|
||||||
}
|
|
||||||
|
|
||||||
.statCard, .clickable {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceCards {
|
|
||||||
padding: 4px 4px 0 4px;
|
|
||||||
margin-bottom: -4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceCards .card {
|
|
||||||
width: 180px;
|
|
||||||
margin: 4px;
|
|
||||||
flex-grow: 1;
|
|
||||||
flex-shrink: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey-background, body {
|
|
||||||
background-color: #E0E0E0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.screen-center {
|
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
-webkit-transform: translate(-50%, -50%);
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-y {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fab-buffer {
|
|
||||||
height: 88px;
|
|
||||||
width: 100%;
|
|
||||||
order: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
*[hidden] {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden{
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
html /deep/ paper-action-dialog[global-dialog] {
|
|
||||||
top: 0 !important;
|
|
||||||
left: 0 !important;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.floatyButton {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 24px;
|
|
||||||
right: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
paper-fab-menu /deep/ .container {
|
|
||||||
padding: 24px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
paper-slider {
|
|
||||||
margin-left: -8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-subhead {
|
|
||||||
color: rgba(0,0,0,0.54);
|
|
||||||
font-size: 14px;
|
|
||||||
height: 40px;
|
|
||||||
padding-left: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.whiteTop {
|
|
||||||
border-bottom: rgba(0,0,0,0.12) solid 1px;
|
|
||||||
background: white;
|
|
||||||
padding: 16px;
|
|
||||||
position: relative;
|
|
||||||
border-radius: 2px 2px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.whiteTop paper-icon-button {
|
|
||||||
margin: -8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullwidth {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.padded {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.listPadded {
|
|
||||||
padding: 0 0 16px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightPadded {
|
|
||||||
padding-right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottomPadded {
|
|
||||||
padding-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.s {
|
|
||||||
padding: 0 0 16px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftRound{
|
|
||||||
border-radius: 2px 0 0 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preline {
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.white-text .display1{
|
.white-text .display1, .white-text.display1{
|
||||||
color: rgba(255,255,255,0.54);
|
color: rgba(255,255,255,0.54);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,6 +109,5 @@ html /deep/ .white-text{
|
|||||||
|
|
||||||
.white54 {
|
.white54 {
|
||||||
color: #eee;
|
color: #eee;
|
||||||
color: rgba(255,255,255,0.54)
|
color: rgba(255,255,255,0.54);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,21 +15,11 @@
|
|||||||
value={{details}}></paper-input>
|
value={{details}}></paper-input>
|
||||||
</div>
|
</div>
|
||||||
<div layout horizontal>
|
<div layout horizontal>
|
||||||
<!--DamageType-->
|
|
||||||
<paper-dropdown-menu id="damageDiceDropdown" label="Damage Dice">
|
|
||||||
<paper-dropdown layered class="dropdown">
|
|
||||||
<core-menu class="menu" selected={{damageDice}}>
|
|
||||||
{{#each DAMAGE_DICE}}
|
|
||||||
<paper-item name={{this}} class="containerMenuItem">{{this}}</paper-item>
|
|
||||||
{{/each}}
|
|
||||||
</core-menu>
|
|
||||||
</paper-dropdown>
|
|
||||||
</paper-dropdown-menu>
|
|
||||||
<!--damageBonus-->
|
<!--damageBonus-->
|
||||||
<paper-input id="damageInput"
|
<paper-input id="damageInput"
|
||||||
label="Damage Bonus"
|
label="Damage"
|
||||||
floatinglabel
|
floatinglabel
|
||||||
value={{damageBonus}}
|
value={{damage}}
|
||||||
flex></paper-input>
|
flex></paper-input>
|
||||||
<!--DamageType-->
|
<!--DamageType-->
|
||||||
<paper-dropdown-menu id="damageTypeDropdown" label="Damage Type">
|
<paper-dropdown-menu id="damageTypeDropdown" label="Damage Type">
|
||||||
|
|||||||
@@ -1,44 +1,50 @@
|
|||||||
var damageTypes = ["bludgeoning", "piercing", "slashing", "acid", "cold", "fire", "force", "lightning", "necrotic",
|
var damageTypes = [
|
||||||
"poison", "psychic", "radiant", "thunder"];
|
"bludgeoning",
|
||||||
|
"piercing",
|
||||||
|
"slashing",
|
||||||
|
"acid",
|
||||||
|
"cold",
|
||||||
|
"fire",
|
||||||
|
"force",
|
||||||
|
"lightning",
|
||||||
|
"necrotic",
|
||||||
|
"poison",
|
||||||
|
"psychic",
|
||||||
|
"radiant",
|
||||||
|
"thunder",
|
||||||
|
];
|
||||||
|
|
||||||
Template.attackEdit.events({
|
Template.attackEdit.events({
|
||||||
"tap #deleteAttack": function(event, instance){
|
"tap #deleteAttack": function(event, instance) {
|
||||||
Attacks.softRemoveNode(this._id);
|
Attacks.softRemoveNode(this._id);
|
||||||
GlobalUI.deletedToast(this._id, "Attacks", "Attack");
|
GlobalUI.deletedToast(this._id, "Attacks", "Attack");
|
||||||
},
|
},
|
||||||
"change #attackBonusInput": function(event){
|
"change #attackBonusInput": function(event) {
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Attacks.update(this._id, {$set: {attackBonus: value}});
|
Attacks.update(this._id, {$set: {attackBonus: value}});
|
||||||
},
|
},
|
||||||
"change #damageInput": function(event){
|
"change #damageInput": function(event) {
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Attacks.update(this._id, {$set: {damageBonus: value}});
|
Attacks.update(this._id, {$set: {damage: value}});
|
||||||
},
|
},
|
||||||
"change #detailInput": function(event){
|
"change #detailInput": function(event) {
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Attacks.update(this._id, {$set: {details: value}});
|
Attacks.update(this._id, {$set: {details: value}});
|
||||||
},
|
},
|
||||||
"core-select #damageTypeDropdown": function(event){
|
"core-select #damageTypeDropdown": function(event) {
|
||||||
var detail = event.originalEvent.detail;
|
var detail = event.originalEvent.detail;
|
||||||
if(!detail.isSelected) return;
|
if (!detail.isSelected) return;
|
||||||
var value = detail.item.getAttribute("name");
|
var value = detail.item.getAttribute("name");
|
||||||
if(value == this.damageType) return;
|
if (value == this.damageType) return;
|
||||||
Attacks.update(this._id, {$set: {damageType: value}});
|
Attacks.update(this._id, {$set: {damageType: value}});
|
||||||
},
|
},
|
||||||
"core-select #damageDiceDropdown": function(event){
|
|
||||||
var detail = event.originalEvent.detail;
|
|
||||||
if(!detail.isSelected) return;
|
|
||||||
var value = detail.item.getAttribute("name");
|
|
||||||
if(value == this.damageDice) return;
|
|
||||||
Attacks.update(this._id, {$set: {damageDice: value}});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.attackEdit.helpers({
|
Template.attackEdit.helpers({
|
||||||
damageTypes: function(){
|
damageTypes: function() {
|
||||||
return damageTypes;
|
return damageTypes;
|
||||||
},
|
},
|
||||||
DAMAGE_DICE: function(){
|
DAMAGE_DICE: function() {
|
||||||
return DAMAGE_DICE;
|
return DAMAGE_DICE;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!--needs to be given charId, parentId and type-->
|
<!--needs to be given charId, parentId and parentCollection-->
|
||||||
<template name="attackEditList">
|
<template name="attackEditList">
|
||||||
{{#if attacks.count}}
|
{{#if attacks.count}}
|
||||||
<hr style="margin: 16px 0 16px 0;">
|
<hr style="margin: 16px 0 16px 0;">
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
Template.attackEditList.helpers({
|
Template.attackEditList.helpers({
|
||||||
attacks: function(){
|
attacks: function() {
|
||||||
var cursor = Attacks.find({"parent.id": this.parentId, type: this.type, charId: this.charId});
|
var cursor = Attacks.find({"parent.id": this.parentId, charId: this.charId});
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.attackEditList.events({
|
Template.attackEditList.events({
|
||||||
"tap #addAttackButton": function(){
|
"tap #addAttackButton": function() {
|
||||||
Attacks.insert({
|
Attacks.insert({
|
||||||
charId: this.charId,
|
charId: this.charId,
|
||||||
parent: {
|
parent: {
|
||||||
id: this.parentId,
|
id: this.parentId,
|
||||||
collection: this.parentCollection
|
collection: this.parentCollection
|
||||||
},
|
}
|
||||||
type: this.type,
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<template name="attackView">
|
||||||
|
<div class="attackView" layout horizontal>
|
||||||
|
<div class="headline" style="margin-right: 16px;" layout horizontal center>
|
||||||
|
{{evaluateSigned charId attackBonus}}
|
||||||
|
</div>
|
||||||
|
<div layout vertical>
|
||||||
|
<div>
|
||||||
|
{{evaluateString charId damage}} {{damageType}}
|
||||||
|
</div>
|
||||||
|
{{#if details}}
|
||||||
|
<div class="caption">
|
||||||
|
{{details}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<template name="attacksViewList">
|
||||||
|
{{#if attacks.count}}
|
||||||
|
<hr style="margin: 16px 0 16px 0;">
|
||||||
|
<div class="attacks">
|
||||||
|
<h2 class="spaceAfter">Attacks</h2>
|
||||||
|
{{#each attacks}}
|
||||||
|
{{> attackView}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Template.attacksViewList.helpers({
|
||||||
|
attacks: function() {
|
||||||
|
return Attacks.find({"parent.id": this.parentId, charId: this.charId});
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<template name="buffDialog">
|
||||||
|
{{#with buff}}
|
||||||
|
{{#baseDialog title=name class=colorClass hideEdit=true}}
|
||||||
|
{{> buffDetails}}
|
||||||
|
{{/baseDialog}}
|
||||||
|
{{/with}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="buffDetails">
|
||||||
|
{{#if description}}
|
||||||
|
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{> effectsViewList charId=charId parentId=_id}}
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Template.buffDialog.helpers({
|
||||||
|
buff: function(){
|
||||||
|
return Buffs.findOne(this.buffId);
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,3 +1,26 @@
|
|||||||
<template name="characterSettings">
|
<template name="characterSettings">
|
||||||
|
{{#with character}}
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Hide Spells tab</td>
|
||||||
|
<td>
|
||||||
|
<paper-toggle-button id="hideSpellcasting"
|
||||||
|
checked={{settings.hideSpellcasting}}
|
||||||
|
touch-action="pan-y">
|
||||||
|
</paper-toggle-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Use variant encumbrance</td>
|
||||||
|
<td>
|
||||||
|
<paper-toggle-button id="variantEncumbrance"
|
||||||
|
checked={{settings.useVariantEncumbrance}}
|
||||||
|
touch-action="pan-y">
|
||||||
|
</paper-toggle-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{/with}}
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,3 +1,26 @@
|
|||||||
Template.characterSettings.events({
|
Template.characterSettings.helpers({
|
||||||
|
character: function() {
|
||||||
|
return Characters.findOne(this._id, {fields: {settings: 1}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.characterSettings.events({
|
||||||
|
"change #variantEncumbrance": function(event, instance){
|
||||||
|
var value = instance.find("#variantEncumbrance").checked;
|
||||||
|
if (this.settings.useVariantEncumbrance !== value){
|
||||||
|
Characters.update(
|
||||||
|
this._id,
|
||||||
|
{$set: {"settings.useVariantEncumbrance": value}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"change #hideSpellcasting": function(event, instance){
|
||||||
|
var value = instance.find("#hideSpellcasting").checked;
|
||||||
|
if (this.settings.hideSpellcasting !== value){
|
||||||
|
Characters.update(
|
||||||
|
this._id,
|
||||||
|
{$set: {"settings.hideSpellcasting": value}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
Template.deleteCharacterConfirmation.onCreated(function(){
|
Template.deleteCharacterConfirmation.onCreated(function() {
|
||||||
this.canDelete = new ReactiveVar(false);
|
this.canDelete = new ReactiveVar(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.deleteCharacterConfirmation.helpers({
|
Template.deleteCharacterConfirmation.helpers({
|
||||||
cantDelete: function(){
|
cantDelete: function() {
|
||||||
return !Template.instance().canDelete.get();
|
return !Template.instance().canDelete.get();
|
||||||
},
|
},
|
||||||
getStyle: function(){
|
getStyle: function() {
|
||||||
if(Template.instance().canDelete.get()) return "background: #d23f31; color: white;";
|
if (Template.instance().canDelete.get()) {
|
||||||
|
return "background: #d23f31; color: white;";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.deleteCharacterConfirmation.events({
|
Template.deleteCharacterConfirmation.events({
|
||||||
"change #nameInput, input #nameInput": function(event, instance){
|
"change #nameInput, input #nameInput": function(event, instance) {
|
||||||
var canDel = instance.find("#nameInput").value === this.name;
|
var canDel = instance.find("#nameInput").value === this.name;
|
||||||
instance.canDelete.set(canDel);
|
instance.canDelete.set(canDel);
|
||||||
},
|
},
|
||||||
"tap #deleteButton": function(event, instance){
|
"tap #deleteButton": function(event, instance) {
|
||||||
if(instance.find("#nameInput").value === this.name){
|
if (instance.find("#nameInput").value === this.name) {
|
||||||
GlobalUI.closeDialog();
|
GlobalUI.closeDialog();
|
||||||
Router.go("/");
|
Router.go("/");
|
||||||
Characters.remove(this._id);
|
Characters.remove(this._id);
|
||||||
|
|||||||
@@ -1,26 +1,42 @@
|
|||||||
<template name="shareDialog">
|
<template name="shareDialog">
|
||||||
<div>
|
<div style="width: 360px;">
|
||||||
<div>
|
<div>
|
||||||
<div class="subhead">
|
{{#if readers.count}}
|
||||||
Can View
|
<div style="font-weight: 500;">
|
||||||
</div>
|
Can View
|
||||||
{{#each readers}}
|
</div>
|
||||||
{{this}}<br>
|
{{#each readers}}
|
||||||
{{/each}}
|
<div layout horizontal center>
|
||||||
<div class="subhead">
|
<div flex>{{username}}</div>
|
||||||
Can Edit
|
<paper-icon-button class="deleteShare" icon="delete"></paper-icon-button>
|
||||||
</div>
|
</div>
|
||||||
{{#each writers}}
|
{{/each}}
|
||||||
{{this}}<br>
|
{{/if}}
|
||||||
{{/each}}
|
{{#if writers.count}}
|
||||||
|
<div style="font-weight: 500;">
|
||||||
|
Can Edit
|
||||||
|
</div>
|
||||||
|
{{#each writers}}
|
||||||
|
<div layout horizontal center>
|
||||||
|
<div flex>{{username}}</div>
|
||||||
|
<paper-icon-button class="deleteShare" icon="delete"></paper-icon-button>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<paper-input id="userNameOrEmailInput" label="Username or email" floatinglabel></paper-input><br>
|
<div layout horizontal center>
|
||||||
{{#if userFindError}}<p style="color: red;">{{userFindError}}</p>{{/if}}
|
<paper-input flex id="userNameOrEmailInput" label="Username or email" floatinglabel></paper-input>
|
||||||
|
<paper-button id="shareButton"
|
||||||
|
class="red-button"
|
||||||
|
style="width: 80px; height: 37px; margin-top: 16px;"
|
||||||
|
raised
|
||||||
|
disabled={{shareButtonDisabled}}>Share</paper-button>
|
||||||
|
</div>
|
||||||
|
<p style="color: red;">{{userFindError}}</p>
|
||||||
<paper-radio-group id="accessLevelMenu" selected="read">
|
<paper-radio-group id="accessLevelMenu" selected="read">
|
||||||
<paper-radio-button name="read" label="View Only"></paper-radio-button>
|
<paper-radio-button name="read" label="View Only"></paper-radio-button>
|
||||||
<paper-radio-button name="write" label="Can Edit"></paper-radio-button>
|
<paper-radio-button name="write" label="Can Edit"></paper-radio-button>
|
||||||
</paper-radio-group>
|
</paper-radio-group>
|
||||||
<br>
|
|
||||||
<paper-button id="shareButton" class="red-button" raised disabled={{shareButtonDisabled}}>Share</paper-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<paper-button id="doneButton" affirmative> Done </paper-button>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ Template.shareDialog.onCreated(function(){
|
|||||||
Template.shareDialog.helpers({
|
Template.shareDialog.helpers({
|
||||||
readers: function(){
|
readers: function(){
|
||||||
var char = Characters.findOne(this._id, {fields: {readers: 1}});
|
var char = Characters.findOne(this._id, {fields: {readers: 1}});
|
||||||
return char && char.readers;
|
return Meteor.users.find({_id: {$in: char.readers}});
|
||||||
},
|
},
|
||||||
writers: function(){
|
writers: function(){
|
||||||
var char = Characters.findOne(this._id, {fields: {writers: 1}});
|
var char = Characters.findOne(this._id, {fields: {writers: 1}});
|
||||||
return char && char.writers;
|
return Meteor.users.find({_id: {$in: char.writers}});
|
||||||
},
|
},
|
||||||
shareButtonDisabled: function(){
|
shareButtonDisabled: function(){
|
||||||
return !Template.instance().userId.get();
|
return !Template.instance().userId.get();
|
||||||
@@ -18,17 +18,18 @@ Template.shareDialog.helpers({
|
|||||||
if (!Template.instance().userId.get()){
|
if (!Template.instance().userId.get()){
|
||||||
return "User not found";
|
return "User not found";
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.shareDialog.events({
|
Template.shareDialog.events({
|
||||||
"input #userNameOrEmailInput, change #userNameOrEmailInput": function(event, instance){
|
"input #userNameOrEmailInput":
|
||||||
|
function(event, instance){
|
||||||
var userName = instance.find("#userNameOrEmailInput").value;
|
var userName = instance.find("#userNameOrEmailInput").value;
|
||||||
instance.userId.set(undefined);
|
instance.userId.set(undefined);
|
||||||
Meteor.call("getUserId", userName, function (err, result) {
|
Meteor.call("getUserId", userName, function(err, result) {
|
||||||
if(err){
|
if (err){
|
||||||
console.error(err);
|
console.error(err);
|
||||||
} else{
|
} else {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
instance.userId.set(result);
|
instance.userId.set(result);
|
||||||
}
|
}
|
||||||
@@ -37,19 +38,24 @@ Template.shareDialog.events({
|
|||||||
"tap #shareButton": function(event, instance){
|
"tap #shareButton": function(event, instance){
|
||||||
var self = this;
|
var self = this;
|
||||||
var permission = instance.find("#accessLevelMenu").selected;
|
var permission = instance.find("#accessLevelMenu").selected;
|
||||||
if(!permission) throw "no permission set";
|
if (!permission) throw "no permission set";
|
||||||
var userId = instance.userId.get();
|
var userId = instance.userId.get();
|
||||||
if(!userId) return;
|
if (!userId) return;
|
||||||
if(permission === "write"){
|
if (permission === "write"){
|
||||||
Characters.update(self._id, {
|
Characters.update(self._id, {
|
||||||
$addToSet: {writers: userId},
|
$addToSet: {writers: userId},
|
||||||
$pull: {readers: userId}
|
$pull: {readers: userId},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Characters.update(self._id, {
|
Characters.update(self._id, {
|
||||||
$addToSet: {readers: userId},
|
$addToSet: {readers: userId},
|
||||||
$pull: {writers: userId}
|
$pull: {writers: userId},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"tap .deleteShare": function(event, instance) {
|
||||||
|
Characters.update(instance.data._id, {
|
||||||
|
$pull: {writers: this._id, readers: this._id}
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
paper-tabs, core-toolbar {
|
paper-tabs, core-toolbar {
|
||||||
background-color: #795548;
|
|
||||||
box-shadow: 0px 3px 2px rgba(0, 0, 0, 0.2);
|
box-shadow: 0px 3px 2px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,18 +20,9 @@ paper-tabs ::shadow #ink {
|
|||||||
|
|
||||||
paper-tabs.transparent-brown {
|
paper-tabs.transparent-brown {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: #795548;
|
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
paper-tabs.transparent-brown::shadow #selectionBar {
|
|
||||||
background-color: #795548;
|
|
||||||
}
|
|
||||||
|
|
||||||
paper-tabs.transparent-brown paper-tab::shadow #ink {
|
|
||||||
color: #795548;
|
|
||||||
}
|
|
||||||
|
|
||||||
core-toolbar.medium-tall {
|
core-toolbar.medium-tall {
|
||||||
height: 108px;
|
height: 108px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,24 +5,35 @@
|
|||||||
<div flex>
|
<div flex>
|
||||||
{{name}}
|
{{name}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
{{#if canEditCharacter _id}}
|
||||||
{{> colorDropdown}}
|
<div>
|
||||||
</div>
|
{{> colorDropdown}}
|
||||||
<paper-menu-button>
|
</div>
|
||||||
<paper-icon-button icon="menu" noink></paper-icon-button>
|
<paper-menu-button>
|
||||||
<paper-dropdown class="dropdown" halign="right">
|
<paper-icon-button icon="more-vert" noink></paper-icon-button>
|
||||||
<core-menu class="menu" style="color: black; color: rgba(0,0,0,0.87);">
|
<paper-dropdown class="dropdown" halign="right">
|
||||||
<paper-item id="deleteCharacter"><core-icon icon="delete"></core-icon>Delete</paper-item>
|
<core-menu class="menu" style="color: black; color: rgba(0,0,0,0.87);">
|
||||||
<paper-item id="shareCharacter"><core-icon icon="social:share"></core-icon>Share</paper-item>
|
<paper-item id="deleteCharacter">
|
||||||
</core-menu>
|
<core-icon icon="delete"></core-icon>Delete
|
||||||
</paper-dropdown>
|
</paper-item>
|
||||||
</paper-menu-button>
|
<paper-item id="shareCharacter">
|
||||||
|
<core-icon icon="social:share"></core-icon>Share
|
||||||
|
</paper-item>
|
||||||
|
<paper-item id="characterSettings">
|
||||||
|
<core-icon icon="settings"></core-icon>Settings
|
||||||
|
</paper-item>
|
||||||
|
</core-menu>
|
||||||
|
</paper-dropdown>
|
||||||
|
</paper-menu-button>
|
||||||
|
{{/if}}
|
||||||
<div class="bottom fit" horizontal layout>
|
<div class="bottom fit" horizontal layout>
|
||||||
<paper-tabs flex horizontal center layout id="characterSheetTabs" selected={{selectedTab}} class="{{colorClass}}">
|
<paper-tabs flex horizontal center layout id="characterSheetTabs" selected={{selectedTab}} class="{{colorClass}}">
|
||||||
<paper-tab name="stats">Stats</paper-tab>
|
<paper-tab name="stats">Stats</paper-tab>
|
||||||
<paper-tab name="features">Features</paper-tab>
|
<paper-tab name="features">Features</paper-tab>
|
||||||
<paper-tab name="inventory">Inventory</paper-tab>
|
<paper-tab name="inventory">Inventory</paper-tab>
|
||||||
|
{{#unless hideSpellcasting}}
|
||||||
<paper-tab name="spells">Spells</paper-tab>
|
<paper-tab name="spells">Spells</paper-tab>
|
||||||
|
{{/unless}}
|
||||||
<paper-tab name="persona">Persona</paper-tab>
|
<paper-tab name="persona">Persona</paper-tab>
|
||||||
<paper-tab name="journal">Journal</paper-tab>
|
<paper-tab name="journal">Journal</paper-tab>
|
||||||
</paper-tabs>
|
</paper-tabs>
|
||||||
@@ -33,7 +44,9 @@
|
|||||||
<section flex name="stats">{{> stats}}</section>
|
<section flex name="stats">{{> stats}}</section>
|
||||||
<section flex name="features">{{> features}}</section>
|
<section flex name="features">{{> features}}</section>
|
||||||
<section flex name="inventory">{{> inventory}}</section>
|
<section flex name="inventory">{{> inventory}}</section>
|
||||||
|
{{#unless hideSpellcasting}}
|
||||||
<section flex name="spells">{{> spells}}</section>
|
<section flex name="spells">{{> spells}}</section>
|
||||||
|
{{/unless}}
|
||||||
<section flex name="persona">{{> persona}}</section>
|
<section flex name="persona">{{> persona}}</section>
|
||||||
<section flex name="journal">{{> journal}}</section>
|
<section flex name="journal">{{> journal}}</section>
|
||||||
</core-animated-pages>
|
</core-animated-pages>
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
Template.characterSheet.created = function(){
|
Template.characterSheet.onCreated(function() {
|
||||||
|
//default to the first tab
|
||||||
Session.setDefault(this.data._id + ".selectedTab", "stats");
|
Session.setDefault(this.data._id + ".selectedTab", "stats");
|
||||||
};
|
//watch this character and make sure their encumbrance is updated
|
||||||
|
trackEncumbranceConditions(this.data._id, this);
|
||||||
|
});
|
||||||
|
|
||||||
var setTab = function(charId, tab){
|
var setTab = function(charId, tab){
|
||||||
return Session.set(charId + ".selectedTab", tab);
|
return Session.set(charId + ".selectedTab", tab);
|
||||||
@@ -13,6 +16,10 @@ var getTab = function(charId){
|
|||||||
Template.characterSheet.helpers({
|
Template.characterSheet.helpers({
|
||||||
selectedTab: function(){
|
selectedTab: function(){
|
||||||
return getTab(this._id);
|
return getTab(this._id);
|
||||||
|
},
|
||||||
|
hideSpellcasting: function() {
|
||||||
|
var char = Characters.findOne(this._id);
|
||||||
|
return char && char.settings.hideSpellcasting;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -40,4 +47,11 @@ Template.characterSheet.events({
|
|||||||
template: "shareDialog",
|
template: "shareDialog",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
"tap #characterSettings": function(event, instance){
|
||||||
|
GlobalUI.showDialog({
|
||||||
|
heading: this.name + " Settings",
|
||||||
|
data: this,
|
||||||
|
template: "characterSettings",
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,21 +1,13 @@
|
|||||||
body /deep/ #statGroupDropDown {
|
html /deep/ .operationDropDown {
|
||||||
width: 120px;
|
width: 152px;
|
||||||
}
|
}
|
||||||
|
|
||||||
body /deep/ #statDropDown {
|
html /deep/ .statDropDown {
|
||||||
width: 120px;
|
width: 152px;
|
||||||
}
|
}
|
||||||
|
|
||||||
body /deep/ #operationDropDown {
|
html /deep/ .damageMultiplierDropDown {
|
||||||
width: 100px;
|
width: 152px;
|
||||||
}
|
|
||||||
|
|
||||||
body /deep/ #damageMultiplierDropDown {
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body /deep/ #proficiencyDropDown {
|
|
||||||
width: 120px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html /deep/ .effectEdit paper-input {
|
html /deep/ .effectEdit paper-input {
|
||||||
@@ -24,6 +16,7 @@ html /deep/ .effectEdit paper-input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
html /deep/ .effectEdit {
|
html /deep/ .effectEdit {
|
||||||
|
height: 64px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,23 @@
|
|||||||
<template name="effectEdit">
|
<template name="effectEdit">
|
||||||
<div class="effectEdit" layout horizontal center>
|
<div class="effectEdit" layout horizontal center>
|
||||||
<paper-dropdown-menu class="statGroupDropDown" label="Stat Group" flex>
|
<paper-dropdown-menu class="statDropDown"
|
||||||
<paper-dropdown layered class="dropdown">
|
label="Stat">
|
||||||
<core-menu class="menu statGroupMenu" selected={{selectedStatGroup}}>
|
<paper-dropdown layered
|
||||||
{{#each statGroups}}
|
class="dropdown">
|
||||||
<paper-item class="statGroupSelect" name={{this}}>{{this}}</paper-item>
|
<core-menu class="menu statMenu" selected={{stat}}>
|
||||||
{{/each}}
|
{{#each statGroups}}
|
||||||
</core-menu>
|
<div style="font-weight: bold;
|
||||||
</paper-dropdown>
|
margin-top: 16px;">{{this}}</div>
|
||||||
</paper-dropdown-menu>
|
{{#each stats}}
|
||||||
{{#if stats}}
|
<paper-item name={{stat}}>{{name}}</paper-item>
|
||||||
<paper-dropdown-menu class="statDropDown" label="Stat" flex>
|
{{/each}}
|
||||||
<paper-dropdown layered class="dropdown">
|
|
||||||
<core-menu class="menu statMenu" selected={{stat}} on-tap="onStatMenuTap">
|
|
||||||
{{#each stats}}
|
|
||||||
<paper-item name={{stat}}>{{name}}</paper-item>
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</core-menu>
|
</core-menu>
|
||||||
</paper-dropdown>
|
</paper-dropdown>
|
||||||
</paper-dropdown-menu>
|
</paper-dropdown-menu>
|
||||||
{{/if}}
|
|
||||||
{{#if operations}}
|
{{#if operations}}
|
||||||
<paper-dropdown-menu class="operationDropDown" label="Operation" flex>
|
<paper-dropdown-menu class="operationDropDown"
|
||||||
|
label="Operation">
|
||||||
<paper-dropdown layered class="dropdown">
|
<paper-dropdown layered class="dropdown">
|
||||||
<core-menu class="menu operationMenu" selected={{operation}}>
|
<core-menu class="menu operationMenu" selected={{operation}}>
|
||||||
{{#each operations}}
|
{{#each operations}}
|
||||||
@@ -31,36 +27,39 @@
|
|||||||
</paper-dropdown>
|
</paper-dropdown>
|
||||||
</paper-dropdown-menu>
|
</paper-dropdown-menu>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{> Template.dynamic template=effectValueTemplate}}
|
{{#if effectValueTemplate}}
|
||||||
<paper-icon-button class="deleteEffect" role="button" tabindex="0" icon="delete" aria-label="Delete"></paper-icon-button>
|
{{> Template.dynamic template=effectValueTemplate}}
|
||||||
|
{{else}}
|
||||||
|
<div flex></div>
|
||||||
|
{{/if}}
|
||||||
|
<paper-icon-button class="deleteEffect"
|
||||||
|
icon="delete">
|
||||||
|
</paper-icon-button>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="regularEffectValue">
|
<template name="regularEffectValue">
|
||||||
<paper-input class="effectValueInput" label="Value" floatinglabel value={{effectValue}} flex></paper-input>
|
<paper-input class="effectValueInput"
|
||||||
|
label="Value"
|
||||||
|
floatinglabel
|
||||||
|
value={{effectValue}}
|
||||||
|
flex>
|
||||||
|
</paper-input>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="multiplierEffectValue">
|
<template name="multiplierEffectValue">
|
||||||
<paper-dropdown-menu class="damageMultiplierDropDown" label="Damage Multiplier" flex>
|
<paper-dropdown-menu class="damageMultiplierDropDown"
|
||||||
<paper-dropdown layered class="dropdown">
|
label="Damage Multiplier">
|
||||||
<core-menu class="menu multiplierMenu" selected={{value}}>
|
<paper-dropdown layered
|
||||||
|
class="dropdown">
|
||||||
|
<core-menu class="menu multiplierMenu"
|
||||||
|
selected={{value}}>
|
||||||
<paper-item name="0.5">Resistance</paper-item>
|
<paper-item name="0.5">Resistance</paper-item>
|
||||||
<paper-item name="2">Vulnerability</paper-item>
|
<paper-item name="2">Vulnerability</paper-item>
|
||||||
<paper-item name="0">Immunity</paper-item>
|
<paper-item name="0">Immunity</paper-item>
|
||||||
</core-menu>
|
</core-menu>
|
||||||
</paper-dropdown>
|
</paper-dropdown>
|
||||||
</paper-dropdown-menu>
|
</paper-dropdown-menu>
|
||||||
|
<div flex></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="proficiencyEffectValue">
|
|
||||||
<paper-dropdown-menu class="proficiencyDropDown" label="Proficiency" flex>
|
|
||||||
<paper-dropdown layered class="dropdown">
|
|
||||||
<core-menu class="menu proficiencyMenu" selected={{value}}>
|
|
||||||
<paper-item name="1">Proficient</paper-item>
|
|
||||||
<paper-item name="0.5">Half Prof. Bonus</paper-item>
|
|
||||||
<paper-item name="2">Double Prof. Bonus</paper-item>
|
|
||||||
</core-menu>
|
|
||||||
</paper-dropdown>
|
|
||||||
</paper-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
@@ -82,7 +82,6 @@ var attributeOperations = [
|
|||||||
{name: "Max", operation: "max"}
|
{name: "Max", operation: "max"}
|
||||||
];
|
];
|
||||||
var skillOperations = [
|
var skillOperations = [
|
||||||
{name: "Proficiency", operation: "proficiency"},
|
|
||||||
{name: "Add", operation: "add"},
|
{name: "Add", operation: "add"},
|
||||||
{name: "Multiply", operation: "mul"},
|
{name: "Multiply", operation: "mul"},
|
||||||
{name: "Min", operation: "min"},
|
{name: "Min", operation: "min"},
|
||||||
@@ -94,26 +93,19 @@ var skillOperations = [
|
|||||||
{name: "Conditional Benefit", operation: "conditional"}
|
{name: "Conditional Benefit", operation: "conditional"}
|
||||||
];
|
];
|
||||||
|
|
||||||
Template.effectEdit.created = function(){
|
|
||||||
var statGroup = statsDict[this.data.stat] && statsDict[this.data.stat].group;
|
|
||||||
this.selectedStatGroup = new ReactiveVar(statGroup);
|
|
||||||
};
|
|
||||||
|
|
||||||
Template.effectEdit.helpers({
|
Template.effectEdit.helpers({
|
||||||
selectedStatGroup: function(){
|
|
||||||
return Template.instance().selectedStatGroup.get();
|
|
||||||
},
|
|
||||||
statGroups: function(){
|
statGroups: function(){
|
||||||
return statGroupNames;
|
return statGroupNames;
|
||||||
},
|
},
|
||||||
stats: function(){
|
stats: function(){
|
||||||
var group = Template.instance().selectedStatGroup.get();
|
var group = this;
|
||||||
return statGroups[group];
|
return statGroups[group];
|
||||||
},
|
},
|
||||||
operations: function(){
|
operations: function(){
|
||||||
var group = Template.instance().selectedStatGroup.get();
|
var stat = statsDict[this.stat];
|
||||||
if(group === "Weakness/Resistance") return null;
|
var group = stat && stat.group;
|
||||||
if(group === "Saving Throws" || group === "Skills"){
|
if (group === "Weakness/Resistance") return null;
|
||||||
|
if (group === "Saving Throws" || group === "Skills"){
|
||||||
return skillOperations;
|
return skillOperations;
|
||||||
} else {
|
} else {
|
||||||
return attributeOperations;
|
return attributeOperations;
|
||||||
@@ -121,15 +113,14 @@ Template.effectEdit.helpers({
|
|||||||
},
|
},
|
||||||
effectValueTemplate: function(){
|
effectValueTemplate: function(){
|
||||||
//resistance/vulnerability template
|
//resistance/vulnerability template
|
||||||
var group = Template.instance().selectedStatGroup.get();
|
var stat = statsDict[this.stat];
|
||||||
if(group === "Weakness/Resistance") return "multiplierEffectValue";
|
var group = stat && stat.group;
|
||||||
|
if (group === "Weakness/Resistance") return "multiplierEffectValue";
|
||||||
|
|
||||||
var op = this.operation;
|
var op = this.operation;
|
||||||
if(!op) return null;
|
if (!op) return null;
|
||||||
//operations that don't need templates
|
//operations that don't need templates
|
||||||
if(op === "advantage" || op === "disadvantage" || op === "fail") return null;
|
if (op === "advantage" || op === "disadvantage" || op === "fail") return null;
|
||||||
//proficiency template
|
|
||||||
if(op === "proficiency") return "proficiencyEffectValue";
|
|
||||||
|
|
||||||
//default template
|
//default template
|
||||||
return "regularEffectValue";
|
return "regularEffectValue";
|
||||||
@@ -147,54 +138,35 @@ Template.effectEdit.events({
|
|||||||
Effects.softRemoveNode(this._id);
|
Effects.softRemoveNode(this._id);
|
||||||
GlobalUI.deletedToast(this._id, "Effects", "Effect");
|
GlobalUI.deletedToast(this._id, "Effects", "Effect");
|
||||||
},
|
},
|
||||||
"core-select .statGroupDropDown": function(event, instance){
|
|
||||||
var detail = event.originalEvent.detail;
|
|
||||||
if(!detail.isSelected) return;
|
|
||||||
var groupName = detail.item.getAttribute("name");
|
|
||||||
var oldName = Template.instance().selectedStatGroup.get();
|
|
||||||
if(oldName != groupName){
|
|
||||||
instance.selectedStatGroup.set(groupName);
|
|
||||||
if(groupName === "Skills" || groupName === "Saving Throws"){
|
|
||||||
Effects.update(this._id, {$set: {operation: "proficiency", value: 1, calculation: ""}, $unset: {stat: ""} });
|
|
||||||
} else if(groupName === "Weakness/Resistance"){
|
|
||||||
Effects.update(this._id, {$set: {value: 0.5, calculation: "", operation: "mul"}, $unset: {stat: ""} });
|
|
||||||
} else {
|
|
||||||
Effects.update(this._id, { $set: {operation: "add"}, $unset: {stat: "", value: "", calculation: ""} });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"core-select .statDropDown": function(event){
|
"core-select .statDropDown": function(event){
|
||||||
var detail = event.originalEvent.detail;
|
var detail = event.originalEvent.detail;
|
||||||
if(!detail.isSelected) return;
|
if (!detail.isSelected) return;
|
||||||
var statName = detail.item.getAttribute("name");
|
var statName = detail.item.getAttribute("name");
|
||||||
if (statName == this.stat) return;
|
if (statName == this.stat) return;
|
||||||
Effects.update(this._id, {$set: {stat: statName}});
|
Effects.update(this._id, {$set: {stat: statName}});
|
||||||
},
|
},
|
||||||
"core-select .operationDropDown": function(event){
|
"core-select .operationDropDown": function(event){
|
||||||
var detail = event.originalEvent.detail;
|
var detail = event.originalEvent.detail;
|
||||||
if(!detail.isSelected) return;
|
if (!detail.isSelected) return;
|
||||||
var opName = detail.item.getAttribute("name");
|
var opName = detail.item.getAttribute("name");
|
||||||
if (opName == this.operation) return;
|
if (opName == this.operation) return;
|
||||||
Effects.update(this._id, {$set: {operation: opName}});
|
Effects.update(this._id, {$set: {operation: opName}});
|
||||||
},
|
},
|
||||||
"core-select .damageMultiplierDropDown": function(event){
|
"core-select .damageMultiplierDropDown": function(event){
|
||||||
var detail = event.originalEvent.detail;
|
var detail = event.originalEvent.detail;
|
||||||
if(!detail.isSelected) return;
|
if (!detail.isSelected) return;
|
||||||
var value = +detail.item.getAttribute("name");
|
var value = +detail.item.getAttribute("name");
|
||||||
if (value == this.value) return;
|
if (value == this.value) return;
|
||||||
Effects.update(this._id, {$set: {value: value, calculation: "", operation: "mul"}});
|
Effects.update(this._id, {$set: {
|
||||||
},
|
value: value,
|
||||||
"core-select .proficiencyDropDown": function(event){
|
calculation: "",
|
||||||
var detail = event.originalEvent.detail;
|
operation: "mul"
|
||||||
if(!detail.isSelected) return;
|
}});
|
||||||
var value = +detail.item.getAttribute("name");
|
|
||||||
if (value == this.value) return;
|
|
||||||
Effects.update(this._id, {$set: {value: value, calculation: ""}});
|
|
||||||
},
|
},
|
||||||
"change .effectValueInput": function(event){
|
"change .effectValueInput": function(event){
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
var numValue = +value;
|
var numValue = +value;
|
||||||
if(_.isFinite(numValue)){
|
if (_.isFinite(numValue)){
|
||||||
if (this.value === numValue) return;
|
if (this.value === numValue) return;
|
||||||
Effects.update(this._id, {$set: {value: numValue, calculation: ""}});
|
Effects.update(this._id, {$set: {value: numValue, calculation: ""}});
|
||||||
} else if (_.isString(value)){
|
} else if (_.isString(value)){
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
<template name="effectView">
|
<template name="effectView">
|
||||||
<div class="effectView" layout horizontal center>
|
<tr>
|
||||||
{{#with statName}}
|
<td>{{statName}}</td>
|
||||||
<div flex>{{statName}}</div>
|
<td>{{operationName}}{{statValue}}</td>
|
||||||
{{else}}
|
</tr>
|
||||||
<div flex>{{sourceName}}</div>
|
|
||||||
{{/with}}
|
|
||||||
<div>{{operationName}}</div>
|
|
||||||
<div>{{statValue}}</div>
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -6,35 +6,35 @@ var stats = {
|
|||||||
"intelligence":{"name":"Intelligence"},
|
"intelligence":{"name":"Intelligence"},
|
||||||
"wisdom":{"name":"Wisdom"},
|
"wisdom":{"name":"Wisdom"},
|
||||||
"charisma":{"name":"Charisma"},
|
"charisma":{"name":"Charisma"},
|
||||||
"strengthSave":{"name":"Strength Save",},
|
"strengthSave":{"name":"Strength Save"},
|
||||||
"dexteritySave":{"name":"Dexterity Save",},
|
"dexteritySave":{"name":"Dexterity Save"},
|
||||||
"constitutionSave":{"name":"Constitution Save",},
|
"constitutionSave":{"name":"Constitution Save"},
|
||||||
"intelligenceSave":{"name":"Intelligence Save",},
|
"intelligenceSave":{"name":"Intelligence Save"},
|
||||||
"wisdomSave":{"name":"Wisdom Save",},
|
"wisdomSave":{"name":"Wisdom Save"},
|
||||||
"charismaSave":{"name":"Charisma Save",},
|
"charismaSave":{"name":"Charisma Save"},
|
||||||
"acrobatics":{"name":"Acrobatics",},
|
"acrobatics":{"name":"Acrobatics"},
|
||||||
"animalHandling":{"name":"Animal Handling",},
|
"animalHandling":{"name":"Animal Handling"},
|
||||||
"arcana":{"name":"Arcana",},
|
"arcana":{"name":"Arcana"},
|
||||||
"athletics":{"name":"Athletics",},
|
"athletics":{"name":"Athletics"},
|
||||||
"deception":{"name":"Deception",},
|
"deception":{"name":"Deception"},
|
||||||
"history":{"name":"History",},
|
"history":{"name":"History"},
|
||||||
"insight":{"name":"Insight",},
|
"insight":{"name":"Insight"},
|
||||||
"intimidation":{"name":"Intimidation",},
|
"intimidation":{"name":"Intimidation"},
|
||||||
"investigation":{"name":"Investigation",},
|
"investigation":{"name":"Investigation"},
|
||||||
"medicine":{"name":"Medicine",},
|
"medicine":{"name":"Medicine"},
|
||||||
"nature":{"name":"Nature",},
|
"nature":{"name":"Nature"},
|
||||||
"perception":{"name":"Perception",},
|
"perception":{"name":"Perception"},
|
||||||
"performance":{"name":"Performance",},
|
"performance":{"name":"Performance"},
|
||||||
"persuasion":{"name":"Persuasion",},
|
"persuasion":{"name":"Persuasion"},
|
||||||
"religion":{"name":"Religion",},
|
"religion":{"name":"Religion"},
|
||||||
"sleightOfHand":{"name":"Sleight of Hand",},
|
"sleightOfHand":{"name":"Sleight of Hand"},
|
||||||
"stealth":{"name":"Stealth",},
|
"stealth":{"name":"Stealth"},
|
||||||
"survival":{"name":"Survival",},
|
"survival":{"name":"Survival"},
|
||||||
"initiative":{"name":"Initiative",},
|
"initiative":{"name":"Initiative"},
|
||||||
"hitPoints":{"name":"Hit Points"},
|
"hitPoints":{"name":"Hit Points"},
|
||||||
"armor":{"name":"Armor"},
|
"armor":{"name":"Armor"},
|
||||||
"dexterityArmor":{"name":"Dexterity Armor Bonus"}
|
"dexterityArmor":{"name":"Dexterity Armor Bonus"},
|
||||||
,"speed":{"name":"Speed"},
|
"speed":{"name":"Speed"},
|
||||||
"proficiencyBonus":{"name":"Proficiency Bonus"},
|
"proficiencyBonus":{"name":"Proficiency Bonus"},
|
||||||
"ki":{"name":"Ki Points"},
|
"ki":{"name":"Ki Points"},
|
||||||
"sorceryPoints":{"name":"Sorcery Points"},
|
"sorceryPoints":{"name":"Sorcery Points"},
|
||||||
@@ -55,40 +55,63 @@ var stats = {
|
|||||||
"d8HitDice":{"name":"d8 Hit Dice"},
|
"d8HitDice":{"name":"d8 Hit Dice"},
|
||||||
"d10HitDice":{"name":"d10 Hit Dice"},
|
"d10HitDice":{"name":"d10 Hit Dice"},
|
||||||
"d12HitDice":{"name":"d12 Hit Dice"},
|
"d12HitDice":{"name":"d12 Hit Dice"},
|
||||||
"acidMultiplier":{"name":"Acid", "group": "Weakness/Resistance"},
|
"acidMultiplier":{"name":"Acid damage", "group": "Weakness/Resistance"},
|
||||||
"bludgeoningMultiplier":{"name":"Bludgeoning", "group": "Weakness/Resistance"},
|
"bludgeoningMultiplier":{
|
||||||
"coldMultiplier":{"name":"Cold", "group": "Weakness/Resistance"},
|
"name":"Bludgeoning damage", "group": "Weakness/Resistance",
|
||||||
"fireMultiplier":{"name":"Fire", "group": "Weakness/Resistance"},
|
},
|
||||||
"forceMultiplier":{"name":"Force", "group": "Weakness/Resistance"},
|
"coldMultiplier":{
|
||||||
"lightningMultiplier":{"name":"Lightning", "group": "Weakness/Resistance"},
|
"name":"Cold damage", "group": "Weakness/Resistance",
|
||||||
"necroticMultiplier":{"name":"Necrotic", "group": "Weakness/Resistance"},
|
},
|
||||||
"piercingMultiplier":{"name":"Piercing", "group": "Weakness/Resistance"},
|
"fireMultiplier":{
|
||||||
"poisonMultiplier":{"name":"Poison", "group": "Weakness/Resistance"},
|
"name":"Fire damage", "group": "Weakness/Resistance",
|
||||||
"psychicMultiplier":{"name":"Psychic", "group": "Weakness/Resistance"},
|
},
|
||||||
"radiantMultiplier":{"name":"Radiant", "group": "Weakness/Resistance"},
|
"forceMultiplier":{
|
||||||
"slashingMultiplier":{"name":"Slashing", "group": "Weakness/Resistance"},
|
"name":"Force damage", "group": "Weakness/Resistance",
|
||||||
"thunderMultiplier":{"name":"Thunder", "group": "Weakness/Resistance"}
|
},
|
||||||
|
"lightningMultiplier":{
|
||||||
|
"name":"Lightning damage", "group": "Weakness/Resistance",
|
||||||
|
},
|
||||||
|
"necroticMultiplier":{
|
||||||
|
"name":"Necrotic damage", "group": "Weakness/Resistance",
|
||||||
|
},
|
||||||
|
"piercingMultiplier":{
|
||||||
|
"name":"Piercing damage", "group": "Weakness/Resistance",
|
||||||
|
},
|
||||||
|
"poisonMultiplier":{
|
||||||
|
"name":"Poison damage", "group": "Weakness/Resistance",
|
||||||
|
},
|
||||||
|
"psychicMultiplier":{
|
||||||
|
"name":"Psychic damage", "group": "Weakness/Resistance",
|
||||||
|
},
|
||||||
|
"radiantMultiplier":{
|
||||||
|
"name":"Radiant damage", "group": "Weakness/Resistance",
|
||||||
|
},
|
||||||
|
"slashingMultiplier":{
|
||||||
|
"name":"Slashing damage", "group": "Weakness/Resistance",
|
||||||
|
},
|
||||||
|
"thunderMultiplier":{
|
||||||
|
"name":"Thunder damage", "group": "Weakness/Resistance",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var operations = {
|
var operations = {
|
||||||
base: {name: "Base Value"},
|
base: {name: "Base Value: "},
|
||||||
proficiency: {name: "Proficiency"},
|
proficiency: {name: "Proficiency"},
|
||||||
add: {name: "Add"},
|
add: {name: "+"},
|
||||||
mul: {name: "Multiply"},
|
mul: {name: "x"},
|
||||||
min: {name: "Min"},
|
min: {name: "Min: "},
|
||||||
max: {name: "Max"},
|
max: {name: "Max: "},
|
||||||
advantage: {name: "Advantage"},
|
advantage: {name: "Advantage"},
|
||||||
disadvantage: {name: "Disadvantage"},
|
disadvantage: {name: "Disadvantage"},
|
||||||
passiveAdd: {name: "Passive Bonus"},
|
passiveAdd: {name: "Passive Bonus: "},
|
||||||
fail: {name: "Automatically Fail"},
|
fail: {name: "Automatically Fail"},
|
||||||
conditional: {name: "Conditional Benefit"}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Template.effectView.helpers({
|
Template.effectView.helpers({
|
||||||
sourceName: function(){
|
sourceName: function(){
|
||||||
var id = this.parent.id;
|
var id = this.parent.id;
|
||||||
if(!id) return;
|
if (!id) return;
|
||||||
switch(this.parent.collection){
|
switch (this.parent.collection){
|
||||||
case "Features":
|
case "Features":
|
||||||
return "Feature - " + Features.findOne(id, {fields: {name: 1}}).name;
|
return "Feature - " + Features.findOne(id, {fields: {name: 1}}).name;
|
||||||
case "Classes":
|
case "Classes":
|
||||||
@@ -100,34 +123,46 @@ Template.effectView.helpers({
|
|||||||
case "Characters":
|
case "Characters":
|
||||||
return Characters.findOne(this.charId, {fields: {race: 1}}).race;
|
return Characters.findOne(this.charId, {fields: {race: 1}}).race;
|
||||||
default:
|
default:
|
||||||
return "Inate"
|
return "Inate";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
statName: function(){
|
statName: function(){
|
||||||
return stats[this.stat] && stats[this.stat].name || "No Stat"
|
return stats[this.stat] && stats[this.stat].name || "No Stat";
|
||||||
},
|
},
|
||||||
operationName: function(){
|
operationName: function(){
|
||||||
if(this.operation === "proficiency") return null;
|
if (this.operation === "proficiency" ||
|
||||||
if(stats[this.stat].group === "Weakness/Resistance") return null;
|
this.operation === "conditional") return null;
|
||||||
return operations[this.operation] && operations[this.operation].name || "No Operation"
|
if (stats[this.stat] && stats[this.stat].group === "Weakness/Resistance")
|
||||||
|
return null;
|
||||||
|
if (this.operation === "add" && evaluateEffect(this.charId, this) < 0)
|
||||||
|
return null;
|
||||||
|
return operations[this.operation] &&
|
||||||
|
operations[this.operation].name || "No Operation";
|
||||||
},
|
},
|
||||||
statValue: function(){
|
statValue: function(){
|
||||||
if(this.operation === "advantage" ||
|
if (this.operation === "advantage" ||
|
||||||
this.operation === "disadvantage" ||
|
this.operation === "disadvantage" ||
|
||||||
this.operation === "fail" ||
|
this.operation === "fail"){
|
||||||
this.operation === "conditional"){
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if(this.operation === "proficiency"){
|
if (this.operation === "proficiency"){
|
||||||
if(this.value == 0.5 || this.calculation == 0.5) return "Half Proficiency";
|
if (this.value == 0.5 || this.calculation == 0.5)
|
||||||
if(this.value == 1 || this.calculation == 1) return "Proficiency";
|
return "Half Proficiency";
|
||||||
if(this.value == 2 || this.calculation == 2) return "Double Proficiency";
|
if (this.value == 1 || this.calculation == 1)
|
||||||
|
return "Proficiency";
|
||||||
|
if (this.value == 2 || this.calculation == 2)
|
||||||
|
return "Double Proficiency";
|
||||||
}
|
}
|
||||||
if(stats[this.stat].group === "Weakness/Resistance"){
|
if (this.operation === "conditional"){
|
||||||
if(this.value == 0.5 || this.calculation == 0.5) return "Resistance";
|
return this.calculation || this.value;
|
||||||
if(this.value == 2 || this.calculation == 2) return "Vulnerability";
|
|
||||||
if(this.value == 0 || this.calculation == 0) return "Immunity";
|
|
||||||
}
|
}
|
||||||
|
if (stats[this.stat] && stats[this.stat].group === "Weakness/Resistance"){
|
||||||
|
if (this.value === 0.5) return "Resistance";
|
||||||
|
if (this.value === 2) return "Vulnerability";
|
||||||
|
if (this.value === 0) return "Immunity";
|
||||||
|
}
|
||||||
|
var value = evaluateEffect(this.charId, this);
|
||||||
|
if (_.isNumber(value)) return value;
|
||||||
return this.calculation || this.value;
|
return this.calculation || this.value;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<!--needs to be given charId, parentId, parentCollection and type-->
|
<!--needs to be given charId, parentId and parentCollection-->
|
||||||
<template name="effectsEditList">
|
<template name="effectsEditList">
|
||||||
{{#if effects.count}}
|
{{#if effects.count}}
|
||||||
<hr style="margin: 16px 0 16px 0;">
|
<hr class="vertMargin">
|
||||||
<div id="effects">
|
<div id="effects">
|
||||||
<h2>Effects</h2>
|
<h2>Effects</h2>
|
||||||
{{#each effects}}
|
{{#each effects}}
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
Template.effectsEditList.helpers({
|
Template.effectsEditList.helpers({
|
||||||
effects: function(){
|
effects: function(){
|
||||||
var cursor = Effects.find({"parent.id": this.parentId, "parent.collection": this.parentCollection, type: this.type});
|
var selector = {
|
||||||
|
"parent.id": this.parentId,
|
||||||
|
"parent.collection": this.parentCollection,
|
||||||
|
"charId": this.charId,
|
||||||
|
};
|
||||||
|
if (this.parentGroup){
|
||||||
|
selector["parent.group"] = this.parentGroup;
|
||||||
|
}
|
||||||
|
var cursor = Effects.find(selector);
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.effectsEditList.events({
|
Template.effectsEditList.events({
|
||||||
"tap #addEffectButton": function(){
|
"tap #addEffectButton": function(){
|
||||||
if ( !_.isBoolean(this.enabled) ) {
|
if (!_.isBoolean(this.enabled)) {
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
}
|
}
|
||||||
Effects.insert({
|
Effects.insert({
|
||||||
@@ -15,11 +23,11 @@ Template.effectsEditList.events({
|
|||||||
charId: this.charId,
|
charId: this.charId,
|
||||||
parent: {
|
parent: {
|
||||||
id: this.parentId,
|
id: this.parentId,
|
||||||
collection: this.parentCollection
|
collection: this.parentCollection,
|
||||||
|
group: this.parentGroup,
|
||||||
},
|
},
|
||||||
operation: "add",
|
operation: "add",
|
||||||
type: this.type,
|
enabled: this.enabled,
|
||||||
enabled: this.enabled
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
<!--needs to be given charId, (parentId or stat) and type-->
|
<!--needs to be given charId, (parentId or stat) and type-->
|
||||||
<template name="effectsViewList">
|
<template name="effectsViewList">
|
||||||
{{#if effects}}
|
{{#if effects.count}}
|
||||||
<hr style="margin: 16px 0 16px 0;">
|
<hr style="margin: 16px 0 16px 0;">
|
||||||
<div id="effects">
|
<div class="effects">
|
||||||
<h2>Effects</h2>
|
<h2 class="spaceAfter">Effects</h2>
|
||||||
{{#each effects}}
|
<table class="wideTable">
|
||||||
{{>effectView}}
|
{{#each effects}}
|
||||||
{{/each}}
|
{{>effectView}}
|
||||||
|
{{/each}}
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
Template.effectsViewList.helpers({
|
Template.effectsViewList.helpers({
|
||||||
effects: function(){
|
effects: function(){
|
||||||
if(this.parentId){
|
var selector = {
|
||||||
return Effects.find({"parent.id": this.parentId, type: this.type, charId: this.charId}, {fields: {parent: 0}});
|
"parent.id": this.parentId,
|
||||||
} else if(this.stat){
|
"charId": this.charId
|
||||||
return Effects.find({charId: this.charId, stat: this.stat});
|
};
|
||||||
|
if (this.parentGroup){
|
||||||
|
selector["parent.group"] = this.parentGroup;
|
||||||
}
|
}
|
||||||
|
return Effects.find(selector, {fields: {parent: 0}});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,40 +1,85 @@
|
|||||||
<template name="featureDialog">
|
<template name="featureDialog">
|
||||||
{{#with feature}}
|
{{#with feature}}
|
||||||
{{#baseDialog title=name class=colorClass}}
|
{{#baseDialog title=name class=colorClass startEditing=../startEditing}}
|
||||||
<!--name-->
|
{{> featureDetails}}
|
||||||
<paper-input id="featureNameInput" label="Name" floatinglabel value={{name}}></paper-input>
|
{{else}}
|
||||||
<hr style="margin: 16px 0 16px 0;">
|
{{> featureEdit}}
|
||||||
<!--description-->
|
|
||||||
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
|
||||||
<paper-autogrow-textarea>
|
|
||||||
<textarea id="featureDescriptionInput" placeholder aria-label="Description" value={{description}}></textarea>
|
|
||||||
</paper-autogrow-textarea>
|
|
||||||
</paper-input-decorator>
|
|
||||||
<hr style="margin: 16px 0 16px 0;">
|
|
||||||
<div layout horizontal center style="height: 60px;">
|
|
||||||
<div class="caption">Limit Uses</div>
|
|
||||||
<paper-toggle-button id="limitUseCheck"
|
|
||||||
checked={{usesSet}}
|
|
||||||
role="button"
|
|
||||||
aria-pressed="false"
|
|
||||||
tabindex="0"
|
|
||||||
touch-action="pan-y"
|
|
||||||
style="margin-left: 8px; margin-right:8px;">
|
|
||||||
</paper-toggle-button>
|
|
||||||
{{#if usesSet}}
|
|
||||||
<paper-input id="usesInput" label="Uses" floatinglabel value={{uses}}></paper-input>
|
|
||||||
{{/if}}
|
|
||||||
<paper-dropdown-menu id="enabledDropdown" label="Enable Feature">
|
|
||||||
<paper-dropdown layered class="dropdown">
|
|
||||||
<core-menu id="enabledMenu" class="menu" selected={{enabled}} on-tap="onStatMenuTap">
|
|
||||||
<paper-item name="alwaysEnabled"> Always Enabled </paper-item>
|
|
||||||
<paper-item name="enabled"> Enabled </paper-item>
|
|
||||||
<paper-item name="disabled"> Disabled </paper-item>
|
|
||||||
</core-menu>
|
|
||||||
</paper-dropdown>
|
|
||||||
</paper-dropdown-menu>
|
|
||||||
</div>
|
|
||||||
{{> effectsEditList parentId=_id parentCollection="Features" charId=charId type="feature" name=name enabled=isEnabled}}
|
|
||||||
{{/baseDialog}}
|
{{/baseDialog}}
|
||||||
{{/with}}
|
{{/with}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template name="featureDetails">
|
||||||
|
{{#if or canEnable hasUses}}
|
||||||
|
<div layout horizontal center justified wrap>
|
||||||
|
{{#if canEnable}}
|
||||||
|
<div>enabled:</div>
|
||||||
|
<paper-checkbox class="sideMargin" checked={{enabled}}></paper-checkbox>
|
||||||
|
{{/if}}
|
||||||
|
{{#if hasUses}}
|
||||||
|
<div class="subhead" style="margin-right: 16px">
|
||||||
|
Uses: {{usesLeft}}/{{usesValue}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if hasUses}}
|
||||||
|
<div layout horizontal>
|
||||||
|
<paper-button class="useFeature" disabled={{noUsesLeft}}>Use</paper-button>
|
||||||
|
<paper-button class="resetFeature" disabled={{usesFull}}>Reset</paper-button>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="vertMargin">
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if description}}
|
||||||
|
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{> effectsViewList charId=charId parentId=_id}}
|
||||||
|
{{> proficiencyViewList charId=charId parentId=_id}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="featureEdit">
|
||||||
|
<!--name-->
|
||||||
|
<paper-input id="featureNameInput" class="fullwidth" label="Name" floatinglabel value={{name}}></paper-input>
|
||||||
|
|
||||||
|
<hr class="vertMargin">
|
||||||
|
|
||||||
|
<div layout horizontal center style="height: 60px;">
|
||||||
|
<paper-dropdown-menu id="enabledDropdown" label="Enable Feature">
|
||||||
|
<paper-dropdown layered class="dropdown">
|
||||||
|
<core-menu id="enabledMenu" class="menu" selected={{enabledSelection}} on-tap="onStatMenuTap">
|
||||||
|
<paper-item name="alwaysEnabled"> Always Enabled </paper-item>
|
||||||
|
<paper-item name="enabled"> Enabled </paper-item>
|
||||||
|
<paper-item name="disabled"> Disabled </paper-item>
|
||||||
|
</core-menu>
|
||||||
|
</paper-dropdown>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
<div layout horizontal center class="sideMargin">
|
||||||
|
<div>Limit Uses: </div>
|
||||||
|
<paper-toggle-button id="limitUseCheck"
|
||||||
|
class="sideMargin"
|
||||||
|
checked={{usesSet}}
|
||||||
|
role="button"
|
||||||
|
aria-pressed="false"
|
||||||
|
tabindex="0"
|
||||||
|
touch-action="pan-y">
|
||||||
|
</paper-toggle-button>
|
||||||
|
</div>
|
||||||
|
{{#if usesSet}}
|
||||||
|
<paper-input flex id="usesInput" label="Uses" floatinglabel value={{uses}}></paper-input>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="vertMargin">
|
||||||
|
|
||||||
|
<!--description-->
|
||||||
|
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
||||||
|
<paper-autogrow-textarea>
|
||||||
|
<textarea id="featureDescriptionInput" placeholder aria-label="Description" value={{description}}></textarea>
|
||||||
|
</paper-autogrow-textarea>
|
||||||
|
</paper-input-decorator>
|
||||||
|
|
||||||
|
{{> effectsEditList parentId=_id parentCollection="Features" charId=charId name=name enabled=enabled}}
|
||||||
|
{{> proficiencyEditList parentId=_id parentCollection="Features" charId=charId enabled=enabled}}
|
||||||
|
</template>
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
Template.featureDialog.helpers({
|
||||||
|
feature: function(){
|
||||||
|
return Features.findOne(this.featureId);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Template.featureDialog.events({
|
Template.featureDialog.events({
|
||||||
"color-change": function(event, instance){
|
"color-change": function(event, instance){
|
||||||
Features.update(instance.data.featureId, {$set: {color: event.color}});
|
Features.update(instance.data.featureId, {$set: {color: event.color}});
|
||||||
@@ -7,6 +13,61 @@ Template.featureDialog.events({
|
|||||||
GlobalUI.deletedToast(instance.data.featureId, "Features", "Feature");
|
GlobalUI.deletedToast(instance.data.featureId, "Features", "Feature");
|
||||||
GlobalUI.closeDetail();
|
GlobalUI.closeDetail();
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.featureDetails.helpers({
|
||||||
|
or: function(a, b){
|
||||||
|
return a || b;
|
||||||
|
},
|
||||||
|
hasUses: function(){
|
||||||
|
return this.usesValue() > 0;
|
||||||
|
},
|
||||||
|
noUsesLeft: function(){
|
||||||
|
return this.usesLeft() <= 0;
|
||||||
|
},
|
||||||
|
usesFull: function(){
|
||||||
|
return this.usesLeft() >= this.usesValue();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.featureDetails.events({
|
||||||
|
"tap .useFeature": function(event){
|
||||||
|
var featureId = this._id;
|
||||||
|
Features.update(featureId, {$inc: {used: 1}});
|
||||||
|
},
|
||||||
|
"tap .resetFeature": function(event){
|
||||||
|
var featureId = this._id;
|
||||||
|
Features.update(featureId, {$set: {used: 0}});
|
||||||
|
},
|
||||||
|
|
||||||
|
"change .enabledCheckbox": function(event){
|
||||||
|
var enabled = !this.enabled;
|
||||||
|
Features.update(this._id, {$set: {enabled: enabled}});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.featureEdit.onRendered(function(){
|
||||||
|
updatePolymerInputs(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.featureEdit.helpers({
|
||||||
|
usesSet: function(){
|
||||||
|
return _.isString(this.uses);
|
||||||
|
},
|
||||||
|
enabledSelection: function(){
|
||||||
|
if (this.enabled){
|
||||||
|
if (this.alwaysEnabled){
|
||||||
|
return "alwaysEnabled";
|
||||||
|
} else {
|
||||||
|
return "enabled";
|
||||||
|
}
|
||||||
|
} else if (this.enabled === false){ //make sure it is false, not just falsey
|
||||||
|
return "disabled";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.featureEdit.events({
|
||||||
"change #featureNameInput": function(event){
|
"change #featureNameInput": function(event){
|
||||||
var name = Template.instance().find("#featureNameInput").value;
|
var name = Template.instance().find("#featureNameInput").value;
|
||||||
Features.update(this._id, {$set: {name: name}});
|
Features.update(this._id, {$set: {name: name}});
|
||||||
@@ -18,7 +79,7 @@ Template.featureDialog.events({
|
|||||||
"change #limitUseCheck": function(event){
|
"change #limitUseCheck": function(event){
|
||||||
var currentUses = this.uses;
|
var currentUses = this.uses;
|
||||||
var featureId = this._id;
|
var featureId = this._id;
|
||||||
if( event.target.checked && !_.isString(currentUses) ){
|
if (event.target.checked && !_.isString(currentUses)){
|
||||||
Features.update(featureId, {$set: {uses: ""}}, {removeEmptyStrings: false});
|
Features.update(featureId, {$set: {uses: ""}}, {removeEmptyStrings: false});
|
||||||
} else if (!event.target.checked && _.isString(currentUses)){
|
} else if (!event.target.checked && _.isString(currentUses)){
|
||||||
Features.update(featureId, {$unset: {uses: ""}});
|
Features.update(featureId, {$unset: {uses: ""}});
|
||||||
@@ -31,29 +92,18 @@ Template.featureDialog.events({
|
|||||||
},
|
},
|
||||||
"core-select #enabledDropdown": function(event){
|
"core-select #enabledDropdown": function(event){
|
||||||
var detail = event.originalEvent.detail;
|
var detail = event.originalEvent.detail;
|
||||||
if(!detail.isSelected) return;
|
if (!detail.isSelected) return;
|
||||||
var value = detail.item.getAttribute("name");
|
var value = detail.item.getAttribute("name");
|
||||||
var setter;
|
var setter;
|
||||||
if(value === "enabled"){
|
if (value === "enabled"){
|
||||||
setter = {enabled: true, alwaysEnabled: false};
|
setter = {enabled: true, alwaysEnabled: false};
|
||||||
} else if (value === "disabled"){
|
} else if (value === "disabled"){
|
||||||
setter = {enabled: false, alwaysEnabled: false};
|
setter = {enabled: false, alwaysEnabled: false};
|
||||||
} else{
|
} else {
|
||||||
setter = {enabled: true, alwaysEnabled: true};
|
setter = {enabled: true, alwaysEnabled: true};
|
||||||
}
|
}
|
||||||
if (setter.enabled === this.enabled && setter.alwaysEnabled === this.alwaysEnabled) return;
|
if (setter.enabled === this.enabled &&
|
||||||
|
setter.alwaysEnabled === this.alwaysEnabled) return;
|
||||||
Features.update(this._id, {$set: setter});
|
Features.update(this._id, {$set: setter});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.featureDialog.helpers({
|
|
||||||
feature: function(){
|
|
||||||
return Features.findOne(this.featureId);
|
|
||||||
},
|
|
||||||
usesSet: function(){
|
|
||||||
return _.isString(this.uses);
|
|
||||||
},
|
|
||||||
isEnabled: function(){
|
|
||||||
return this.enabled !== "disabled";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<template name="features">
|
<template name="features">
|
||||||
<div fit>
|
<div fit>
|
||||||
<div class="scroll-y" fit>
|
<div class="scroll-y" fit>
|
||||||
<div class="containers">
|
<div class="column-container">
|
||||||
<!--expertiseDice-->
|
<!--expertiseDice-->
|
||||||
{{>resource name="expertiseDice" title="Expertise Dice" color="teal" char=this}}
|
{{>resource name="expertiseDice" title="Expertise Dice" color="teal" char=this}}
|
||||||
<!--ki-->
|
<!--ki-->
|
||||||
@@ -14,27 +14,27 @@
|
|||||||
{{>resource name="superiorityDice" title="Superiority Dice" color="teal" char=this}}
|
{{>resource name="superiorityDice" title="Superiority Dice" color="teal" char=this}}
|
||||||
|
|
||||||
<!--Attacks-->
|
<!--Attacks-->
|
||||||
<paper-shadow class="card container" hero-id="main" {{detailHero}}>
|
<paper-shadow class="card">
|
||||||
<div class="whiteTop" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
<div class="top white">
|
||||||
<div flex>
|
Attacks
|
||||||
<div class="containerName subhead">Attacks</div>
|
|
||||||
</div>
|
|
||||||
<!--<paper-icon-button class="black54" id="addAttackButton" icon="add"></paper-icon-button>-->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="containerMain listPadded">
|
<div class="bottom list">
|
||||||
{{#each attacks}}
|
{{#each attacks}}
|
||||||
<div class="itemSlot">
|
<div class="item-slot">
|
||||||
<paper-item class="white attack" hero-id="main" {{detailHero}}>
|
<div class="flexible attack item"
|
||||||
<div layout horizontal class="fullwidth">
|
hero-id="main" {{detailHero}}>
|
||||||
<div class="headline rightPadded" layout horizontal center>
|
<div layout horizontal>
|
||||||
|
<div class="headline"
|
||||||
|
style="margin-right: 16px;"
|
||||||
|
layout horizontal center>
|
||||||
{{evaluateSigned ../_id attackBonus}}
|
{{evaluateSigned ../_id attackBonus}}
|
||||||
</div>
|
</div>
|
||||||
<div layout vertical flex>
|
<div flex layout vertical>
|
||||||
<div class="body2">
|
<div class="body2">
|
||||||
{{name}}
|
{{name}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{damageDice}} {{{evaluateSignedSpaced ../_id damageBonus}}} {{damageType}}
|
{{evaluateString ../_id damage}} {{damageType}}
|
||||||
</div>
|
</div>
|
||||||
{{#if details}}
|
{{#if details}}
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
@@ -43,43 +43,77 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</paper-item>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
|
|
||||||
<!--Proficiencies-->
|
<!--Proficiencies-->
|
||||||
<paper-shadow class="card container" hero-id="main" {{detailHero "proficiencies"}}>
|
<paper-shadow class="card">
|
||||||
<div id="proficiencies"
|
<div class="white top">
|
||||||
class="whiteTop"
|
Proficiencies
|
||||||
hero-id="toolbar"
|
</div>
|
||||||
layout horizontal center
|
<div flex class="bottom list">
|
||||||
{{detailHero "proficiencies"}}>
|
{{#if weaponProfs.count}}
|
||||||
<div class="containerName subhead">Proficiencies</div>
|
<div class="subhead">Weapons</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#each weaponProfs}}
|
||||||
|
{{> proficiencyListItem}}
|
||||||
|
{{/each}}
|
||||||
|
{{#if armorProfs.count}}
|
||||||
|
<div class="subhead">Armor</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#each armorProfs}}
|
||||||
|
{{> proficiencyListItem}}
|
||||||
|
{{/each}}
|
||||||
|
{{#if toolProfs.count}}
|
||||||
|
<div class="subhead">Tools</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#each toolProfs}}
|
||||||
|
{{> proficiencyListItem}}
|
||||||
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
<div flex class="containerMain padded preline">{{characterProficiencies}}</div>
|
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
|
|
||||||
<!--features-->
|
<!--features-->
|
||||||
{{#each features}}
|
{{#each features}}
|
||||||
<paper-shadow class="card container featureCard" hero-id="main" {{detailHero}}>
|
<paper-shadow class="card featureCard"
|
||||||
<div class="containerTop {{colorClass}}" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
hero-id="main" {{detailHero}}>
|
||||||
<paper-ripple fit></paper-ripple>
|
<div class="top {{colorClass}} subhead"
|
||||||
<div class="containerName subhead" hero-id="title" flex {{detailHero}}>{{name}}</div>
|
layout horizontal
|
||||||
{{#if hasUses}}<div class="subhead" style="margin-right: 8px">{{usesLeft}}/{{usesValue}}</div>{{/if}}
|
hero-id="toolbar" {{detailHero}}>
|
||||||
<paper-ripple fit></paper-ripple>
|
<div flex hero-id="title" {{detailHero}}>
|
||||||
|
{{name}}
|
||||||
|
</div>
|
||||||
|
{{#if hasUses}}
|
||||||
|
<div style="margin-right: 8px">
|
||||||
|
{{usesLeft}}/{{usesValue}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{#if canEnable}}
|
{{#if canEnable}}
|
||||||
<core-tooltip label="Feature enabled" position="left">
|
<core-tooltip label="Feature enabled"
|
||||||
<paper-checkbox class="enabledCheckbox" checked={{enabled}}></paper-checkbox>
|
position="left">
|
||||||
|
<paper-checkbox class="enabledCheckbox"
|
||||||
|
checked={{enabled}}>
|
||||||
|
</paper-checkbox>
|
||||||
</core-tooltip>
|
</core-tooltip>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{#if description}}<div flex class="containerMain body1 featureDescription">{{description}}</div>{{/if}}
|
{{#if description}}
|
||||||
|
<div flex class="bottom text"
|
||||||
|
>{{evaluateString charId description}}</div>
|
||||||
|
{{/if}}
|
||||||
{{#if hasUses}}
|
{{#if hasUses}}
|
||||||
<div class="containerFoot" layout horizontal center end-justified>
|
<div layout horizontal center end-justified>
|
||||||
<paper-button class="useFeature" disabled={{noUsesLeft}}>Use</paper-button>
|
<paper-button class="useFeature"
|
||||||
<paper-button class="resetFeature" disabled={{usesFull}}>Reset</paper-button>
|
disabled={{noUsesLeft}}>
|
||||||
|
Use
|
||||||
|
</paper-button>
|
||||||
|
<paper-button class="resetFeature"
|
||||||
|
disabled={{usesFull}}>
|
||||||
|
Reset
|
||||||
|
</paper-button>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
@@ -87,31 +121,43 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="fab-buffer"></div>
|
<div class="fab-buffer"></div>
|
||||||
</div>
|
</div>
|
||||||
<paper-fab id="addFeature"
|
{{#if canEditCharacter _id}}
|
||||||
class="floatyButton"
|
<paper-fab id="addFeature"
|
||||||
icon="add"
|
class="floatyButton"
|
||||||
title="Add"
|
icon="add"
|
||||||
role="button"
|
title="Add"
|
||||||
tabindex="0"
|
role="button"
|
||||||
aria-label="Add"
|
tabindex="0"
|
||||||
hero-id="main"></paper-fab>
|
aria-label="Add"
|
||||||
|
hero-id="main"></paper-fab>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="resource">
|
<template name="resource">
|
||||||
{{#if char.attributeBase name}}
|
{{#if char.attributeBase name}}
|
||||||
<paper-shadow class="card container" hero-id="main" {{detailHero}} layout horizontal>
|
<paper-shadow class="card"
|
||||||
<div class="containerLeft {{getColor}}">
|
hero-id="main" {{detailHero name char._id}}
|
||||||
<div class="resourceValue">{{char.attributeValue name}}</div>
|
layout horizontal>
|
||||||
<!--<div class="resourceMax">{{char.attributeBase name}}</div>-->
|
<div class="left {{getColor}} display1 white-text"
|
||||||
<div class="resourceButtons">
|
hero-id="toolbar" {{detailHero name char._id}}
|
||||||
<paper-icon-button class="resourceUp" icon="arrow-drop-up" disabled={{cantIncrement}}></paper-icon-button>
|
layout horizontal center>
|
||||||
<paper-icon-button class="resourceDown" icon="arrow-drop-down" disabled={{cantDecrement}}></paper-icon-button>
|
<div style="margin-right: 8px;">
|
||||||
|
<paper-icon-button class="resourceUp"
|
||||||
|
icon="arrow-drop-up"
|
||||||
|
disabled={{cantIncrement}}>
|
||||||
|
</paper-icon-button>
|
||||||
|
<paper-icon-button class="resourceDown"
|
||||||
|
icon="arrow-drop-down"
|
||||||
|
disabled={{cantDecrement}}>
|
||||||
|
</paper-icon-button>
|
||||||
</div>
|
</div>
|
||||||
|
<div>{{char.attributeValue name}}</div>
|
||||||
|
<!--<div>/{{char.attributeBase name}}</div>-->
|
||||||
</div>
|
</div>
|
||||||
<div class="containerRight" flex relative horizontal layout center>
|
<div class="right clickable"
|
||||||
|
flex layout horizontal center>
|
||||||
{{title}}
|
{{title}}
|
||||||
<paper-ripple fit></paper-ripple>
|
|
||||||
</div>
|
</div>
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
@@ -13,63 +13,69 @@ Template.features.helpers({
|
|||||||
return this.usesLeft() >= this.usesValue();
|
return this.usesLeft() >= this.usesValue();
|
||||||
},
|
},
|
||||||
colorClass: function(){
|
colorClass: function(){
|
||||||
return getColorClass(this.color)
|
return getColorClass(this.color);
|
||||||
},
|
},
|
||||||
featureOrder: function(){
|
featureOrder: function(){
|
||||||
return _.indexOf(_.keys(colorOptions), this.color);
|
return _.indexOf(_.keys(colorOptions), this.color);
|
||||||
},
|
},
|
||||||
attacks: function(){
|
attacks: function(){
|
||||||
return Attacks.find({charId: this._id, enabled: true}, {sort: {color: 1, name: 1}});
|
return Attacks.find(
|
||||||
},
|
{charId: this._id, enabled: true},
|
||||||
characterProficiencies: function(){
|
{sort: {color: 1, name: 1}});
|
||||||
var char = Characters.findOne(this._id);
|
|
||||||
return char && char.proficiencies;
|
|
||||||
},
|
},
|
||||||
canEnable: function(){
|
canEnable: function(){
|
||||||
return !this.alwaysEnabled;
|
return !this.alwaysEnabled;
|
||||||
}
|
},
|
||||||
|
weaponProfs: function(){
|
||||||
|
return Proficiencies.find({charId: this._id, type: "weapon"});
|
||||||
|
},
|
||||||
|
armorProfs: function(){
|
||||||
|
return Proficiencies.find({charId: this._id, type: "armor"});
|
||||||
|
},
|
||||||
|
toolProfs: function(){
|
||||||
|
return Proficiencies.find({charId: this._id, type: "tool"});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.features.events({
|
Template.features.events({
|
||||||
"tap #addFeature": function(event){
|
"tap #addFeature": function(event){
|
||||||
var featureId = Features.insert({name: "New Feature", charId: this._id});
|
var featureId = Features.insert({
|
||||||
|
name: "New Feature",
|
||||||
|
charId: this._id,
|
||||||
|
enabled: true,
|
||||||
|
alwaysEnabled: true,
|
||||||
|
});
|
||||||
GlobalUI.setDetail({
|
GlobalUI.setDetail({
|
||||||
template: "featureDialog",
|
template: "featureDialog",
|
||||||
data: {featureId: featureId, charId: this._id},
|
data: {featureId: featureId, charId: this._id, startEditing: true},
|
||||||
heroId: featureId
|
heroId: featureId,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
"tap #addAttackButton": function(event){
|
"tap #addAttackButton": function(event){
|
||||||
var charId = this._id;
|
var charId = this._id;
|
||||||
Attacks.insert({
|
Attacks.insert({
|
||||||
charId: charId
|
charId: charId
|
||||||
}, function(error, id){
|
}, function(error, id){
|
||||||
if(!error){
|
if (!error){
|
||||||
GlobalUI.setDetail({
|
GlobalUI.setDetail({
|
||||||
template: "attackDialog",
|
template: "attackDialog",
|
||||||
data: {attackId: id, charId: charId},
|
data: {attackId: id, charId: charId},
|
||||||
heroId: id
|
heroId: id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"tap .featureCard .containerTop": function(event){
|
"tap .featureCard .top": function(event){
|
||||||
var featureId = this._id;
|
var featureId = this._id;
|
||||||
var charId = Template.parentData()._id;
|
var charId = Template.parentData()._id;
|
||||||
GlobalUI.setDetail({
|
GlobalUI.setDetail({
|
||||||
template: "featureDialog",
|
template: "featureDialog",
|
||||||
data: {featureId: featureId, charId: charId},
|
data: {featureId: featureId, charId: charId},
|
||||||
heroId: featureId
|
heroId: featureId,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"tap .attack": function(event){
|
"tap .attack": function(event){
|
||||||
var attackId = this._id;
|
openParentDialog(this.parent, this.charId, this._id);
|
||||||
var charId = Template.parentData()._id;
|
|
||||||
GlobalUI.setDetail({
|
|
||||||
template: "attackDialog",
|
|
||||||
data: {attackId: attackId, charId: charId},
|
|
||||||
heroId: attackId
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
"tap .useFeature": function(event){
|
"tap .useFeature": function(event){
|
||||||
var featureId = this._id;
|
var featureId = this._id;
|
||||||
@@ -79,52 +85,54 @@ Template.features.events({
|
|||||||
var featureId = this._id;
|
var featureId = this._id;
|
||||||
Features.update(featureId, {$set: {used: 0}});
|
Features.update(featureId, {$set: {used: 0}});
|
||||||
},
|
},
|
||||||
"tap #proficiencies": function(event){
|
|
||||||
var charId = this._id;
|
|
||||||
GlobalUI.setDetail({
|
|
||||||
template: "textDialog",
|
|
||||||
data: {charId: charId, field: "proficiencies", title: "Proficiencies", color: "q"},
|
|
||||||
heroId: this._id + "proficiencies"
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"tap .enabledCheckbox": function(event){
|
"tap .enabledCheckbox": function(event){
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
},
|
},
|
||||||
"change .enabledCheckbox": function(event){
|
"change .enabledCheckbox": function(event){
|
||||||
var enabled = !this.enabled;
|
var enabled = !this.enabled;
|
||||||
Features.update(this._id, {$set: {enabled: enabled}});
|
Features.update(this._id, {$set: {enabled: enabled}});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.resource.helpers({
|
Template.resource.helpers({
|
||||||
cantIncrement: function(){
|
cantIncrement: function(){
|
||||||
return !(this.char.attributeValue(this.name) < this.char.attributeBase(this.name));
|
var baseBigger = this.char.attributeValue(this.name) <
|
||||||
|
this.char.attributeBase(this.name);
|
||||||
|
return !baseBigger;
|
||||||
},
|
},
|
||||||
cantDecrement: function(){
|
cantDecrement: function(){
|
||||||
return !(this.char.attributeValue(this.name) > 0);
|
var valuePositive = this.char.attributeValue(this.name) > 0;
|
||||||
|
return !valuePositive;
|
||||||
},
|
},
|
||||||
getColor: function(){
|
getColor: function(){
|
||||||
if(this.char.attributeValue(this.name) > 0){
|
if (this.char.attributeValue(this.name) > 0){
|
||||||
return this.color;
|
return this.color;
|
||||||
} else {
|
} else {
|
||||||
return "grey";
|
return "grey";
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.resource.events({
|
Template.resource.events({
|
||||||
"tap .resourceUp": function(event){
|
"tap .resourceUp": function(event){
|
||||||
if(this.char.attributeValue(this.name) < this.char.attributeBase(this.name)){
|
if (this.char.attributeValue(this.name) < this.char.attributeBase(this.name)){
|
||||||
var modifier = {$inc: {}};
|
var modifier = {$inc: {}};
|
||||||
modifier.$inc[this.name + ".adjustment"] = 1;
|
modifier.$inc[this.name + ".adjustment"] = 1;
|
||||||
Characters.update(this.char._id, modifier, {validate: false});
|
Characters.update(this.char._id, modifier, {validate: false});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tap .resourceDown": function(event){
|
"tap .resourceDown": function(event){
|
||||||
if(this.char.attributeValue(this.name) > 0){
|
if (this.char.attributeValue(this.name) > 0){
|
||||||
var modifier = {$inc: {}};
|
var modifier = {$inc: {}};
|
||||||
modifier.$inc[this.name + ".adjustment"] = -1;
|
modifier.$inc[this.name + ".adjustment"] = -1;
|
||||||
Characters.update(this.char._id, modifier, {validate: false});
|
Characters.update(this.char._id, modifier, {validate: false});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"tap .right": function(event, instance) {
|
||||||
|
GlobalUI.setDetail({
|
||||||
|
template: "attributeDialog",
|
||||||
|
data: {name: this.title, statName: this.name, charId: this.char._id},
|
||||||
|
heroId: this.char._id + this.name,
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<template name="carryCapacityBar">
|
||||||
|
<div class="carryCapacityBar">
|
||||||
|
<div class="carriedWeightBar"
|
||||||
|
style="width: {{carriedPercent}}%;
|
||||||
|
background-color: {{carriedColor}}">
|
||||||
|
</div>
|
||||||
|
<div class="tick"
|
||||||
|
style="width: 33.333%;">
|
||||||
|
</div>
|
||||||
|
<div class="tick"
|
||||||
|
style="width: 66.666%;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{#if overCarriedPercent}}
|
||||||
|
<div class="carryCapacityBar">
|
||||||
|
<div class="carriedWeightBar"
|
||||||
|
style="width: {{overCarriedPercent}}%;
|
||||||
|
background-color: {{overCarriedColor}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
var getFractionCarried = function(char) {
|
||||||
|
//find out the weight
|
||||||
|
var weight = 0;
|
||||||
|
Containers.find(
|
||||||
|
{charId: char._id, isCarried: true}
|
||||||
|
).forEach(function(container){
|
||||||
|
weight += container.totalWeight();
|
||||||
|
});
|
||||||
|
Items.find(
|
||||||
|
{charId: char._id, "parent.id": char._id},
|
||||||
|
{fields: {weight : 1, quantity: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
|
weight += item.totalWeight();
|
||||||
|
});
|
||||||
|
//get strength
|
||||||
|
var strength = char.attributeValue("strength");
|
||||||
|
var capacity = strength * 15;
|
||||||
|
return weight / capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
Template.carryCapacityBar.onCreated(function() {
|
||||||
|
var self = this;
|
||||||
|
self.carriedFraction = new ReactiveVar(0);
|
||||||
|
self.autorun(function() {
|
||||||
|
self.carriedFraction.set(getFractionCarried(self.data));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.carryCapacityBar.helpers({
|
||||||
|
carriedPercent: function() {
|
||||||
|
var percent = 100 * Template.instance().carriedFraction.get();
|
||||||
|
return percent > 100 ? 100 : percent;
|
||||||
|
},
|
||||||
|
overCarriedPercent: function() {
|
||||||
|
var percent = 100 * Template.instance().carriedFraction.get();
|
||||||
|
var overPercent = percent - 100;
|
||||||
|
if (overPercent < 0) return 0;
|
||||||
|
if (overPercent > 100) return 100;
|
||||||
|
return overPercent;
|
||||||
|
},
|
||||||
|
carriedColor: function() {
|
||||||
|
var frac = Template.instance().carriedFraction.get();
|
||||||
|
if (frac < 1 / 3){
|
||||||
|
return "#2196F3";
|
||||||
|
} else if (frac < 2 / 3){
|
||||||
|
return "#CDDC39";
|
||||||
|
} else if (frac < 1) {
|
||||||
|
return "#FFC107";
|
||||||
|
} else {
|
||||||
|
return "#F44336";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
overCarriedColor: function() {
|
||||||
|
var frac = Template.instance().carriedFraction.get();
|
||||||
|
if (frac < 1 / 3){
|
||||||
|
return "#2196F3";
|
||||||
|
} else if (frac < 2 / 3){
|
||||||
|
return "#CDDC39";
|
||||||
|
} else if (frac < 1) {
|
||||||
|
return "#FFC107";
|
||||||
|
} else {
|
||||||
|
return "#F44336";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
.carryCapacityBar {
|
||||||
|
background-color: #7DC580;
|
||||||
|
background-color: rgba(255,255,255,0.27);
|
||||||
|
position: relative;
|
||||||
|
height: 4px;
|
||||||
|
div{
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.tick {
|
||||||
|
border-right: solid 2px #E5E5E5;
|
||||||
|
border-right-color: rgba(255,255,255,0.54);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<template name="carryDialog">
|
||||||
|
{{#baseDialog title="Weight Carried" class=color hideEdit=true}}
|
||||||
|
<div layout horizontal center-justified end>
|
||||||
|
<div class="display2">
|
||||||
|
{{round carriedWeight 1}}
|
||||||
|
</div>
|
||||||
|
<div class="display1">
|
||||||
|
lbs
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="vertMargin">
|
||||||
|
|
||||||
|
{{> carryCapacityTable}}
|
||||||
|
|
||||||
|
{{/baseDialog}}
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
Template.carryDialog.helpers({
|
||||||
|
carriedWeight: function() {
|
||||||
|
var weight = 0;
|
||||||
|
Containers.find(
|
||||||
|
{charId: this.charId, isCarried: true}
|
||||||
|
).forEach(function(container){
|
||||||
|
weight += container.totalWeight();
|
||||||
|
});
|
||||||
|
Items.find(
|
||||||
|
{charId: this.charId, "parent.id": this.charId},
|
||||||
|
{fields: {weight : 1, quantity: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
|
weight += item.totalWeight();
|
||||||
|
});
|
||||||
|
return weight;
|
||||||
|
},
|
||||||
|
color: function() {
|
||||||
|
if (this.color) return this.color + " white-text";
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,22 +1,46 @@
|
|||||||
<template name="containerDialog">
|
<template name="containerDialog">
|
||||||
{{#with container}}
|
{{#with container}}
|
||||||
{{#baseDialog title=name class=colorClass}}
|
{{#baseDialog title=name class=colorClass startEditing=../startEditing}}
|
||||||
<!--Name and plural name-->
|
{{> containerView}}
|
||||||
<paper-input id="containerNameInput" label="Name" floatinglabel value={{name}}></paper-input>
|
{{else}}
|
||||||
<!--Weight-->
|
{{> containerEdit}}
|
||||||
<paper-input-decorator label="Weight" floatinglabel>
|
|
||||||
<input id="weightInput" type="number" value={{weight}}>
|
|
||||||
</paper-input-decorator>
|
|
||||||
<!--Value-->
|
|
||||||
<paper-input-decorator label="Value" floatinglabel>
|
|
||||||
<input id="valueInput" type="number" value={{value}}>
|
|
||||||
</paper-input-decorator>
|
|
||||||
<!--Description-->
|
|
||||||
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
|
||||||
<paper-autogrow-textarea>
|
|
||||||
<textarea id="containerDescriptionInput" placeholder aria-label="Description" value={{description}}></textarea>
|
|
||||||
</paper-autogrow-textarea>
|
|
||||||
</paper-input-decorator>
|
|
||||||
{{/baseDialog}}
|
{{/baseDialog}}
|
||||||
{{/with}}
|
{{/with}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template name="containerEdit">
|
||||||
|
<paper-input id="containerNameInput"
|
||||||
|
label="Name"
|
||||||
|
floatinglabel
|
||||||
|
value={{name}}></paper-input>
|
||||||
|
<div layout horizontal around-justified wrap>
|
||||||
|
<paper-input-decorator label="Weight" floatinglabel>
|
||||||
|
<input id="weightInput" type="number" value={{weight}}>
|
||||||
|
</paper-input-decorator>
|
||||||
|
<paper-input-decorator label="Value" floatinglabel>
|
||||||
|
<input id="valueInput" type="number" value={{value}}>
|
||||||
|
</paper-input-decorator>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="vertMargin">
|
||||||
|
|
||||||
|
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
||||||
|
<paper-autogrow-textarea>
|
||||||
|
<textarea id="containerDescriptionInput" placeholder aria-label="Description" value={{description}}></textarea>
|
||||||
|
</paper-autogrow-textarea>
|
||||||
|
</paper-input-decorator>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{#if description}}
|
||||||
|
<hr class="vertMargin">
|
||||||
|
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||||
|
{{/if}}
|
||||||
|
</template>
|
||||||
|
|||||||
@@ -10,11 +10,21 @@ Template.containerDialog.events({
|
|||||||
},
|
},
|
||||||
"tap #deleteButton": function(event, instance){
|
"tap #deleteButton": function(event, instance){
|
||||||
Containers.softRemoveNode(instance.data.containerId);
|
Containers.softRemoveNode(instance.data.containerId);
|
||||||
GlobalUI.deletedToast(instance.data.containerId, "Containers", "Container and contents");
|
GlobalUI.deletedToast(
|
||||||
|
instance.data.containerId,
|
||||||
|
"Containers", "Container and contents"
|
||||||
|
);
|
||||||
GlobalUI.closeDetail();
|
GlobalUI.closeDetail();
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.containerEdit.onRendered(function(){
|
||||||
|
updatePolymerInputs(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.containerEdit.events({
|
||||||
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
|
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
|
||||||
"change #containerNameInput, input #containerNameInput": function(event){
|
"change #containerNameInput": function(event){
|
||||||
var name = Template.instance().find("#containerNameInput").value;
|
var name = Template.instance().find("#containerNameInput").value;
|
||||||
Containers.update(this._id, {$set: {name: name}});
|
Containers.update(this._id, {$set: {name: name}});
|
||||||
},
|
},
|
||||||
@@ -26,8 +36,8 @@ Template.containerDialog.events({
|
|||||||
var value = +Template.instance().find("#valueInput").value;
|
var value = +Template.instance().find("#valueInput").value;
|
||||||
Containers.update(this._id, {$set: {value: value}});
|
Containers.update(this._id, {$set: {value: value}});
|
||||||
},
|
},
|
||||||
"change #containerDescriptionInput": function(event){
|
"change #containerDescriptionInput": function(event, instance){
|
||||||
var description = Template.instance().find("#containerDescriptionInput").value;
|
var description = instance.find("#containerDescriptionInput").value;
|
||||||
Containers.update(this._id, {$set: {description: description}});
|
Containers.update(this._id, {$set: {description: description}});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,153 +0,0 @@
|
|||||||
div#stats {
|
|
||||||
-webkit-column-width: 200px;
|
|
||||||
-moz-column-width: 200px;
|
|
||||||
column-width: 200px;
|
|
||||||
-webkit-column-count: 4;
|
|
||||||
-moz-column-count: 4;
|
|
||||||
column-count: 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.containers {
|
|
||||||
-webkit-column-width: 300px;
|
|
||||||
-moz-column-width: 300px;
|
|
||||||
column-width: 300px;
|
|
||||||
-webkit-column-gap: 8px;
|
|
||||||
-moz-column-gap: 8px;
|
|
||||||
column-gap: 8px;
|
|
||||||
-moz-column-fill: balance;
|
|
||||||
column-fill: balance;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.containerLeft {
|
|
||||||
padding: 16px 16px 16px 24px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: row;
|
|
||||||
border-radius: 2px 0 0 2px;
|
|
||||||
|
|
||||||
/* same style as display-1 */
|
|
||||||
font-size: 34px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #ffffff;
|
|
||||||
color: rgba(255,255,255,0.54);
|
|
||||||
letter-spacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.statCard .containerLeft {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.containerRight {
|
|
||||||
padding: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
/* same style as subhead */
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
margin: 0;
|
|
||||||
color: #000;
|
|
||||||
color: rgba(0,0,0,0.87);
|
|
||||||
letter-spacing: 0.010em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceValue {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceMax {
|
|
||||||
display: inline-block;
|
|
||||||
align-self: flex-end;
|
|
||||||
|
|
||||||
/* same style as subhead */
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
margin: 0;
|
|
||||||
color: #fff;
|
|
||||||
color: rgba(255,255,255,0.54);
|
|
||||||
letter-spacing: 0.010em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceMax:before {
|
|
||||||
content: "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceButtons {
|
|
||||||
margin: -16px -16px -16px 8px;
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceButtons paper-icon-button{
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
padding: 0;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceButtons paper-icon-button[disabled]{
|
|
||||||
color: rgba(255, 255, 255, 0.26);
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourceButtons /deep/ core-icon {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.containerTop {
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 16px;
|
|
||||||
position: relative;
|
|
||||||
border-radius: 2px 2px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.equipmentTop {
|
|
||||||
padding: 16px;
|
|
||||||
border-bottom: rgba(0,0,0,0.12) solid 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.containerMain {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.equipmentMain {
|
|
||||||
padding-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inventoryItem {
|
|
||||||
background: white;
|
|
||||||
transition: box-shadow 0.3s ease,
|
|
||||||
opacity 0.5s ease-in-out;
|
|
||||||
height: 40px;
|
|
||||||
margin: 1px 0 1px 0;
|
|
||||||
font-size: 16px;
|
|
||||||
color: rgba(0,0,0,0.87);
|
|
||||||
letter-spacing: 0.010em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inventoryItem core-icon, .inventoryItem paper-icon-button {
|
|
||||||
color: rgba(0,0,0,0.54);
|
|
||||||
}
|
|
||||||
|
|
||||||
.inventoryItem core-icon {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inventoryItem /deep/ .button-content {
|
|
||||||
-webkit-flex: 1;
|
|
||||||
flex: 1;
|
|
||||||
-webkit-flex-basis: 0.000000001px;
|
|
||||||
flex-basis: 0.000000001px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inventoryItem[hero] {
|
|
||||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.37);
|
|
||||||
}
|
|
||||||
|
|
||||||
.itemSlot {
|
|
||||||
background-color: rgb(232, 232, 232);
|
|
||||||
background-color: rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#inventory .containerMain {
|
|
||||||
padding: 0 0 16px 0;
|
|
||||||
}
|
|
||||||
@@ -1,73 +1,124 @@
|
|||||||
<template name="inventory">
|
<template name="inventory">
|
||||||
<div fit>
|
<div fit>
|
||||||
<div id="inventory" class="scroll-y" fit>
|
<div id="inventory" class="scroll-y" fit>
|
||||||
<div class="containers">
|
<div class="column-container">
|
||||||
<!--Net Worth-->
|
<!--Net Worth-->
|
||||||
<paper-shadow class="card container" hero-id="main" {{detailHero}} layout horizontal>
|
<paper-shadow class="card">
|
||||||
<div class="indigo white-text subhead padded leftRound" layout horizontal center>
|
<div class="white top" layout horizontal center>
|
||||||
Net Worth
|
<div class="subhead" flex>
|
||||||
</div>
|
Net Worth
|
||||||
<div class="padded" layout horizontal center>
|
</div>
|
||||||
{{valueString netWorth}}
|
<div>
|
||||||
|
{{valueString netWorth}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
<!--Weight Carried-->
|
<!--Weight Carried-->
|
||||||
<paper-shadow class="card container" hero-id="main" {{detailHero}} layout horizontal>
|
<paper-shadow class="card"
|
||||||
<div class="green white-text subhead padded leftRound" layout horizontal center>
|
hero-id="main" {{detailHero "weightCarried" _id}}>
|
||||||
Weight Carried
|
<div class="top green white-text weightCarried"
|
||||||
|
hero-id="toolbar" {{detailHero "weightCarried" _id}}
|
||||||
|
layout horizontal center>
|
||||||
|
<div class="subhead" flex>
|
||||||
|
Weight Carried
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{round weightCarried}}lbs
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="padded" layout horizontal center>
|
<div class="bottom green" style="padding: 0;">
|
||||||
{{round weightCarried}}lbs
|
{{> carryCapacityBar}}
|
||||||
</div>
|
</div>
|
||||||
|
{{#if encumberedBuffs.count}}
|
||||||
|
<div class="bottom list">
|
||||||
|
{{#each encumberedBuffs}}
|
||||||
|
<div class="item-slot">
|
||||||
|
<div class="item buff"
|
||||||
|
hero-id="main" {{detailHero}}
|
||||||
|
layout horizontal center
|
||||||
|
draggable="true">
|
||||||
|
<div flex>
|
||||||
|
<core-icon icon="work"
|
||||||
|
style="margin-right: 16px">
|
||||||
|
</core-icon>
|
||||||
|
{{name}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
<!--Equipment-->
|
<!--Equipment-->
|
||||||
<paper-shadow class="card container equipmentContainer">
|
<paper-shadow class="card equipmentContainer">
|
||||||
<div class="equipmentTop" layout horizontal center>
|
<div class="white top" layout horizontal center>
|
||||||
<div class="containerName subhead" flex>
|
<div class="subhead" flex>
|
||||||
Equipment
|
Equipment
|
||||||
</div>
|
</div>
|
||||||
<div class="caption" style="margin-right: 8px">{{valueString equipmentValue}}</div>
|
<div class="caption" style="margin-right: 8px">
|
||||||
<div class="caption">{{round equipmentWeight}}lbs</div>
|
{{valueString equipmentValue}}
|
||||||
|
</div>
|
||||||
|
<div class="caption">
|
||||||
|
{{round equipmentWeight}}lbs
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div flex class="equipmentMain">
|
<div flex class="bottom list">
|
||||||
{{#if attuned.count}}
|
{{#if attuned.count}}
|
||||||
<div class="list-subhead" layout horizontal center>Attuned</div>
|
<div class="subhead">Attuned</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#each attuned}}
|
{{#each attuned}}
|
||||||
{{>inventoryItem}}
|
{{>inventoryItem}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#if attuned.count}}<div class="list-subhead" layout horizontal center>Equipment</div>{{/if}}
|
{{#if attuned.count}}
|
||||||
|
<div class="subhead">Equipment</div>
|
||||||
|
{{/if}}
|
||||||
{{#each equipment}}
|
{{#each equipment}}
|
||||||
{{>inventoryItem}}
|
{{>inventoryItem}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
<!--Carried Items-->
|
<!--Carried Items-->
|
||||||
<paper-shadow class="card container carriedContainer">
|
<paper-shadow class="card carriedContainer">
|
||||||
<div class="equipmentTop" layout horizontal center>
|
<div class="white top" layout horizontal center>
|
||||||
<div class="containerName subhead" flex>
|
<div class="subhead" flex>
|
||||||
Carried
|
Carried
|
||||||
</div>
|
</div>
|
||||||
<div class="caption" style="margin-right: 8px">{{valueString carriedValue}}</div>
|
<div class="caption" style="margin-right: 8px">
|
||||||
<div class="caption">{{round carriedWeight}}lbs</div>
|
{{valueString carriedValue}}
|
||||||
|
</div>
|
||||||
|
<div class="caption">
|
||||||
|
{{round carriedWeight}}lbs
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div flex class="containerMain">
|
<div flex class="bottom list">
|
||||||
{{#each carriedItems}}
|
{{#each carriedItems}}
|
||||||
{{>inventoryItem}}
|
{{>inventoryItem}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
{{#each containers}}
|
{{#each containers}}
|
||||||
<paper-shadow class="card container itemContainer" hero-id="main" {{detailHero}} style="order: {{containerOrder}};">
|
<paper-shadow class="card itemContainer"
|
||||||
<div class="containerTop {{colorClass}}" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
hero-id="main" {{detailHero}}>
|
||||||
<div class="containerName subhead" hero-id="title" flex {{detailHero}}>{{name}}</div>
|
<div class="top {{colorClass}}"
|
||||||
<div class="caption" style="margin-right: 8px">{{valueString totalValue}}</div>
|
hero-id="toolbar" {{detailHero}}
|
||||||
<div class="caption" style="margin-right: 8px">{{round totalWeight}}lbs</div>
|
layout horizontal center>
|
||||||
|
<div class="subhead" flex
|
||||||
|
hero-id="title" {{detailHero}}>
|
||||||
|
{{name}}
|
||||||
|
</div>
|
||||||
|
<div class="caption" style="margin-right: 8px">
|
||||||
|
{{valueString totalValue}}
|
||||||
|
</div>
|
||||||
|
<div class="caption" style="margin-right: 8px">
|
||||||
|
{{round totalWeight}}lbs
|
||||||
|
</div>
|
||||||
<core-tooltip label="Container carried" position="left">
|
<core-tooltip label="Container carried" position="left">
|
||||||
<paper-checkbox class="carriedCheckbox" checked={{isCarried}}></paper-checkbox>
|
<paper-checkbox class="carriedCheckbox"
|
||||||
|
checked={{isCarried}}>
|
||||||
|
</paper-checkbox>
|
||||||
</core-tooltip>
|
</core-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div flex class="containerMain">
|
<div class="bottom list">
|
||||||
{{#each items ../_id _id}}
|
{{#each items ../_id _id}}
|
||||||
{{>inventoryItem}}
|
{{>inventoryItem}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
@@ -77,17 +128,45 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="fab-buffer"></div>
|
<div class="fab-buffer"></div>
|
||||||
</div>
|
</div>
|
||||||
<paper-fab-menu id="inventoryAddMenu" icon="add" closeIcon="close" duration="0.3">
|
{{#if canEditCharacter _id}}
|
||||||
<paper-fab-menu-item id="addItem" icon="note-add" color="#d23f31" tooltip="Item"></paper-fab-menu-item>
|
{{#fabMenu}}
|
||||||
<paper-fab-menu-item id="addContainer" icon="work" color="#d23f31" tooltip="Container"></paper-fab-menu-item>
|
<core-tooltip label="New container" position="left">
|
||||||
</paper-fab-menu>
|
<paper-fab icon="work"
|
||||||
|
class="addContainer"
|
||||||
|
mini>
|
||||||
|
</paper-fab>
|
||||||
|
</core-tooltip>
|
||||||
|
<core-tooltip label="New item" position="left">
|
||||||
|
<paper-fab icon="note-add"
|
||||||
|
class="addItem"
|
||||||
|
mini>
|
||||||
|
</paper-fab>
|
||||||
|
</core-tooltip>
|
||||||
|
{{/fabMenu}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="inventoryItem">
|
<template name="inventoryItem">
|
||||||
<div class="itemSlot">
|
<div class="item-slot">
|
||||||
<paper-item class="inventoryItem {{hidden}}" hero-id="main" noink {{detailHero}} layout horizontal draggable="true">
|
<div class="item {{hidden}} inventoryItem"
|
||||||
{{#if ne1 quantity}}{{quantity}} {{/if}}{{pluralName}}
|
hero-id="main" {{detailHero}}
|
||||||
</paper-item>
|
layout horizontal center
|
||||||
|
draggable="true">
|
||||||
|
<div flex class="itemName">
|
||||||
|
{{#if ne1 quantity}}{{quantity}} {{/if}}{{pluralName}}
|
||||||
|
</div>
|
||||||
|
{{#if settings.showIncrement}}
|
||||||
|
<div class="incrementButtons">
|
||||||
|
<paper-icon-button class="addItemQuantity"
|
||||||
|
icon="add"
|
||||||
|
style="margin-right: -8px"></paper-icon-button>
|
||||||
|
<paper-icon-button class="subItemQuantity"
|
||||||
|
disabled={{lt1 quantity}}
|
||||||
|
icon="remove"
|
||||||
|
style="margin-right: -8px"></paper-icon-button>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -7,16 +7,28 @@ Template.inventory.helpers({
|
|||||||
return Containers.find({charId: this._id}, {sort: {color: 1, name: 1}});
|
return Containers.find({charId: this._id}, {sort: {color: 1, name: 1}});
|
||||||
},
|
},
|
||||||
items: function(charId, containerId){
|
items: function(charId, containerId){
|
||||||
return Items.find({charId: charId, "parent.id": containerId }, {sort: {color: 1, name: 1}});
|
return Items.find(
|
||||||
|
{charId: charId, "parent.id": containerId},
|
||||||
|
{sort: {color: 1, name: 1}}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
attuned: function(){
|
attuned: function(){
|
||||||
return Items.find({ charId: this._id, enabled: true, requiresAttunement: true }, {sort: {color: 1, name: 1}});
|
return Items.find(
|
||||||
|
{charId: this._id, enabled: true, requiresAttunement: true},
|
||||||
|
{sort: {color: 1, name: 1}}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
equipment: function(){
|
equipment: function(){
|
||||||
return Items.find({ charId: this._id, enabled: true, requiresAttunement: false }, {sort: {color: 1, name: 1}});
|
return Items.find(
|
||||||
|
{charId: this._id, enabled: true, requiresAttunement: false},
|
||||||
|
{sort: {color: 1, name: 1}}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
carriedItems: function(){
|
carriedItems: function(){
|
||||||
return Items.find({charId: this._id, enabled: false, "parent.id": this._id}, {sort: {color: 1, name: 1}});
|
return Items.find(
|
||||||
|
{charId: this._id, enabled: false, "parent.id": this._id},
|
||||||
|
{sort: {color: 1, name: 1}}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
showAddButtons: function(){
|
showAddButtons: function(){
|
||||||
return Template.instance().showAddButtons.get();
|
return Template.instance().showAddButtons.get();
|
||||||
@@ -26,45 +38,76 @@ Template.inventory.helpers({
|
|||||||
},
|
},
|
||||||
netWorth: function(){
|
netWorth: function(){
|
||||||
var worth = 0;
|
var worth = 0;
|
||||||
Items.find({charId: this._id}, {fields: {value : 1, quantity: 1}}).forEach(function(item){
|
Items.find(
|
||||||
|
{charId: this._id},
|
||||||
|
{fields: {value : 1, quantity: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
worth += item.totalValue();
|
worth += item.totalValue();
|
||||||
});
|
});
|
||||||
return worth;
|
return worth;
|
||||||
},
|
},
|
||||||
weightCarried: function(){
|
weightCarried: function(){
|
||||||
var weight = 0;
|
var weight = 0;
|
||||||
Containers.find({charId: this._id, isCarried: true}).forEach(function(container){
|
Containers.find(
|
||||||
|
{charId: this._id, isCarried: true}
|
||||||
|
).forEach(function(container){
|
||||||
weight += container.totalWeight();
|
weight += container.totalWeight();
|
||||||
});
|
});
|
||||||
Items.find({charId: this._id, "parent.id": this._id}, {fields: {weight : 1, quantity: 1}}).forEach(function(item){
|
Items.find(
|
||||||
|
{charId: this._id, "parent.id": this._id},
|
||||||
|
{fields: {weight : 1, quantity: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
weight += item.totalWeight();
|
weight += item.totalWeight();
|
||||||
});
|
});
|
||||||
return weight;
|
return weight;
|
||||||
},
|
},
|
||||||
|
encumberedBuffs: function(){
|
||||||
|
return Buffs.find({
|
||||||
|
charId: this._id,
|
||||||
|
type: "inate",
|
||||||
|
name: {$in: [
|
||||||
|
"Encumbered",
|
||||||
|
"Heavily encumbered",
|
||||||
|
"Over encumbered",
|
||||||
|
"Can't move load",
|
||||||
|
]},
|
||||||
|
});
|
||||||
|
},
|
||||||
equipmentValue: function(){
|
equipmentValue: function(){
|
||||||
var value = 0;
|
var value = 0;
|
||||||
Items.find({charId: this._id, enabled: true}, {fields: {value : 1, quantity: 1}}).forEach(function(item){
|
Items.find(
|
||||||
|
{charId: this._id, enabled: true},
|
||||||
|
{fields: {value : 1, quantity: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
value += item.totalValue();
|
value += item.totalValue();
|
||||||
});
|
});
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
equipmentWeight: function(){
|
equipmentWeight: function(){
|
||||||
var weight = 0;
|
var weight = 0;
|
||||||
Items.find({charId: this._id, enabled: true}, {fields: {weight : 1, quantity: 1}}).forEach(function(item){
|
Items.find({charId: this._id, enabled: true},
|
||||||
|
{fields: {weight : 1, quantity: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
weight += item.totalWeight();
|
weight += item.totalWeight();
|
||||||
});
|
});
|
||||||
return weight;
|
return weight;
|
||||||
},
|
},
|
||||||
carriedValue: function(){
|
carriedValue: function(){
|
||||||
var value = 0;
|
var value = 0;
|
||||||
Items.find({charId: this._id, enabled: false, "parent.id": this._id}, {fields: {value : 1, quantity: 1}}).forEach(function(item){
|
Items.find(
|
||||||
|
{charId: this._id, enabled: false, "parent.id": this._id},
|
||||||
|
{fields: {value : 1, quantity: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
value += item.totalValue();
|
value += item.totalValue();
|
||||||
});
|
});
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
carriedWeight: function(){
|
carriedWeight: function(){
|
||||||
var weight = 0;
|
var weight = 0;
|
||||||
Items.find({charId: this._id, enabled: false, "parent.id": this._id}, {fields: {weight : 1, quantity: 1}}).forEach(function(item){
|
Items.find(
|
||||||
|
{charId: this._id, enabled: false, "parent.id": this._id},
|
||||||
|
{fields: {weight : 1, quantity: 1}}
|
||||||
|
).forEach(function(item){
|
||||||
weight += item.totalWeight();
|
weight += item.totalWeight();
|
||||||
});
|
});
|
||||||
return weight;
|
return weight;
|
||||||
@@ -72,29 +115,54 @@ Template.inventory.helpers({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.inventory.events({
|
Template.inventory.events({
|
||||||
"tap #addItem": function(event){
|
"tap .addItem": function(event){
|
||||||
var charId = this._id;
|
var charId = this._id;
|
||||||
Items.insert({
|
Items.insert({
|
||||||
charId: charId,
|
charId: charId,
|
||||||
parent:{
|
parent:{
|
||||||
id: charId,
|
id: charId,
|
||||||
collection: "Characters"
|
collection: "Characters",
|
||||||
}
|
},
|
||||||
}, function(err, itemId){
|
}, function(err, itemId){
|
||||||
if(err) throw err;
|
if (err) throw err;
|
||||||
GlobalUI.setDetail({
|
GlobalUI.setDetail({
|
||||||
template: "itemDialog",
|
template: "itemDialog",
|
||||||
data: {itemId: itemId, charId: charId},
|
data: {itemId: itemId, charId: charId, startEditing: true},
|
||||||
heroId: itemId
|
heroId: itemId,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"tap #addContainer": function(event){
|
"tap .addContainer": function(event){
|
||||||
var containerId = Containers.insert({name: "New Container", isCarried: true, charId: this._id});
|
var containerId = Containers.insert({
|
||||||
|
name: "New Container",
|
||||||
|
isCarried: true,
|
||||||
|
charId: this._id,
|
||||||
|
});
|
||||||
GlobalUI.setDetail({
|
GlobalUI.setDetail({
|
||||||
template: "containerDialog",
|
template: "containerDialog",
|
||||||
data: {containerId: containerId, charId: this.charId},
|
data: {
|
||||||
heroId: containerId
|
containerId: containerId,
|
||||||
|
charId: this.charId,
|
||||||
|
startEditing: true,
|
||||||
|
},
|
||||||
|
heroId: containerId,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"tap .weightCarried": function(event) {
|
||||||
|
var charId = this._id;
|
||||||
|
GlobalUI.setDetail({
|
||||||
|
template: "carryDialog",
|
||||||
|
data: {charId: charId, color: "green"},
|
||||||
|
heroId: charId + "weightCarried",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"tap .buff": function(event){
|
||||||
|
var buffId = this._id;
|
||||||
|
var charId = Template.parentData()._id;
|
||||||
|
GlobalUI.setDetail({
|
||||||
|
template: "buffDialog",
|
||||||
|
data: {buffId: buffId, charId: charId},
|
||||||
|
heroId: buffId,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"tap .inventoryItem": function(event){
|
"tap .inventoryItem": function(event){
|
||||||
@@ -103,14 +171,25 @@ Template.inventory.events({
|
|||||||
GlobalUI.setDetail({
|
GlobalUI.setDetail({
|
||||||
template: "itemDialog",
|
template: "itemDialog",
|
||||||
data: {itemId: itemId, charId: charId},
|
data: {itemId: itemId, charId: charId},
|
||||||
heroId: itemId
|
heroId: itemId,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"tap .containerTop": function(event){
|
"tap .incrementButtons": function(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
"tap .addItemQuantity": function(event) {
|
||||||
|
var itemId = this._id;
|
||||||
|
Items.update(itemId, {$set: {quantity: this.quantity + 1}});
|
||||||
|
},
|
||||||
|
"tap .subItemQuantity": function(event) {
|
||||||
|
var itemId = this._id;
|
||||||
|
Items.update(itemId, {$set: {quantity: this.quantity - 1}});
|
||||||
|
},
|
||||||
|
"tap .itemContainer .top": function(event){
|
||||||
GlobalUI.setDetail({
|
GlobalUI.setDetail({
|
||||||
template: "containerDialog",
|
template: "containerDialog",
|
||||||
data: {containerId: this._id, charId: this.charId},
|
data: {containerId: this._id, charId: this.charId},
|
||||||
heroId: this._id
|
heroId: this._id,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"tap .carriedCheckbox": function(event){
|
"tap .carriedCheckbox": function(event){
|
||||||
@@ -118,88 +197,113 @@ Template.inventory.events({
|
|||||||
},
|
},
|
||||||
"change .carriedCheckbox": function(event){
|
"change .carriedCheckbox": function(event){
|
||||||
var carried;
|
var carried;
|
||||||
if(this.isCarried) carried = false;
|
if (this.isCarried) carried = false;
|
||||||
else carried = true;
|
else carried = true;
|
||||||
Containers.update(this._id, {$set: {isCarried: carried}});
|
Containers.update(this._id, {$set: {isCarried: carried}});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.inventoryItem.helpers({
|
Template.inventoryItem.helpers({
|
||||||
ne1: function(num){
|
ne1: function(num){
|
||||||
return num !== 1;
|
return num !== 1;
|
||||||
},
|
},
|
||||||
|
lt1: function(num) {
|
||||||
|
return num < 1;
|
||||||
|
},
|
||||||
hidden: function(){
|
hidden: function(){
|
||||||
return Session.equals("inventory.dragItemId", this._id)? "hidden" : null;
|
return Session.equals("inventory.dragItemId", this._id) ? "hidden" : null;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.layout.events({
|
Template.layout.events({
|
||||||
"dragstart .inventoryItem": function(event, instance){
|
"dragstart .inventoryItem": function(event, instance){
|
||||||
|
event.originalEvent.dataTransfer.setData("dicecloud-id/items", this._id);
|
||||||
Session.set("inventory.dragItemId", this._id);
|
Session.set("inventory.dragItemId", this._id);
|
||||||
Session.set("inventory.dragItemOriginalContainer", this.container);
|
},
|
||||||
Session.set("inventory.dragItemOriginalCharacter", this.charId);
|
"dragover .itemContainer, dragenter .itemContainer":
|
||||||
|
function(event, instance){
|
||||||
|
if (_.contains(event.originalEvent.dataTransfer.types, "dicecloud-id/items")){
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dragover .equipmentContainer, dragenter .equipmentContainer":
|
||||||
|
function(event, instance){
|
||||||
|
if (_.contains(event.originalEvent.dataTransfer.types, "dicecloud-id/items")){
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dragover .carriedContainer, dragenter .carriedContainer":
|
||||||
|
function(event, instance){
|
||||||
|
if (_.contains(event.originalEvent.dataTransfer.types, "dicecloud-id/items")){
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dragover .characterRepresentative, dragenter .characterRepresentative":
|
||||||
|
function(event, instance){
|
||||||
|
if (_.contains(event.originalEvent.dataTransfer.types, "dicecloud-id/items")){
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"dragend .inventoryItem": function(event, instance){
|
"dragend .inventoryItem": function(event, instance){
|
||||||
resetInvetorySession(); //this is a valid drop zone
|
Session.set("inventory.dragItemId", null);
|
||||||
},
|
},
|
||||||
"dragover .itemContainer": function(event, instance){
|
"drop .itemContainer": function(event, instance){
|
||||||
event.preventDefault();
|
var itemId = event.originalEvent.dataTransfer.getData("dicecloud-id/items");
|
||||||
},
|
if (event.ctrlKey){
|
||||||
"dragover .equipmentContainer": function(event, instance){
|
|
||||||
event.preventDefault();
|
|
||||||
},
|
|
||||||
"dragover .carriedContainer": function(event, instance){
|
|
||||||
event.preventDefault();
|
|
||||||
},
|
|
||||||
"drop .itemContainer": function(event, instacne){
|
|
||||||
var item = Items.findOne(Session.get("inventory.dragItemId"));
|
|
||||||
if(event.ctrlKey){
|
|
||||||
//split the stack to the container
|
//split the stack to the container
|
||||||
GlobalUI.showDialog({
|
GlobalUI.showDialog({
|
||||||
template: "splitStackDialog",
|
template: "splitStackDialog",
|
||||||
data: {
|
data: {
|
||||||
id: item._id,
|
id: itemId,
|
||||||
parentCollection: "Containers",
|
parentCollection: "Containers",
|
||||||
parentId: this._id
|
parentId: this._id,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
} else{
|
} else {
|
||||||
//move item to the container
|
//move item to the container
|
||||||
item.moveToContainer(this._id);
|
Meteor.call("moveItemToContainer", itemId, this._id);
|
||||||
}
|
}
|
||||||
resetInvetorySession();
|
Session.set("inventory.dragItemId", null);
|
||||||
},
|
},
|
||||||
"drop .equipmentContainer": function(event, instance){
|
"drop .equipmentContainer": function(event, instance){
|
||||||
var charId = Session.get("inventory.dragItemOriginalCharacter");
|
var itemId = event.originalEvent.dataTransfer.getData("dicecloud-id/items");
|
||||||
var item = Items.findOne(Session.get("inventory.dragItemId"));
|
Meteor.call("equipItem", itemId, this._id);
|
||||||
item.equip(charId);
|
Session.set("inventory.dragItemId", null);
|
||||||
resetInvetorySession();
|
|
||||||
},
|
},
|
||||||
"drop .carriedContainer": function(event, instance){
|
"drop .carriedContainer": function(event, instance){
|
||||||
var charId = Session.get("inventory.dragItemOriginalCharacter");
|
var itemId = event.originalEvent.dataTransfer.getData("dicecloud-id/items");
|
||||||
var item = Items.findOne(Session.get("inventory.dragItemId"));
|
if (event.ctrlKey){
|
||||||
if(event.ctrlKey){
|
|
||||||
//split the stack to the container
|
//split the stack to the container
|
||||||
GlobalUI.showDialog({
|
GlobalUI.showDialog({
|
||||||
template: "splitStackDialog",
|
template: "splitStackDialog",
|
||||||
data: {
|
data: {
|
||||||
id: item._id,
|
id: itemId,
|
||||||
parentCollection: "Characters",
|
parentCollection: "Characters",
|
||||||
parentId: this._id
|
parentId: this._id,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
} else{
|
} else {
|
||||||
//move item to the character
|
//move item to the character
|
||||||
item.moveToCharacter(this._id);
|
Meteor.call("moveItemToCharacter", itemId, this._id);
|
||||||
}
|
}
|
||||||
resetInvetorySession();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var resetInvetorySession = function(){
|
|
||||||
_.defer(function(){
|
|
||||||
Session.set("inventory.dragItemId", null);
|
Session.set("inventory.dragItemId", null);
|
||||||
Session.set("inventory.dragItemOriginalContainer", null);
|
},
|
||||||
Session.set("inventory.dragItemOriginalCharacter", null);
|
"drop .characterRepresentative": function(event, instance) {
|
||||||
});
|
var itemId = event.originalEvent.dataTransfer.getData("dicecloud-id/items");
|
||||||
};
|
if (event.ctrlKey){
|
||||||
|
//split the stack to the container
|
||||||
|
GlobalUI.showDialog({
|
||||||
|
template: "splitStackDialog",
|
||||||
|
data: {
|
||||||
|
id: itemId,
|
||||||
|
parentCollection: "Characters",
|
||||||
|
parentId: this._id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
//move item to the character
|
||||||
|
Meteor.call("moveItemToCharacter", itemId, this._id);
|
||||||
|
}
|
||||||
|
Session.set("inventory.dragItemId", null);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,57 +1,113 @@
|
|||||||
<template name="itemDialog">
|
<template name="itemDialog">
|
||||||
{{#with item}}
|
{{#with item}}
|
||||||
{{#baseDialog title=name class=colorClass}}
|
{{#baseDialog title=itemHeading class=colorClass startEditing=../startEditing}}
|
||||||
<!--Name and plural name-->
|
{{> itemDetails}}
|
||||||
<paper-input id="itemNameInput" class="fullwidth" label="Name" floatinglabel value={{name}}></paper-input>
|
{{else}}
|
||||||
{{# if ne1 quantity}}<paper-input id="itemPluralInput" label="Plural Name" floatinglabel value={{plural}}></paper-input>{{/if}}
|
{{> itemEdit}}
|
||||||
<!--Container dropdown-->
|
|
||||||
<paper-dropdown-menu id="containerDropDown" label="Container">
|
|
||||||
<paper-dropdown layered class="dropdown">
|
|
||||||
<core-menu class="menu" selected={{parent.id}}>
|
|
||||||
{{#each containers}}
|
|
||||||
<paper-item name={{_id}} class="containerMenuItem">{{name}}</paper-item>
|
|
||||||
{{/each}}
|
|
||||||
</core-menu>
|
|
||||||
</paper-dropdown>
|
|
||||||
</paper-dropdown-menu>
|
|
||||||
<!--Equipped-->
|
|
||||||
<div center horizontal layout>
|
|
||||||
<div flex>Equipped</div>
|
|
||||||
<paper-toggle-button id="equippedInput"
|
|
||||||
checked={{enabled}}
|
|
||||||
role="button"
|
|
||||||
aria-pressed="false"
|
|
||||||
tabindex="0"
|
|
||||||
touch-action="pan-y">
|
|
||||||
</paper-toggle-button>
|
|
||||||
</div>
|
|
||||||
<!--Equipped-->
|
|
||||||
<div center horizontal layout>
|
|
||||||
<div flex>Requires Attunement</div>
|
|
||||||
<paper-checkbox id="attunementCheckbox" checked={{requiresAttunement}}></paper-checkbox>
|
|
||||||
</div>
|
|
||||||
<!--Quantity-->
|
|
||||||
<paper-input-decorator label="Quantity" floatinglabel>
|
|
||||||
<input id="quantityInput" type="number" value={{quantity}}>
|
|
||||||
</paper-input-decorator>
|
|
||||||
<!--Weight-->
|
|
||||||
<paper-input-decorator label="Weight Each (lbs)" floatinglabel>
|
|
||||||
<input id="weightInput" type="number" value={{weight}}>
|
|
||||||
</paper-input-decorator>
|
|
||||||
<!--Value-->
|
|
||||||
<paper-input-decorator label="Value Each (GP)" floatinglabel>
|
|
||||||
<input id="valueInput" type="number" value={{value}}>
|
|
||||||
</paper-input-decorator>
|
|
||||||
<!--Description-->
|
|
||||||
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
|
||||||
<paper-autogrow-textarea>
|
|
||||||
<textarea id="itemDescriptionInput" placeholder aria-label="Description" value={{description}}></textarea>
|
|
||||||
</paper-autogrow-textarea>
|
|
||||||
</paper-input-decorator>
|
|
||||||
<!--Effects-->
|
|
||||||
{{> effectsEditList parentId=_id parentCollection="Items" charId=charId type="equipment" enabled=equipped name=name}}
|
|
||||||
<!--Attacks-->
|
|
||||||
{{> attackEditList parentId=_id parentCollection="Items" charId=charId type="equipment" enabled=equipped name=name}}
|
|
||||||
{{/baseDialog}}
|
{{/baseDialog}}
|
||||||
{{/with}}
|
{{/with}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template name="itemDetails">
|
||||||
|
<div layout horizontal wrap center justified class="headline">
|
||||||
|
{{#if weight}}<div class="sideMargin">{{round totalWeight}}lbs</div>{{/if}}
|
||||||
|
{{#if value}}<div>{{valueString totalValue}}</div>{{/if}}
|
||||||
|
</div>
|
||||||
|
<div layout horizontal wrap class="caption">
|
||||||
|
{{#if enabled}}<div class="vertMargin" style="margin-right: 16px">Equipped</div>{{/if}}
|
||||||
|
{{#if requiresAttunement}}<div class="vertMargin">Requires Attunement</div>{{/if}}
|
||||||
|
</div>
|
||||||
|
{{#if description}}
|
||||||
|
<hr class="vertMargin">
|
||||||
|
<div class="pre-wrap">{{evaluateString charId description}}</div>
|
||||||
|
{{/if}}
|
||||||
|
{{> effectsViewList charId=charId parentId=_id}}
|
||||||
|
{{> attacksViewList charId=charId parentId=_id}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="itemEdit">
|
||||||
|
<paper-input class="fullwidth" id="itemNameInput" label="Name" floatinglabel value={{name}}></paper-input>
|
||||||
|
<div layout horizontal wrap>
|
||||||
|
<paper-input-decorator label="Quantity"
|
||||||
|
floatinglabel
|
||||||
|
style="width: 80px">
|
||||||
|
<input id="quantityInput"
|
||||||
|
type="number"
|
||||||
|
value={{quantity}}>
|
||||||
|
</paper-input-decorator>
|
||||||
|
{{# if ne1 quantity}}
|
||||||
|
<paper-input flex id="itemPluralInput"
|
||||||
|
label="Plural Name"
|
||||||
|
floatinglabel
|
||||||
|
value={{plural}}></paper-input>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<div center horizontal layout>
|
||||||
|
<div class="padded">Show increment buttons</div>
|
||||||
|
<paper-checkbox id="incrementCheckbox"
|
||||||
|
checked={{settings.showIncrement}}>
|
||||||
|
</paper-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="vertMargin">
|
||||||
|
|
||||||
|
<div layout horizontal wrap justified>
|
||||||
|
<div center horizontal layout>
|
||||||
|
<div class="padded">Container</div>
|
||||||
|
{{> containerDropdown}}
|
||||||
|
</div>
|
||||||
|
<div center horizontal layout>
|
||||||
|
<div class="padded">Equipped</div>
|
||||||
|
<paper-toggle-button id="equippedInput"
|
||||||
|
checked={{enabled}}
|
||||||
|
role="button"
|
||||||
|
aria-pressed="false"
|
||||||
|
tabindex="0"
|
||||||
|
touch-action="pan-y">
|
||||||
|
</paper-toggle-button>
|
||||||
|
</div>
|
||||||
|
<div center horizontal layout>
|
||||||
|
<div class="padded">Requires Attunement</div>
|
||||||
|
<paper-checkbox id="attunementCheckbox"
|
||||||
|
checked={{requiresAttunement}}>
|
||||||
|
</paper-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="vertMargin">
|
||||||
|
|
||||||
|
<div layout horizontal around-justified>
|
||||||
|
<paper-input-decorator label="Weight Each (lbs)" floatinglabel>
|
||||||
|
<input id="weightInput" type="number" value={{weight}}>
|
||||||
|
</paper-input-decorator>
|
||||||
|
<!--Value-->
|
||||||
|
<paper-input-decorator label="Value Each (GP)" floatinglabel>
|
||||||
|
<input id="valueInput" type="number" value={{value}}>
|
||||||
|
</paper-input-decorator>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="vertMargin">
|
||||||
|
|
||||||
|
<!--Description-->
|
||||||
|
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
||||||
|
<paper-autogrow-textarea>
|
||||||
|
<textarea id="itemDescriptionInput" placeholder aria-label="Description" value={{description}}></textarea>
|
||||||
|
</paper-autogrow-textarea>
|
||||||
|
</paper-input-decorator>
|
||||||
|
<!--Effects-->
|
||||||
|
{{> effectsEditList parentId=_id parentCollection="Items" charId=charId enabled=equipped name=name}}
|
||||||
|
<!--Attacks-->
|
||||||
|
{{> attackEditList parentId=_id parentCollection="Items" charId=charId enabled=equipped name=name}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="containerDropdown">
|
||||||
|
<paper-dropdown-menu id="containerDropDown" label="Container">
|
||||||
|
<paper-dropdown layered class="dropdown">
|
||||||
|
<core-menu class="menu" selected={{parent.id}}>
|
||||||
|
{{#each containers}}
|
||||||
|
<paper-item name={{_id}} class="containerMenuItem">{{name}}</paper-item>
|
||||||
|
{{/each}}
|
||||||
|
</core-menu>
|
||||||
|
</paper-dropdown>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
|||||||
@@ -1,20 +1,38 @@
|
|||||||
var getContainers = function(charId){
|
var getContainers = function(charId){
|
||||||
return Containers.find({charId: charId}, {sort: {name: 1, _id: 1}, fields: {name: 1}}).fetch();
|
return Containers.find(
|
||||||
|
{charId: charId},
|
||||||
|
{sort: {name: 1, _id: 1}, fields: {name: 1}}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Template.itemDialog.onCreated(function(){
|
||||||
|
this.editing = new ReactiveVar(!!this.data.startEditing);
|
||||||
|
});
|
||||||
|
|
||||||
Template.itemDialog.helpers({
|
Template.itemDialog.helpers({
|
||||||
item: function(){
|
item: function(){
|
||||||
return Items.findOne(this.itemId);
|
return Items.findOne(this.itemId);
|
||||||
},
|
},
|
||||||
containers: function(){
|
editing: function(){
|
||||||
return getContainers(this.charId);
|
return Template.instance().editing.get();
|
||||||
|
},
|
||||||
|
itemHeading: function(){
|
||||||
|
if (this.quantity === 1){
|
||||||
|
return this.name;
|
||||||
|
} else {
|
||||||
|
var pName = this.plural || this.name;
|
||||||
|
return this.quantity + " " + pName;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
ne1: function(num){
|
|
||||||
return num != 1;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.itemDialog.events({
|
Template.itemDialog.events({
|
||||||
|
"tap #editButton": function(event, instance){
|
||||||
|
instance.editing.set(true);
|
||||||
|
},
|
||||||
|
"tap #doneEditingButton": function(event, instance){
|
||||||
|
instance.editing.set(false);
|
||||||
|
},
|
||||||
"color-change": function(event, instance){
|
"color-change": function(event, instance){
|
||||||
Items.update(instance.data.itemId, {$set: {color: event.color}});
|
Items.update(instance.data.itemId, {$set: {color: event.color}});
|
||||||
},
|
},
|
||||||
@@ -23,6 +41,19 @@ Template.itemDialog.events({
|
|||||||
GlobalUI.deletedToast(instance.data.itemId, "Items", "Item");
|
GlobalUI.deletedToast(instance.data.itemId, "Items", "Item");
|
||||||
GlobalUI.closeDetail();
|
GlobalUI.closeDetail();
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.itemEdit.onRendered(function(){
|
||||||
|
updatePolymerInputs(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.itemEdit.helpers({
|
||||||
|
ne1: function(num){
|
||||||
|
return num != 1;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.itemEdit.events({
|
||||||
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
|
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
|
||||||
"change #itemNameInput": function(event){
|
"change #itemNameInput": function(event){
|
||||||
var name = Template.instance().find("#itemNameInput").value;
|
var name = Template.instance().find("#itemNameInput").value;
|
||||||
@@ -50,24 +81,33 @@ Template.itemDialog.events({
|
|||||||
},
|
},
|
||||||
"change #equippedInput": function(event){
|
"change #equippedInput": function(event){
|
||||||
var equipped = Template.instance().find("#equippedInput").checked;
|
var equipped = Template.instance().find("#equippedInput").checked;
|
||||||
var item = Items.findOne(this._id);
|
if (equipped){
|
||||||
if(item){
|
Meteor.call("equipItem", this._id, this.charId);
|
||||||
if(equipped){
|
} else {
|
||||||
item.equip();
|
Meteor.call("unequipItem", this._id, this.charId);
|
||||||
} else {
|
|
||||||
item.unequip();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"change #incrementCheckbox": function(event){
|
||||||
|
var value = event.currentTarget.checked;
|
||||||
|
Items.update(this._id, {$set: {"settings.showIncrement": value}});
|
||||||
|
},
|
||||||
"change #attunementCheckbox": function(event){
|
"change #attunementCheckbox": function(event){
|
||||||
var value = event.currentTarget.checked;
|
var value = event.currentTarget.checked;
|
||||||
Items.update(this._id, {$set: {requiresAttunement: value}});
|
Items.update(this._id, {$set: {requiresAttunement: value}});
|
||||||
},
|
},
|
||||||
"core-select #containerDropDown": function(event){
|
});
|
||||||
var detail = event.originalEvent.detail;
|
|
||||||
if(!detail.isSelected) return;
|
Template.containerDropdown.helpers({
|
||||||
var containerId = detail.item.getAttribute("name");
|
containers: function(){
|
||||||
var item = Items.findOne(Template.currentData().itemId);
|
return getContainers(this.charId);
|
||||||
item.moveToContainer(containerId);
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.containerDropdown.events({
|
||||||
|
"core-select #containerDropDown": function(event){
|
||||||
|
var detail = event.originalEvent.detail;
|
||||||
|
if (!detail.isSelected) return;
|
||||||
|
var containerId = detail.item.getAttribute("name");
|
||||||
|
Meteor.call("moveItemToContainer", Template.currentData()._id, containerId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
Template.splitStackDialog.helpers({
|
Template.splitStackDialog.helpers({
|
||||||
quantity: function(){
|
quantity: function(){
|
||||||
var item = Items.findOne(this.id);
|
var item = Items.findOne(this.id);
|
||||||
if(item) return Math.round(item.quantity/2);
|
if (item) return Math.round(item.quantity / 2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.splitStackDialog.events({
|
Template.splitStackDialog.events({
|
||||||
'tap #moveButton': function(event, instance){
|
"tap #moveButton": function(event, instance){
|
||||||
var item = Items.findOne(this.id);
|
Meteor.call(
|
||||||
if(item){
|
"splitItemToParent",
|
||||||
item.splitToParent(
|
this.id,
|
||||||
{collection: this.parentCollection , id: this.parentId},
|
+instance.find("#quantityInput").value,
|
||||||
+instance.find('#quantityInput').value
|
{collection: this.parentCollection , id: this.parentId}
|
||||||
);
|
);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
'tap #oneButton':function(event, instance){
|
"tap #oneButton":function(event, instance){
|
||||||
instance.find('#quantityInput').value = 1;
|
instance.find("#quantityInput").value = 1;
|
||||||
},
|
},
|
||||||
'tap #halfButton':function(event, instance){
|
"tap #halfButton":function(event, instance){
|
||||||
instance.find('#quantityInput').value = Math.round(Items.findOne(this.id).quantity/2);
|
var val = Math.round(Items.findOne(this.id).quantity / 2);
|
||||||
|
instance.find("#quantityInput").value = val;
|
||||||
|
},
|
||||||
|
"tap #allButton":function(event, instance){
|
||||||
|
instance.find("#quantityInput").value = Items.findOne(this.id).quantity;
|
||||||
},
|
},
|
||||||
'tap #allButton':function(event, instance){
|
|
||||||
instance.find('#quantityInput').value = Items.findOne(this.id).quantity;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,25 @@
|
|||||||
<template name="classDialog">
|
<template name="classDialog">
|
||||||
{{#with class}}
|
{{#with class}}
|
||||||
{{#baseDialog title=name class=colorClass hideColor="true"}}
|
{{#baseDialog title=name class=colorClass startEditing=../startEditing}}
|
||||||
|
<div layout vertical center>
|
||||||
|
<div class="display2">
|
||||||
|
{{level}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
level
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{> effectsViewList charId=charId parentId=_id}}
|
||||||
|
{{> proficiencyViewList charId=charId parentId=_id}}
|
||||||
|
{{else}}
|
||||||
<!--Name-->
|
<!--Name-->
|
||||||
<paper-input id="classNameInput" label="Class Name" floatinglabel value={{name}}></paper-input>
|
<paper-input id="classNameInput" label="Class Name" floatinglabel value={{name}}></paper-input>
|
||||||
<!--Level-->
|
<!--Level-->
|
||||||
<paper-input id="levelValueInput" label="Level" floatinglabel value={{level}}></paper-input>
|
<paper-input id="levelValueInput" label="Level" floatinglabel value={{level}}></paper-input>
|
||||||
<!--Effects-->
|
<!--Effects-->
|
||||||
{{> effectsEditList parentId=_id parentCollection="Classes" charId=charId type="class"}}
|
{{> effectsEditList parentId=_id parentCollection="Classes" charId=charId}}
|
||||||
|
{{> proficiencyEditList parentId=_id parentCollection="Classes" charId=charId}}
|
||||||
{{/baseDialog}}
|
{{/baseDialog}}
|
||||||
{{/with}}
|
{{/with}}
|
||||||
</template>
|
</template>
|
||||||
@@ -1,4 +1,11 @@
|
|||||||
|
Template.classDialog.onRendered(function(){
|
||||||
|
updatePolymerInputs(this);
|
||||||
|
});
|
||||||
|
|
||||||
Template.classDialog.events({
|
Template.classDialog.events({
|
||||||
|
"color-change": function(event, instance){
|
||||||
|
Classes.update(instance.data.classId, {$set: {color: event.color}});
|
||||||
|
},
|
||||||
"tap #deleteButton": function(event, instance){
|
"tap #deleteButton": function(event, instance){
|
||||||
Classes.softRemoveNode(instance.data.classId);
|
Classes.softRemoveNode(instance.data.classId);
|
||||||
GlobalUI.deletedToast(instance.data.classId, "Classes", "Class");
|
GlobalUI.deletedToast(instance.data.classId, "Classes", "Class");
|
||||||
@@ -11,11 +18,11 @@ Template.classDialog.events({
|
|||||||
"change #levelValueInput": function(event){
|
"change #levelValueInput": function(event){
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Classes.update(this._id, {$set: {level: value}});
|
Classes.update(this._id, {$set: {level: value}});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.classDialog.helpers({
|
Template.classDialog.helpers({
|
||||||
class: function(){
|
class: function(){
|
||||||
return Classes.findOne(this.classId);
|
return Classes.findOne(this.classId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
<template name="experienceDialog">
|
<template name="experienceDialog">
|
||||||
{{#with experience}}
|
{{#with experience}}
|
||||||
{{#baseDialog title=name class=colorClass hideColor="true"}}
|
{{#baseDialog title=name class=color hideColor="true" startEditing=../startEditing}}
|
||||||
|
<div horizontal layout center-justified class= "display2">
|
||||||
|
{{value}}
|
||||||
|
</div>
|
||||||
|
{{#if description}}
|
||||||
|
<hr class="vertMargin">
|
||||||
|
<div class="pre-wrap">{{description}}</div>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
<div horizontal layout>
|
<div horizontal layout>
|
||||||
<!--Name-->
|
<!--Name-->
|
||||||
<paper-input id="experienceNameInput" label="Name" floatinglabel value={{name}} flex></paper-input>
|
<paper-input id="experienceNameInput" label="Name" floatinglabel value={{name}} flex></paper-input>
|
||||||
|
|||||||
@@ -1,7 +1,21 @@
|
|||||||
|
Template.experienceDialog.helpers({
|
||||||
|
experience: function(){
|
||||||
|
Experiences.findOne(this.experienceId);
|
||||||
|
return Experiences.findOne(this.experienceId);
|
||||||
|
},
|
||||||
|
color: function() {
|
||||||
|
var char = Characters.findOne(this.charId, {fields: {color: 1}});
|
||||||
|
if (char) return getColorClass(char.color);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Template.experienceDialog.events({
|
Template.experienceDialog.events({
|
||||||
"tap #deleteButton": function(event, instance){
|
"tap #deleteButton": function(event, instance){
|
||||||
Experiences.softRemove(instance.data.experienceId);
|
Experiences.softRemove(instance.data.experienceId);
|
||||||
GlobalUI.deletedToast(instance.data.experienceId, "Experiences", "Experience");
|
GlobalUI.deletedToast(
|
||||||
|
instance.data.experienceId,
|
||||||
|
"Experiences", "Experience"
|
||||||
|
);
|
||||||
GlobalUI.closeDetail();
|
GlobalUI.closeDetail();
|
||||||
},
|
},
|
||||||
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
|
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
|
||||||
@@ -16,12 +30,5 @@ Template.experienceDialog.events({
|
|||||||
"change #experienceDescriptionInput": function(event){
|
"change #experienceDescriptionInput": function(event){
|
||||||
var value = event.currentTarget.value;
|
var value = event.currentTarget.value;
|
||||||
Experiences.update(this._id, {$set: {description: value}});
|
Experiences.update(this._id, {$set: {description: value}});
|
||||||
}
|
},
|
||||||
});
|
|
||||||
|
|
||||||
Template.experienceDialog.helpers({
|
|
||||||
experience: function(){
|
|
||||||
Experiences.findOne(this.experienceId);
|
|
||||||
return Experiences.findOne(this.experienceId);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,73 +1,98 @@
|
|||||||
<template name="journal">
|
<template name="journal">
|
||||||
<div fit>
|
<div fit>
|
||||||
<div id="journal" class="scroll-y" fit>
|
<div id="journal" class="scroll-y" fit>
|
||||||
<div class="containers">
|
<div class="column-container">
|
||||||
<!--Experience Table-->
|
<!--Experience Table-->
|
||||||
<paper-shadow class="card container experiencesCard" hero-id="main" {{detailHero}}>
|
<paper-shadow class="card experiencesCard"
|
||||||
<div class="whiteTop" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
hero-id="main" {{detailHero}}>
|
||||||
<div class="containerName subhead" flex>Experience</div>
|
<div class="top white subhead"
|
||||||
<div class="subhead">{{experience}} XP</div>
|
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>
|
<paper-icon-button class="black54" id="addXP" icon="add"></paper-icon-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="containerMain experiences">
|
<div class="bottom list">
|
||||||
{{#each experiences}}
|
{{#each experiences}}
|
||||||
<div class="itemSlot">
|
<div class="item-slot">
|
||||||
<paper-item class="inventoryItem experience" hero-id="main" {{detailHero}} layout horizontal>
|
<div class="item experience"
|
||||||
<div flex>{{name}}</div><div class="xpValue">{{value}}</div>
|
hero-id="main" {{detailHero}}
|
||||||
</paper-item>
|
layout horizontal center>
|
||||||
|
<div flex>{{name}}</div>
|
||||||
|
<div class="xpValue">{{value}}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
{{#if moreExperiencesOrCollapse}}
|
{{#if moreExperiencesOrCollapse}}
|
||||||
<div class="containerFoot" layout="" horizontal="" center="" end-justified="">
|
<div layout horizontal center end-justified>
|
||||||
<paper-button id="moreExperiences" disabled={{notMoreExperiences}}>Load More</paper-button>
|
<paper-button id="moreExperiences"
|
||||||
<paper-button id="lessExperiences" disabled={{cantCollapse}}>Collapse</paper-button>
|
disabled={{notMoreExperiences}}>
|
||||||
|
Load More
|
||||||
|
</paper-button>
|
||||||
|
<paper-button id="lessExperiences"
|
||||||
|
disabled={{cantCollapse}}>
|
||||||
|
Collapse
|
||||||
|
</paper-button>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
<!--Class Table-->
|
<!--Class Table-->
|
||||||
<paper-shadow class="card container" hero-id="main" {{detailHero}}>
|
<paper-shadow class="card"
|
||||||
<div class="whiteTop" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
hero-id="main" {{detailHero}}>
|
||||||
|
<div class="white top"
|
||||||
|
hero-id="toolbar" {{detailHero}}
|
||||||
|
layout horizontal center>
|
||||||
<div flex>
|
<div flex>
|
||||||
<div class="containerName subhead">Level {{level}}</div>
|
<div class="containerName subhead">
|
||||||
|
Level {{level}}
|
||||||
|
</div>
|
||||||
{{#if nextLevelXP}}
|
{{#if nextLevelXP}}
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
Next Level: {{nextLevelXP}}XP
|
Next Level: {{nextLevelXP}}XP
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<paper-icon-button class="black54" id="addClassButton" icon="add"></paper-icon-button>
|
<paper-icon-button class="black54"
|
||||||
|
id="addClassButton"
|
||||||
|
icon="add">
|
||||||
|
</paper-icon-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="containerMain experiences">
|
<div class="bottom list">
|
||||||
<div class="itemSlot">
|
<div class="item-slot">
|
||||||
<paper-item class="inventoryItem race" hero-id="main" {{detailHero "race"}} layout horizontal>
|
<div class="item race"
|
||||||
|
hero-id="main" {{detailHero "race" _id}}
|
||||||
|
layout horizontal center>
|
||||||
{{race}}
|
{{race}}
|
||||||
</paper-item>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{#each classes}}
|
{{#each classes}}
|
||||||
<div class="itemSlot">
|
<div class="item-slot">
|
||||||
<paper-item class="inventoryItem class" hero-id="main" {{detailHero}} layout horizontal>
|
<div class="item class"
|
||||||
|
hero-id="main" {{detailHero}}
|
||||||
|
layout horizontal center>
|
||||||
{{name}} {{level}}
|
{{name}} {{level}}
|
||||||
</paper-item>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
<!--Notes-->
|
<!--Notes-->
|
||||||
{{#each notes}}
|
{{#each notes}}
|
||||||
<paper-shadow class="card container" hero-id="main" {{detailHero}}>
|
<paper-shadow class="card" hero-id="main" {{detailHero}}>
|
||||||
<div class="containerTop {{colorClass}} noteTop" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
<div class="top {{colorClass}} noteTop subhead"
|
||||||
<div flex>
|
hero-id="toolbar" {{detailHero}}
|
||||||
<div class="containerName subhead">{{name}}</div>
|
layout horizontal center>
|
||||||
</div>
|
{{name}}
|
||||||
</div>
|
</div>
|
||||||
<div class="containerMain preline">{{description}}</div>
|
<div class="bottom text">{{description}}</div>
|
||||||
</paper-shadow>
|
</paper-shadow>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
<div class="fab-buffer"></div>
|
<div class="fab-buffer"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{#if canEditCharacter _id}}
|
||||||
<paper-fab id="addNote"
|
<paper-fab id="addNote"
|
||||||
class="floatyButton"
|
class="floatyButton"
|
||||||
icon="add"
|
icon="add"
|
||||||
@@ -75,4 +100,5 @@
|
|||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
hero-id="main"></paper-fab>
|
hero-id="main"></paper-fab>
|
||||||
|
{{/if}}
|
||||||
</template>
|
</template>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user