diff --git a/client/naturalCrit/encounter/encounter.jsx b/client/naturalCrit/encounter/encounter.jsx index cfee03b..faf3114 100644 --- a/client/naturalCrit/encounter/encounter.jsx +++ b/client/naturalCrit/encounter/encounter.jsx @@ -68,15 +68,16 @@ var Encounter = React.createClass({ getPlayerObjects : function(){ - return _.map(this.props.players.split('\n'), function(line){ + return _.reduce(this.props.players.split('\n'), function(r, line){ var parts = line.split(' '); - if(parts.length != 2) return null; - return { + if(parts.length != 2) return r; + r.push({ name : parts[0], initiative : parts[1] * 1, isPC : true - } - }) + }) + return r; + },[]) }, @@ -84,7 +85,7 @@ var Encounter = React.createClass({ var self = this; var sortedEnemies = _.sortBy(_.union(_.values(this.state.enemies), this.getPlayerObjects()), function(e){ - if(e.initiative) return -e.initiative; + if(e && e.initiative) return -e.initiative; return 0; }); diff --git a/client/naturalCrit/encounter/monsterCard/monsterCard.jsx b/client/naturalCrit/encounter/monsterCard/monsterCard.jsx index 4796580..0c663fd 100644 --- a/client/naturalCrit/encounter/monsterCard/monsterCard.jsx +++ b/client/naturalCrit/encounter/monsterCard/monsterCard.jsx @@ -131,13 +131,10 @@ var MonsterCard = React.createClass({ var self = this; var usedItems = this.state.usedItems.slice(0); return _.map(this.props.items, function(item, index){ - var used = _.contains(usedItems, item); - if(used){ usedItems.splice(usedItems.indexOf(item), 1); } - return - +
+ {this.props.abilities} +
+ {this.renderItems()}
- ); } diff --git a/client/naturalCrit/encounter/monsterCard/monsterCard.less b/client/naturalCrit/encounter/monsterCard/monsterCard.less index 553edc4..22e4356 100644 --- a/client/naturalCrit/encounter/monsterCard/monsterCard.less +++ b/client/naturalCrit/encounter/monsterCard/monsterCard.less @@ -1,4 +1,5 @@ +@marginSize : 10px; .noselect(){ -webkit-touch-callout : none; -webkit-user-select : none; @@ -7,9 +8,6 @@ -ms-user-select : none; user-select : none; } - -@marginSize : 10px; - .playerCard{ display : inline-block; box-sizing : border-box; @@ -17,25 +15,21 @@ padding : 10px; background-color : white; border : 1px solid #bbb; - .name{ - margin-right: 20px; + margin-right : 20px; } .initiative{ - font-size: 0.8em; + font-size : 0.8em; i{ - font-size: 0.8em; + font-size : 0.8em; } } - &:nth-child(5n + 1){ background-color: fade(@blue, 25%); } &:nth-child(5n + 2){ background-color: fade(@purple, 25%); } &:nth-child(5n + 3){ background-color: fade(@steel, 25%); } &:nth-child(5n + 4){ background-color: fade(@green, 25%); } &:nth-child(5n + 5){ background-color: fade(@orange, 25%); } } - - .monsterCard{ position : relative; display : inline-block; @@ -50,19 +44,19 @@ position : absolute; top : 0px; left : 0px; + z-index : 50; height : 3px; max-width : 100%; background-color : @green; - z-index : 50; } .overhealbar{ position : absolute; top : 0px; left : 0px; + z-index : 100; height : 3px; max-width : 100%; background-color : @blueLight; - z-index : 100; } &.hurt{ .healthbar{ @@ -70,26 +64,25 @@ } } &.last_legs{ - background-color: lighten(@red, 49%); + background-color : lighten(@red, 49%); .healthbar{ background-color : red; } } &.dead{ - opacity: 0.3; + opacity : 0.3; } - &>.info{ - margin-bottom: 10px; + margin-bottom : 10px; .name{ - font-size: 1.5em; - margin-right: 10px; + margin-right : 10px; + font-size : 1.5em; } .stat{ - font-size: 0.7em; - margin-right: 5px; + margin-right : 5px; + font-size : 0.7em; i{ - font-size: 0.7em; + font-size : 0.7em; } } } @@ -118,17 +111,21 @@ font-weight : 800; } } - + .abilitiesContainer{ + margin-top : 5px; + } .itemContainer{ - + margin-top : 5px; + i{ + font-size : 0.7em; + } span{ - cursor: pointer; - font-size: 0.7em; - margin-right: 5px; + margin-right : 5px; + cursor : pointer; + font-size : 0.7em; &.used{ - text-decoration: line-through; + text-decoration : line-through; } } - } } \ No newline at end of file diff --git a/client/naturalCrit/favicon.ico b/client/naturalCrit/favicon.ico new file mode 100644 index 0000000..090aeb8 Binary files /dev/null and b/client/naturalCrit/favicon.ico differ diff --git a/client/naturalCrit/naturalCrit.jsx b/client/naturalCrit/naturalCrit.jsx index 8870ba6..8dd7b41 100644 --- a/client/naturalCrit/naturalCrit.jsx +++ b/client/naturalCrit/naturalCrit.jsx @@ -47,7 +47,7 @@ var encounters = [ ]; -var MonsterManual = { +var monsterManual = { 'goblin' : { "hp" : 40, "mov": 30, @@ -97,69 +97,48 @@ var NaturalCrit = React.createClass({ getInitialState: function() { var self = this; - return { - selectedEncounterIndex : 0, + encounters : JSON.parse(localStorage.getItem('encounters')) || encounters, + monsterManual : JSON.parse(localStorage.getItem('monsterManual')) || monsterManual, - encounters : encounters, - monsterManual : MonsterManual, - - players : 'jasper 13' + players : localStorage.getItem('players') || 'jasper 13\nzatch 19' }; }, - createEnemy : function(type, index){ - var stats = MonsterManual[type] - return _.extend({ - id : type + index, - name : type, - currentHP : stats.hp, - initiative : _.random(1,20) + attrMod(stats.attr.dex) - }, stats); - }, - addPC : function(name, initiative){ - this.state.enemies[name] = { - name : name, - id : name, - initiative : initiative, - isPC : true - }; - this.setState({ - enemies : this.state.enemies - }) - - }, - - - addRandomPC : function(){ - this.addPC( - _.sample(['zatch', 'jasper', 'el toro', 'tulik']) + _.random(1,1000), - _.random(1,25) - ) - }, - - - - handleJSONChange : function(encounterIndex, json){ + handleEncounterJSONChange : function(encounterIndex, json){ this.state.encounters[encounterIndex] = json; this.setState({ encounters : this.state.encounters }) + localStorage.setItem("encounters", JSON.stringify(this.state.encounters)); }, - handleEncounterChange : function(encounterIndex){ + handleMonsterManualJSONChange : function(json){ this.setState({ - selectedEncounterIndex : encounterIndex + monsterManual : json }); + localStorage.setItem("monsterManual", JSON.stringify(this.state.monsterManual)); }, handlePlayerChange : function(e){ this.setState({ players : e.target.value }); + localStorage.setItem("players", e.target.value); + }, + handleSelectedEncounterChange : function(encounterIndex){ + this.setState({ + selectedEncounterIndex : encounterIndex + }); + }, + handleRemoveEncounter : function(encounterIndex){ + this.state.encounters.splice(encounterIndex, 1); + this.setState({ + encounters : this.state.encounters + }); + localStorage.setItem("encounters", JSON.stringify(this.state.encounters)); }, - renderSelectedEncounter : function(){ var self = this; @@ -183,9 +162,6 @@ var NaturalCrit = React.createClass({ render : function(){ var self = this; - - console.log(this.state.encounters); - return(
- {this.renderSelectedEncounter()} + {this.renderSelectedEncounter()}
); diff --git a/client/naturalCrit/sidebar/sidebar.jsx b/client/naturalCrit/sidebar/sidebar.jsx index 894ef96..0a4e0b9 100644 --- a/client/naturalCrit/sidebar/sidebar.jsx +++ b/client/naturalCrit/sidebar/sidebar.jsx @@ -15,8 +15,9 @@ var Sidebar = React.createClass({ onSelectEncounter : function(){}, onJSONChange : function(encounterIndex, json){}, - + onMonsterManualChange : function(json){}, onPlayerChange : function(){}, + onRemoveEncounter : function(encounterIndex){} }; }, @@ -33,17 +34,14 @@ var Sidebar = React.createClass({ }, handleJSONChange : function(encounterIndex, json){ - - this.props.onJSONChange(encounterIndex, json); - - }, - handleSelectEncounter : function(encounterIndex){ - console.log(encounterIndex); this.props.onSelectEncounter(encounterIndex); }, + handleRemoveEncounter : function(encounterIndex){ + this.props.onRemoveEncounter(encounterIndex); + }, renderEncounters : function(){ var self = this; @@ -53,7 +51,7 @@ var Sidebar = React.createClass({ var isSelected = self.props.selectedEncounter == index; return
- @@ -64,6 +62,8 @@ var Sidebar = React.createClass({ json={encounter} onJSONChange={self.handleJSONChange.bind(self, index)} /> + +
}) }, @@ -81,11 +81,20 @@ var Sidebar = React.createClass({
- - +
+
-

Encounters

+

+ Encounters + +

{this.renderEncounters()}
diff --git a/client/naturalCrit/sidebar/sidebar.less b/client/naturalCrit/sidebar/sidebar.less index 8f6d9f5..60149e1 100644 --- a/client/naturalCrit/sidebar/sidebar.less +++ b/client/naturalCrit/sidebar/sidebar.less @@ -41,6 +41,7 @@ cursor : pointer; fill : white; } + span.name{ .animateAll(); position : absolute; @@ -68,17 +69,51 @@ .encounterContainer{ margin-bottom : 20px; h3{ - background-color : fade(@red, 25%); + background-color : @red; + color : white; + + button{ + outline: none; + border : none; + cursor: pointer; + background-color: transparent; + .animate(color); + float : right; + &:hover{ + color : white; + } + } } .encounter{ + padding-left: 20px; + position: relative; + i.remove{ + position: absolute; + top : 3px; + right : 3px; + font-size: 0.6em; + cursor: pointer; + color : #333; + &:hover{ + color: @red; + } + } + i.select{ + cursor: pointer; + } + .jsonFileEditor{ + display: inline-block; + } &.selected{ - background-color : @green; + background-color : fade(@green, 30%); } } } .addPlayers{ h3{ - background-color : fade(@purple, 25%); + //background-color : fade(@purple, 25%); + color : white; + background-color: @purple; } textarea{ height : 80px; diff --git a/client/template.dot b/client/template.dot index 708c46e..ae3c5e3 100644 --- a/client/template.dot +++ b/client/template.dot @@ -7,7 +7,7 @@ {{=vitreum.css}} {{=vitreum.globals}} - NaturalCrit + Natural Crit - D&D Combat Manager
{{=vitreum.component}}
diff --git a/shared/naturalCrit/jsonFileEditor/jsonFileEditor.jsx b/shared/naturalCrit/jsonFileEditor/jsonFileEditor.jsx index e341153..d0d78c1 100644 --- a/shared/naturalCrit/jsonFileEditor/jsonFileEditor.jsx +++ b/shared/naturalCrit/jsonFileEditor/jsonFileEditor.jsx @@ -2,29 +2,16 @@ var React = require('react'); var _ = require('lodash'); var cx = require('classnames'); - var JSONEditor = require('jsoneditor'); -//var editor = new JSONEditor(container); - -var json = { - test : 6, - arr : [true, 1,2,3,4], - yo : { - yeah : true - } -} var downloadFile = function(filename, text) { var element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); element.setAttribute('download', filename); - element.style.display = 'none'; document.body.appendChild(element); - element.click(); - document.body.removeChild(element); } @@ -32,10 +19,8 @@ var downloadFile = function(filename, text) { var JsonFileEditor = React.createClass({ getDefaultProps: function() { return { - name : "yo", - - json : json, - + name : "test", + json : {}, onJSONChange : function(){} }; }, @@ -45,11 +30,11 @@ var JsonFileEditor = React.createClass({ showEditor: false }; }, - componentWillReceiveProps: function(nextProps) { - //this.editor.set(nextProps.json); + if(JSON.stringify(nextProps.json) != JSON.stringify(this.editor.get())){ + this.editor.set(nextProps.json); + } }, - componentDidMount: function() { this.editor = new JSONEditor(this.refs.editor, { change : this.handleJSONChange, @@ -57,23 +42,14 @@ var JsonFileEditor = React.createClass({ }, this.props.json) }, - - - handleJSONChange : function(){ - this.props.onJSONChange(this.editor.get()); - - //try to store in local storage? - }, - handleShowEditorClick : function(){ this.setState({ showEditor : !this.state.showEditor }) }, - handleDownload : function(){ downloadFile(this.props.name + '.json', JSON.stringify(this.props.json, null, '\t')); }, @@ -88,12 +64,6 @@ var JsonFileEditor = React.createClass({ handleUploadClick : function(){ this.refs.uploader.click() }, - handleRemove : function(){ - - - - }, - renderEditor : function(){ return
@@ -104,23 +74,14 @@ var JsonFileEditor = React.createClass({ var self = this; return(
- {this.props.name} -
- - - - - -
- {this.renderEditor()}
diff --git a/shared/naturalCrit/jsonFileEditor/jsonFileEditor.less b/shared/naturalCrit/jsonFileEditor/jsonFileEditor.less index 26169b7..7ab8fbc 100644 --- a/shared/naturalCrit/jsonFileEditor/jsonFileEditor.less +++ b/shared/naturalCrit/jsonFileEditor/jsonFileEditor.less @@ -2,34 +2,52 @@ @import (less) "./jsoneditor.css"; .jsonFileEditor{ position : relative; - width : 100%; + padding : 10px; &.showEditor{ .jsonEditor{ display : initial; } } - .jsonEditor{ position : absolute; display : none; top : 100%; left : 0px; z-index : 1000; + min-width : 400px; background-color : white; } .name{ display : inline-block; font-size : 0.8em; font-weight : 800; + min-width: 100px; } .controls{ - position : absolute; - top : 0px; - right : 0px; + display: inline-block; + float: right; + //position : absolute; + //top : 0px; + //right : 0px; + button{ + outline: none; + border : none; + cursor: pointer; + background-color: transparent; + .animate(color); + + &:hover{ + &.showEditor{ color : @green; } + &.downloadJSON{ color : @blue; } + &.uploadJSON{ color : @orange; } + } + + + + } } - input[type="file"]{ - display: none; + display : none; } } \ No newline at end of file