Implemented Spell Dialogs
This commit is contained in:
@@ -6,7 +6,7 @@ Schemas.Spell = new SimpleSchema({
|
||||
prepared: {type: String, defaultValue: "unprepared", allowedValues: ["prepared","unprepared","always"]},
|
||||
name: {type: String},
|
||||
description: {type: String, optional: true},
|
||||
castingTime: {type: String, optional: true},
|
||||
castingTime: {type: String, defaultValue: "action"},
|
||||
range: {type: String, optional: true},
|
||||
duration: {type: String, optional: true},
|
||||
"components.verbal": {type: Boolean, defaultValue: false},
|
||||
@@ -14,7 +14,9 @@ Schemas.Spell = new SimpleSchema({
|
||||
"components.material": {type: String, optional: true},
|
||||
"components.concentration": {type: Boolean, defaultValue: false},
|
||||
ritual: {type: Boolean, defaultValue: false},
|
||||
level: {type: Number, defaultValue: 0}
|
||||
level: {type: Number, defaultValue: 0},
|
||||
school: {type: String, defaultValue: "Abjuration", allowedValues: magicSchools},
|
||||
color: {type: String, allowedValues: _.keys(colorOptions), defaultValue: "green"}
|
||||
});
|
||||
|
||||
Spells.attachSchema(Schemas.Spell);
|
||||
|
||||
@@ -14,7 +14,8 @@ Schemas.Item = new SimpleSchema({
|
||||
defaultValue: "none",
|
||||
allowedValues: ["none", "head", "armor", "arms", "hands", "held", "feet"]
|
||||
},
|
||||
equipped: {type: Boolean, defaultValue: false}
|
||||
equipped: {type: Boolean, defaultValue: false},
|
||||
color: {type: String, allowedValues: _.keys(colorOptions), defaultValue: "green"}
|
||||
});
|
||||
|
||||
Items.attachSchema(Schemas.Item);
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
Template.registerHelper("colorClass", function(color){
|
||||
return color? getColorClass(color) : getColorClass(this.color);
|
||||
});
|
||||
|
||||
Template.registerHelper("hexColor", function(color){
|
||||
return colorOptions[color].color;
|
||||
});
|
||||
|
||||
@@ -132,3 +132,7 @@ paper-fab-menu /deep/ .container {
|
||||
padding-left: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fullwidth {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,14 @@
|
||||
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;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</core-toolbar>
|
||||
<div class="detailContent">
|
||||
<!--Name and plural name-->
|
||||
<paper-input id="itemNameInput" label="Name" floatinglabel value={{name}}></paper-input>
|
||||
<paper-input id="itemNameInput" class="fullwidth" label="Name" floatinglabel value={{name}}></paper-input>
|
||||
{{# if ne1 quantity}}<paper-input id="itemPluralInput" label="Plural Name" floatinglabel value={{plural}}></paper-input>{{/if}}
|
||||
<!--Equipped-->
|
||||
{{# if canEquip}}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<template name="spellDialog">
|
||||
{{#with spell}}
|
||||
<core-header-panel fit class="spellDialog">
|
||||
<core-toolbar hero-id="toolbar" class={{colorClass}} hero>
|
||||
<paper-icon-button id="backButton" role="button" tabindex="0" icon="arrow-back" aria-label="close"></paper-icon-button>
|
||||
<div flex hero-id="title" hero>{{name}}</div>
|
||||
<paper-icon-button id="deleteSpell"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
icon="delete"
|
||||
aria-label="Delete Feature"
|
||||
noink></paper-icon-button>
|
||||
</core-toolbar>
|
||||
<div class="detailContent">
|
||||
<!--Name-->
|
||||
<div horizontal layout>
|
||||
<paper-input id="spellNameInput" label="Name" floatinglabel value={{name}} flex></paper-input>
|
||||
<!--Color-->
|
||||
{{> colorDropdown}}<br>
|
||||
</div>
|
||||
<!--List dropdown-->
|
||||
<paper-dropdown-menu id="listDropdown" label="Spell List">
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu class="menu" selected={{listId}}>
|
||||
{{#each spellLists}}
|
||||
<paper-item name={{_id}} class="containerMenuItem">{{name}}</paper-item>
|
||||
{{/each}}
|
||||
</core-menu>
|
||||
</paper-dropdown>
|
||||
</paper-dropdown-menu>
|
||||
<!--Level-->
|
||||
<paper-dropdown-menu id="levelDropdown" label="Level">
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu class="menu" selected={{level}}>
|
||||
{{#each spellLevels}}
|
||||
<paper-item name={{level}} class="containerMenuItem">{{name}}</paper-item>
|
||||
{{/each}}
|
||||
</core-menu>
|
||||
</paper-dropdown>
|
||||
</paper-dropdown-menu>
|
||||
<!--School-->
|
||||
<paper-dropdown-menu id="schoolDropdown" label="School">
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu class="menu" selected={{school}}>
|
||||
{{#each magicSchools}}
|
||||
<paper-item name={{this}} class="containerMenuItem">{{this}}</paper-item>
|
||||
{{/each}}
|
||||
</core-menu>
|
||||
</paper-dropdown>
|
||||
</paper-dropdown-menu>
|
||||
<!--Prepared-->
|
||||
<paper-dropdown-menu id="preparedDropdown" label="School">
|
||||
<paper-dropdown layered class="dropdown">
|
||||
<core-menu class="menu" selected={{prepared}}>
|
||||
{{#each preparedOptions}}
|
||||
<paper-item name={{value}} class="containerMenuItem">{{name}}</paper-item>
|
||||
{{/each}}
|
||||
</core-menu>
|
||||
</paper-dropdown>
|
||||
</paper-dropdown-menu>
|
||||
<!--Casting Time-->
|
||||
<paper-input id="castingTimeInput" class="fullwidth" label="Casting Time" floatinglabel value={{castingTime}} flex></paper-input>
|
||||
<!--Range-->
|
||||
<paper-input id="rangeInput" class="fullwidth" label="Range" floatinglabel value={{range}} flex></paper-input>
|
||||
<!--Duration-->
|
||||
<paper-input id="durationInput" class="fullwidth" label="Duration" floatinglabel value={{duration}} flex></paper-input>
|
||||
<!--Components-->
|
||||
<div horizontal layout wrap>
|
||||
<div>Verbal:</div>
|
||||
<paper-checkbox id="verbalCheckbox" checked={{components.verbal}}></paper-checkbox>
|
||||
<div>Somatic:</div>
|
||||
<paper-checkbox id="somaticCheckbox" checked={{components.somatic}}></paper-checkbox>
|
||||
<div>Concentration:</div>
|
||||
<paper-checkbox id="concentrationCheckbox" checked={{components.concentration}}></paper-checkbox>
|
||||
<!--Ritual-->
|
||||
<div>Ritual: </div>
|
||||
<paper-checkbox id="ritualCheckbox" checked={{ritual}}></paper-checkbox>
|
||||
</div>
|
||||
<paper-input id="materialInput" class="fullwidth" label="Material Components" floatinglabel value={{components.material}} flex></paper-input>
|
||||
<!--Description-->
|
||||
<paper-input-decorator label="Description" floatinglabel layout vertical>
|
||||
<paper-autogrow-textarea>
|
||||
<textarea id="descriptionInput" placeholder value={{description}}></textarea>
|
||||
</paper-autogrow-textarea>
|
||||
</paper-input-decorator>
|
||||
</div>
|
||||
</core-header-panel>
|
||||
{{/with}}
|
||||
</template>
|
||||
@@ -0,0 +1,138 @@
|
||||
var spellLevels = [
|
||||
{ name: "Cantrips", level: 0 },
|
||||
{ name: "Level 1", level: 1 },
|
||||
{ name: "Level 2", level: 2 },
|
||||
{ name: "Level 3", level: 3 },
|
||||
{ name: "Level 4", level: 4 },
|
||||
{ name: "Level 5", level: 5 },
|
||||
{ name: "Level 6", level: 6 },
|
||||
{ name: "Level 7", level: 7 },
|
||||
{ name: "Level 8", level: 8 },
|
||||
{ name: "Level 9", level: 9 },
|
||||
];
|
||||
|
||||
Template.spellDialog.rendered = function(){
|
||||
var self = this;
|
||||
//update all autogrows after they've been filled
|
||||
var pata = this.$("paper-autogrow-textarea");
|
||||
pata.each(function(index, el){
|
||||
el.update($(el).children().get(0));
|
||||
})
|
||||
//update all input fields as well
|
||||
var input = this.$("paper-input");
|
||||
input.each(function(index, el){
|
||||
el.valueChanged();
|
||||
})
|
||||
//after the dialog is built, open it
|
||||
if (!this.alreadyRendered){
|
||||
Session.set("global.ui.detailShow", true);
|
||||
this.alreadyRendered = true;
|
||||
}
|
||||
}
|
||||
|
||||
Template.spellDialog.events({
|
||||
"tap #backButton": function(){
|
||||
GlobalUI.closeDetail();
|
||||
},
|
||||
"tap #deleteSpell": function(){
|
||||
Spells.remove(this._id);
|
||||
GlobalUI.closeDetail();
|
||||
},
|
||||
//TODO clean up String -> num here so they don't need casting by Schema.clean
|
||||
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
|
||||
"change #spellNameInput, input #spellNameInput": function(event){
|
||||
var value = event.currentTarget.value
|
||||
Spells.update(this._id, {$set: {name: value}});
|
||||
},
|
||||
"change #castingTimeInput": function(event){
|
||||
var value = event.currentTarget.value
|
||||
Spells.update(this._id, {$set: {castingTime: value}});
|
||||
},
|
||||
"change #rangeInput": function(event){
|
||||
var value = event.currentTarget.value
|
||||
Spells.update(this._id, {$set: {range: value}});
|
||||
},
|
||||
"change #durationInput": function(event){
|
||||
var value = event.currentTarget.value
|
||||
Spells.update(this._id, {$set: {duration: value}});
|
||||
},
|
||||
"change #materialInput": function(event){
|
||||
var value = event.currentTarget.value
|
||||
Spells.update(this._id, {$set: {"components.material": value}});
|
||||
},
|
||||
"change #descriptionInput": function(event){
|
||||
var value = event.currentTarget.value
|
||||
Spells.update(this._id, {$set: {"description": value}});
|
||||
},
|
||||
"core-select #listDropdown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var value = detail.item.getAttribute("name");
|
||||
Spells.update(this._id, {$set: {listId: value}});
|
||||
},
|
||||
"core-select #levelDropdown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var value = detail.item.getAttribute("name");
|
||||
Spells.update(this._id, {$set: {level: value}});
|
||||
},
|
||||
"core-select #schoolDropdown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var value = detail.item.getAttribute("name");
|
||||
Spells.update(this._id, {$set: {school: value}});
|
||||
},
|
||||
"core-select #preparedDropdown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var value = detail.item.getAttribute("name");
|
||||
Spells.update(this._id, {$set: {prepared: value}});
|
||||
},
|
||||
"core-select .colorDropdown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
var value = detail.item.getAttribute("name");
|
||||
Spells.update(this._id, {$set: {color: value}});
|
||||
},
|
||||
"change #verbalCheckbox": function(event){
|
||||
var value = event.currentTarget.checked;
|
||||
Spells.update(this._id, {$set: {"components.verbal": value}});
|
||||
},
|
||||
"change #somaticCheckbox": function(event){
|
||||
var value = event.currentTarget.checked;
|
||||
Spells.update(this._id, {$set: {"components.somatic": value}});
|
||||
},
|
||||
"change #concentrationCheckbox": function(event){
|
||||
var value = event.currentTarget.checked;
|
||||
Spells.update(this._id, {$set: {"components.concentration": value}});
|
||||
},
|
||||
"change #ritualCheckbox": function(event){
|
||||
var value = event.currentTarget.checked;
|
||||
Spells.update(this._id, {$set: {"ritual": value}});
|
||||
},
|
||||
});
|
||||
|
||||
Template.spellDialog.helpers({
|
||||
spell: function(){
|
||||
return Spells.findOne(this.spellId);
|
||||
},
|
||||
colorClass: function(){
|
||||
return getColorClass(this.color)
|
||||
},
|
||||
spellLists: function(){
|
||||
return SpellLists.find({charId: this.charId}, {fields: {name: 1}});
|
||||
},
|
||||
magicSchools: function(){
|
||||
return magicSchools;
|
||||
},
|
||||
spellLevels: function(){
|
||||
return spellLevels;
|
||||
},
|
||||
preparedOptions: function(){
|
||||
return [
|
||||
{name: "Prepared", value: "prepared"},
|
||||
{name: "Unprepared", value: "unprepared"},
|
||||
{name: "Always Prepared", value: "always"}
|
||||
];
|
||||
}
|
||||
});
|
||||
@@ -43,6 +43,7 @@ Template.spellListDialog.events({
|
||||
var value = event.currentTarget.value
|
||||
SpellLists.update(this._id, {$set: {maxPrepared: value}});
|
||||
},
|
||||
//TODO change #spellListDescription
|
||||
"core-select .colorDropdown": function(event){
|
||||
var detail = event.originalEvent.detail;
|
||||
if(!detail.isSelected) return;
|
||||
|
||||
8
rpg-docs/client/views/character/spells/spells.css
Normal file
8
rpg-docs/client/views/character/spells/spells.css
Normal file
@@ -0,0 +1,8 @@
|
||||
#spells .inventoryItem {
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
#spells .inventoryItem core-icon{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
@@ -26,10 +26,19 @@
|
||||
{{/if}}
|
||||
{{#each spells ../_id ../../_id}}
|
||||
<div class="itemSlot">
|
||||
<paper-item class="inventoryItem" hero-id="main" {{detailHero}} layout horizontal center>
|
||||
<core-icon icon="social:whatshot"></core-icon>
|
||||
<div flex>{{name}}</div>
|
||||
<paper-icon-button class="castButton" icon="send"></paper-icon-button>
|
||||
<paper-item class="inventoryItem spell" hero-id="main" {{detailHero}} layout horizontal center>
|
||||
<core-icon icon="social:whatshot" style="color: {{hexColor color}};"></core-icon>
|
||||
<div flex layout vertical>
|
||||
<div>{{name}}</div>
|
||||
<div class="caption">
|
||||
{{school}} {{castingTime}}{{#if ritual}} (ritual){{/if}} - {{spellComponents}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if ../../settings.showUnprepared}}
|
||||
<paper-checkbox class="preparedCheckbox" checked={{isPrepared}} disabled={{cantUnprepare}}></paper-checkbox>
|
||||
{{else}}
|
||||
<paper-icon-button class="castButton" icon="send"></paper-icon-button>
|
||||
{{/if}}
|
||||
</paper-item>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
@@ -29,6 +29,29 @@ Template.spells.helpers({
|
||||
},
|
||||
order: function(){
|
||||
return _.indexOf(_.keys(colorOptions), this.color);
|
||||
},
|
||||
spellComponents: function(){
|
||||
var components = "";
|
||||
if(this.components.verbal){
|
||||
components += "V"
|
||||
}
|
||||
if(this.components.somatic){
|
||||
components += components? ", S" : "S";
|
||||
}
|
||||
if(this.components.material){
|
||||
components += components? ", M" : "M";
|
||||
components += "("+this.components.material+")";
|
||||
}
|
||||
if(this.components.concentration){
|
||||
components += " - Requires concentration"
|
||||
}
|
||||
return components;
|
||||
},
|
||||
isPrepared: function(){
|
||||
return this.prepared === "prepared" || this.prepared === "always";
|
||||
},
|
||||
cantUnprepare: function(){
|
||||
return this.prepared === "always";
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,6 +63,13 @@ Template.spells.events({
|
||||
heroId: this._id
|
||||
});
|
||||
},
|
||||
"tap .spell": function(event){
|
||||
GlobalUI.setDetail({
|
||||
template: "spellDialog",
|
||||
data: {spellId: this._id, charId: this.charId},
|
||||
heroId: this._id
|
||||
});
|
||||
},
|
||||
"tap #addSpellList": function(event){
|
||||
var charId = this.charId;
|
||||
SpellLists.insert({
|
||||
@@ -57,10 +87,31 @@ Template.spells.events({
|
||||
}
|
||||
});
|
||||
},
|
||||
"downAction .castButton": function(event){
|
||||
event.stopPropagation()
|
||||
"tap #addSpell": function(event){
|
||||
var charId = this.charId;
|
||||
var listId = this.listId;
|
||||
Spells.insert({
|
||||
name: "New Spell",
|
||||
charId: this._id,
|
||||
listId: SpellLists.findOne({charId: this._id})._id
|
||||
}, function(error, id){
|
||||
if(!error){
|
||||
GlobalUI.setDetail({
|
||||
template: "spellDialog",
|
||||
data: {spellId: id, charId: charId, listId: listId},
|
||||
heroId: id
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
"upAction .castButton": function(event){
|
||||
event.stopPropagation()
|
||||
"tap .preparedCheckbox": function(event){
|
||||
event.stopPropagation();
|
||||
},
|
||||
"change .preparedCheckbox": function(event){
|
||||
var value = event.currentTarget.checked;
|
||||
if(this.prepared === "unprepared" && value)
|
||||
Spells.update(this._id, {$set: {prepared: "prepared"}});
|
||||
else if(this.prepared === "prepared" && !value)
|
||||
Spells.update(this._id, {$set: {prepared: "unprepared"}});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<!--paper components-->
|
||||
<link rel="import" href="/components/paper-button/paper-button.html">
|
||||
<link rel="import" href="/components/paper-checkbox/paper-checkbox.html">
|
||||
<link rel="import" href="/components/paper-dialog/paper-action-dialog.html">
|
||||
<link rel="import" href="/components/paper-dialog/paper-dialog.html">
|
||||
<link rel="import" href="/components/paper-dialog/paper-dialog-transition.html">
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
colorOptions = {
|
||||
"red": {whiteText: true},
|
||||
"pink": {whiteText: true},
|
||||
"purple": {whiteText: true},
|
||||
"deep-purple": {whiteText: true},
|
||||
"indigo": {whiteText: true},
|
||||
"blue": {whiteText: true},
|
||||
"light-blue": {whiteText: true},
|
||||
"cyan": {whiteText: true},
|
||||
"teal": {whiteText: true},
|
||||
"green": {whiteText: true},
|
||||
"light-green": {whiteText: true},
|
||||
"lime": {whiteText: false},
|
||||
"yellow": {whiteText: false},
|
||||
"amber": {whiteText: false},
|
||||
"orange": {whiteText: false},
|
||||
"deep-orange": {whiteText: true},
|
||||
"brown": {whiteText: true},
|
||||
"grey": {whiteText: true}, //spec says no white text
|
||||
"blue-grey": {whiteText: true},
|
||||
"black": {whiteText: true},
|
||||
"red": {whiteText: true, color: "#F44336"},
|
||||
"pink": {whiteText: true, color: "#E91E63"},
|
||||
"purple": {whiteText: true, color: "#9C27B0"},
|
||||
"deep-purple": {whiteText: true, color: "#673AB7"},
|
||||
"indigo": {whiteText: true, color: "#3F51B5"},
|
||||
"blue": {whiteText: true, color: "#2196F3"},
|
||||
"light-blue": {whiteText: true, color: "#03A9F4"},
|
||||
"cyan": {whiteText: true, color: "#00BCD4"},
|
||||
"teal": {whiteText: true, color: "#009688"},
|
||||
"green": {whiteText: true, color: "#4CAF50"},
|
||||
"light-green": {whiteText: true, color: "#8BC34A"},
|
||||
"lime": {whiteText: false, color: "#CDDC39"},
|
||||
"yellow": {whiteText: false, color: "#FFEB3B"},
|
||||
"amber": {whiteText: false, color: "#FFC107"},
|
||||
"orange": {whiteText: false, color: "#FF9800"},
|
||||
"deep-orange": {whiteText: true, color: "#FF5722"},
|
||||
"grey": {whiteText: true, color: "#9E9E9E"}, //spec says no white text
|
||||
//"blue-grey": {whiteText: true, color: "#607D8B"},
|
||||
"brown": {whiteText: true, color: "#795548"},
|
||||
"black": {whiteText: true, color: "#000000"},
|
||||
};
|
||||
|
||||
getColorClass = function(key){
|
||||
|
||||
9
rpg-docs/lib/constants/magicSchools.js
Normal file
9
rpg-docs/lib/constants/magicSchools.js
Normal file
@@ -0,0 +1,9 @@
|
||||
magicSchools = [
|
||||
"Abjuration",
|
||||
"Conjuration",
|
||||
"Divination",
|
||||
"Enchantment",
|
||||
"Evocation",
|
||||
"Illusion",
|
||||
"Necromancy"
|
||||
];
|
||||
Reference in New Issue
Block a user