mirror of
https://github.com/stolksdorf/homebrewery.git
synced 2025-12-13 05:25:58 +00:00
Workign on the homebrew
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\homebrew\\homebrew.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"marked"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\shared\\naturalCrit\\defaultMonsterManual.js": [],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\shared\\naturalCrit\\combat.actions.js": [
|
||||
"pico-flux"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\shared\\naturalCrit\\rollDice.js": [
|
||||
"lodash"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\combatManager\\sidebar\\dmDice\\dmDice.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"naturalCrit/rollDice"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\shared\\naturalCrit\\jsonFileEditor\\jsonFileEditor.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"jsoneditor"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\combatManager\\encounter\\monsterCard\\attackSlot\\attackSlot.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"naturalCrit/rollDice"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\combatManager\\encounter\\monsterCard\\monsterCard.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"./attackSlot/attackSlot.jsx"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\combatManager\\encounter\\encounter.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"naturalCrit/combat.store.js",
|
||||
"./monsterCard/monsterCard.jsx"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\combatManager\\sidebar\\encounters\\encounters.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"naturalCrit/combat.store.js",
|
||||
"naturalCrit/combat.actions.js",
|
||||
"naturalCrit/jsonFileEditor/jsonFileEditor.jsx"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\combatManager\\sidebar\\sidebar.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"naturalCrit/combat.store.js",
|
||||
"naturalCrit/combat.actions.js",
|
||||
"./dmDice/dmDice.jsx",
|
||||
"naturalCrit/jsonFileEditor/jsonFileEditor.jsx",
|
||||
"./encounters/encounters.jsx"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\shared\\naturalCrit\\randomEncounter.js": [
|
||||
"lodash"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\shared\\naturalCrit\\combat.store.js": [
|
||||
"pico-flux",
|
||||
"lodash",
|
||||
"naturalCrit/defaultMonsterManual.js",
|
||||
"naturalCrit/randomEncounter.js"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\combatManager\\combatManager.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"naturalCrit/defaultMonsterManual.js",
|
||||
"naturalCrit/combat.actions",
|
||||
"./encounter/encounter.jsx",
|
||||
"./sidebar/sidebar.jsx",
|
||||
"naturalCrit/combat.store"
|
||||
],
|
||||
"C:\\Dropbox\\root\\Programming\\Javascript\\NaturalCrit\\client\\naturalCrit\\naturalCrit.jsx": [
|
||||
"react",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"pico-router",
|
||||
"./homebrew/homebrew.jsx",
|
||||
"./combatManager/combatManager.jsx"
|
||||
]
|
||||
}
|
||||
165
client/naturalCrit/combatManager/combatManager.jsx
Normal file
165
client/naturalCrit/combatManager/combatManager.jsx
Normal file
@@ -0,0 +1,165 @@
|
||||
var React = require('react');
|
||||
var _ = require('lodash');
|
||||
var cx = require('classnames');
|
||||
|
||||
var Sidebar = require('./sidebar/sidebar.jsx');
|
||||
var Encounter = require('./encounter/encounter.jsx');
|
||||
|
||||
var encounters = [
|
||||
{
|
||||
name : 'The Big Bad',
|
||||
desc : 'The big fight!',
|
||||
reward : 'gems',
|
||||
enemies : ['goblin', 'goblin'],
|
||||
reserve : ['goblin'],
|
||||
},
|
||||
{
|
||||
name : 'Demon Goats',
|
||||
desc : 'Gross fight',
|
||||
reward : 'curved horn, goat sac',
|
||||
enemies : ['demon_goat', 'demon_goat', 'demon_goat'],
|
||||
unique : {
|
||||
demon_goat : {
|
||||
"hp" : 140,
|
||||
"ac" : 16,
|
||||
"attr" : {
|
||||
"str" : 8,
|
||||
"con" : 8,
|
||||
"dex" : 8,
|
||||
"int" : 8,
|
||||
"wis" : 8,
|
||||
"cha" : 8
|
||||
},
|
||||
"attacks" : {
|
||||
"charge" : {
|
||||
"atk" : "1d20+5",
|
||||
"dmg" : "1d8+5",
|
||||
"type" : "bludge"
|
||||
}
|
||||
},
|
||||
"abilities" : ["charge"],
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
var defaultMonsterManual = require('naturalCrit/defaultMonsterManual.js');
|
||||
|
||||
var attrMod = function(attr){
|
||||
return Math.floor(attr/2) - 5;
|
||||
}
|
||||
|
||||
|
||||
var Store = require('naturalCrit/combat.store');
|
||||
var Actions = require('naturalCrit/combat.actions');
|
||||
|
||||
|
||||
|
||||
var CombatManager = React.createClass({
|
||||
mixins : [Store.mixin()],
|
||||
|
||||
|
||||
getInitialState: function() {
|
||||
var self = this;
|
||||
return {
|
||||
selectedEncounterIndex : 0,
|
||||
encounters : JSON.parse(localStorage.getItem('encounters')) || encounters,
|
||||
monsterManual : JSON.parse(localStorage.getItem('monsterManual')) || defaultMonsterManual,
|
||||
|
||||
players : localStorage.getItem('players') || 'jasper 13\nzatch 19',
|
||||
|
||||
|
||||
};
|
||||
},
|
||||
|
||||
onStoreChange : function(){
|
||||
console.log('STORE CAHNGE', Store.getInc());
|
||||
this.setState({
|
||||
inc : Store.getInc()
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
handleEncounterJSONChange : function(encounterIndex, json){
|
||||
this.state.encounters[encounterIndex] = json;
|
||||
this.setState({
|
||||
encounters : this.state.encounters
|
||||
})
|
||||
localStorage.setItem("encounters", JSON.stringify(this.state.encounters));
|
||||
},
|
||||
handleMonsterManualJSONChange : function(json){
|
||||
this.setState({
|
||||
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){
|
||||
console.log(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;
|
||||
|
||||
if(this.state.selectedEncounterIndex != null && this.state.encounters[this.state.selectedEncounterIndex]){
|
||||
var selectedEncounter = this.state.encounters[this.state.selectedEncounterIndex]
|
||||
return <Encounter
|
||||
key={selectedEncounter.name}
|
||||
{...selectedEncounter}
|
||||
monsterManual={this.state.monsterManual}
|
||||
players={this.state.players}
|
||||
/>
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
temp : function(){
|
||||
Actions.setInc(++this.state.inc);
|
||||
},
|
||||
|
||||
|
||||
render : function(){
|
||||
var self = this;
|
||||
return(
|
||||
<div className='combatManager'>
|
||||
<Sidebar
|
||||
selectedEncounter={this.state.selectedEncounterIndex}
|
||||
encounters={this.state.encounters}
|
||||
monsterManual={this.state.monsterManual}
|
||||
players={this.state.players}
|
||||
|
||||
onSelectEncounter={this.handleSelectedEncounterChange}
|
||||
onRemoveEncounter={this.handleRemoveEncounter}
|
||||
onJSONChange={this.handleEncounterJSONChange}
|
||||
onMonsterManualChange={this.handleMonsterManualJSONChange}
|
||||
onPlayerChange={this.handlePlayerChange}
|
||||
/>
|
||||
|
||||
|
||||
{this.renderSelectedEncounter()}
|
||||
|
||||
<button onClick={this.temp}>YUP {this.state.inc}</button>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = CombatManager;
|
||||
8
client/naturalCrit/combatManager/combatManager.less
Normal file
8
client/naturalCrit/combatManager/combatManager.less
Normal file
@@ -0,0 +1,8 @@
|
||||
.combatManager{
|
||||
|
||||
.encounterContainer{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,13 +2,28 @@ var React = require('react');
|
||||
var _ = require('lodash');
|
||||
var cx = require('classnames');
|
||||
|
||||
var Store = require('naturalCrit/combat.store.js');
|
||||
|
||||
var MonsterCard = require('./monsterCard/monsterCard.jsx');
|
||||
|
||||
|
||||
|
||||
var attrMod = function(attr){
|
||||
return Math.floor(attr/2) - 5;
|
||||
}
|
||||
|
||||
var Encounter = React.createClass({
|
||||
mixins : [Store.mixin()],
|
||||
getInitialState: function() {
|
||||
return {
|
||||
enemies: this.createEnemies(this.props)
|
||||
};
|
||||
},
|
||||
|
||||
onStoreChange : function(){
|
||||
var players = Store.getplayersText();
|
||||
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
@@ -23,11 +38,7 @@ var Encounter = React.createClass({
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
enemies: this.createEnemies(this.props)
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
this.setState({
|
||||
@@ -4,10 +4,27 @@ var cx = require('classnames');
|
||||
|
||||
var JSONFileEditor = require('naturalCrit/jsonFileEditor/jsonFileEditor.jsx');
|
||||
|
||||
var GetRandomEncounter = require('naturalCrit/randomEncounter.js');
|
||||
//var GetRandomEncounter = require('naturalCrit/randomEncounter.js');
|
||||
|
||||
var Store = require('naturalCrit/combat.store.js');
|
||||
var Actions = require('naturalCrit/combat.actions.js');
|
||||
|
||||
|
||||
var Encounters = React.createClass({
|
||||
mixins : [Store.mixin()],
|
||||
onStoreChange : function(){
|
||||
this.setState({
|
||||
encounters : Store.getEncounters(),
|
||||
selectedEncounter : Store.getSelectedEncounterIndex()
|
||||
});
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
encounters : Store.getEncounters(),
|
||||
selectedEncounter : Store.getSelectedEncounterIndex()
|
||||
};
|
||||
},
|
||||
/*
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
encounters : [],
|
||||
@@ -18,27 +35,29 @@ var Encounters = React.createClass({
|
||||
onRemoveEncounter : function(encounterIndex){}
|
||||
};
|
||||
},
|
||||
|
||||
*/
|
||||
handleJSONChange : function(encounterIndex, json){
|
||||
this.props.onJSONChange(encounterIndex, json);
|
||||
//this.props.onJSONChange(encounterIndex, json);
|
||||
Actions.updateEncounter(encounterIndex, json);
|
||||
},
|
||||
handleSelectEncounter : function(encounterIndex){
|
||||
this.props.onSelectEncounter(encounterIndex);
|
||||
//this.props.onSelectEncounter(encounterIndex);
|
||||
Actions.selectEncounter(encounterIndex);
|
||||
},
|
||||
handleRemoveEncounter : function(encounterIndex){
|
||||
this.props.onRemoveEncounter(encounterIndex);
|
||||
//this.props.onRemoveEncounter(encounterIndex);
|
||||
Actions.removeEncounter(encounterIndex);
|
||||
},
|
||||
|
||||
addRandomEncounter : function(){
|
||||
this.props.onJSONChange(this.props.encounters.length, GetRandomEncounter());
|
||||
Actions.addEncounter();
|
||||
},
|
||||
|
||||
|
||||
renderEncounters : function(){
|
||||
var self = this;
|
||||
return _.map(this.props.encounters, function(encounter, index){
|
||||
return _.map(this.state.encounters, function(encounter, index){
|
||||
|
||||
var isSelected = self.props.selectedEncounter == index;
|
||||
var isSelected = self.state.selectedEncounter == index;
|
||||
return <div className={cx('encounter' , {'selected' : isSelected})} key={index}>
|
||||
|
||||
<i onClick={self.handleSelectEncounter.bind(self, index)} className={cx('select', 'fa', {
|
||||
@@ -4,69 +4,44 @@ var cx = require('classnames');
|
||||
|
||||
var JSONFileEditor = require('naturalCrit/jsonFileEditor/jsonFileEditor.jsx');
|
||||
|
||||
|
||||
var DMDice = require('./dmDice/dmDice.jsx');
|
||||
|
||||
var Encounters = require('./encounters/encounters.jsx');
|
||||
|
||||
var Store = require('naturalCrit/combat.store.js');
|
||||
var Actions = require('naturalCrit/combat.actions.js');
|
||||
|
||||
|
||||
var Sidebar = React.createClass({
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
selectedEncounter : null,
|
||||
|
||||
monsterManual : {},
|
||||
encounters : [],
|
||||
|
||||
onSelectEncounter : function(){},
|
||||
onJSONChange : function(encounterIndex, json){},
|
||||
onMonsterManualChange : function(json){},
|
||||
onPlayerChange : function(){},
|
||||
onRemoveEncounter : function(encounterIndex){}
|
||||
};
|
||||
},
|
||||
mixins : [Store.mixin()],
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
hide : false
|
||||
hide : false,
|
||||
|
||||
monsterManual : Store.getMonsterManual(),
|
||||
players : Store.getPlayersText()
|
||||
};
|
||||
},
|
||||
|
||||
onStoreChange : function(){
|
||||
this.setState({
|
||||
players : Store.getPlayersText(),
|
||||
monsterManual : Store.getMonsterManual()
|
||||
})
|
||||
},
|
||||
|
||||
handleLogoClick : function(){
|
||||
this.setState({
|
||||
hide : !this.state.hide
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
renderEncounters : function(){
|
||||
var self = this;
|
||||
|
||||
return _.map(this.props.encounters, function(encounter, index){
|
||||
|
||||
var isSelected = self.props.selectedEncounter == index;
|
||||
return <div className={cx('encounter' , {'selected' : isSelected})} key={index}>
|
||||
|
||||
<i onClick={self.handleSelectEncounter.bind(self, index)} className={cx('select', 'fa', {
|
||||
'fa-square-o' : !isSelected,
|
||||
'fa-check-square-o' : isSelected,
|
||||
})} />
|
||||
|
||||
|
||||
<JSONFileEditor
|
||||
name={encounter.name}
|
||||
json={encounter}
|
||||
onJSONChange={self.handleJSONChange.bind(self, index)}
|
||||
/>
|
||||
|
||||
<i onClick={self.handleRemoveEncounter.bind(self, index)} className='remove fa fa-times' />
|
||||
</div>
|
||||
})
|
||||
handleMonsterManualChange : function(json){
|
||||
Actions.updateMonsterManual(json);
|
||||
},
|
||||
*/
|
||||
handlePlayerChange : function(e){
|
||||
Actions.updatePlayers(e.target.value);
|
||||
},
|
||||
|
||||
render : function(){
|
||||
var self = this;
|
||||
return(
|
||||
@@ -79,39 +54,20 @@ var Sidebar = React.createClass({
|
||||
</span>
|
||||
</div>
|
||||
<div className='contents'>
|
||||
|
||||
<div className='monsterManualContainer'>
|
||||
<JSONFileEditor
|
||||
name="Monster Manual"
|
||||
json={this.props.monsterManual}
|
||||
onJSONChange={this.onMonsterManualChange}
|
||||
json={this.state.monsterManual}
|
||||
onJSONChange={this.handleMonsterManualChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<Encounters
|
||||
encounters={this.props.encounters}
|
||||
selectedEncounter={this.props.selectedEncounter}
|
||||
|
||||
onJSONChange={this.props.onJSONChange}
|
||||
onSelectEncounter={this.props.onSelectEncounter}
|
||||
onRemoveEncounter={this.props.onRemoveEncounter}
|
||||
|
||||
/>
|
||||
|
||||
<Encounters />
|
||||
<div className='addPlayers'>
|
||||
<h3> <i className='fa fa-group' /> Players </h3>
|
||||
<textarea value={this.props.players} onChange={this.props.onPlayerChange} />
|
||||
<textarea value={this.state.players} onChange={this.handlePlayerChange} />
|
||||
</div>
|
||||
|
||||
|
||||
<DMDice />
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
BIN
client/naturalCrit/homebrew/assets/Bookinsanity Bold Italic.otf
Normal file
BIN
client/naturalCrit/homebrew/assets/Bookinsanity Bold Italic.otf
Normal file
Binary file not shown.
BIN
client/naturalCrit/homebrew/assets/Bookinsanity Bold.otf
Normal file
BIN
client/naturalCrit/homebrew/assets/Bookinsanity Bold.otf
Normal file
Binary file not shown.
BIN
client/naturalCrit/homebrew/assets/Bookinsanity Italic.otf
Normal file
BIN
client/naturalCrit/homebrew/assets/Bookinsanity Italic.otf
Normal file
Binary file not shown.
BIN
client/naturalCrit/homebrew/assets/Bookinsanity.otf
Normal file
BIN
client/naturalCrit/homebrew/assets/Bookinsanity.otf
Normal file
Binary file not shown.
BIN
client/naturalCrit/homebrew/assets/Mr Eaves Small Caps.otf
Normal file
BIN
client/naturalCrit/homebrew/assets/Mr Eaves Small Caps.otf
Normal file
Binary file not shown.
BIN
client/naturalCrit/homebrew/assets/MrsEavesSmallCaps_Regular.ttf
Normal file
BIN
client/naturalCrit/homebrew/assets/MrsEavesSmallCaps_Regular.ttf
Normal file
Binary file not shown.
BIN
client/naturalCrit/homebrew/assets/PHB fonts used.jpg
Normal file
BIN
client/naturalCrit/homebrew/assets/PHB fonts used.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 337 KiB |
BIN
client/naturalCrit/homebrew/assets/PHB-background.png
Normal file
BIN
client/naturalCrit/homebrew/assets/PHB-background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 MiB |
BIN
client/naturalCrit/homebrew/assets/Scaly Sans.otf
Normal file
BIN
client/naturalCrit/homebrew/assets/Scaly Sans.otf
Normal file
Binary file not shown.
BIN
client/naturalCrit/homebrew/assets/Solbera Imitation.otf
Normal file
BIN
client/naturalCrit/homebrew/assets/Solbera Imitation.otf
Normal file
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
BIN
client/naturalCrit/homebrew/assets/frame border corner.png
Normal file
BIN
client/naturalCrit/homebrew/assets/frame border corner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
40
client/naturalCrit/homebrew/homebrew.jsx
Normal file
40
client/naturalCrit/homebrew/homebrew.jsx
Normal file
@@ -0,0 +1,40 @@
|
||||
var React = require('react');
|
||||
var _ = require('lodash');
|
||||
var cx = require('classnames');
|
||||
|
||||
|
||||
var Markdown = require('marked');
|
||||
|
||||
|
||||
var Homebrew = React.createClass({
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
text : "# test \nneato"
|
||||
};
|
||||
},
|
||||
|
||||
handleTextChange : function(e){
|
||||
|
||||
console.log(e.value);
|
||||
this.setState({
|
||||
text : e.target.value
|
||||
})
|
||||
},
|
||||
|
||||
render : function(){
|
||||
var self = this;
|
||||
|
||||
console.log(this.state.text);
|
||||
return(
|
||||
<div className='homebrew'>
|
||||
<textarea value={this.state.text} onChange={this.handleTextChange} />
|
||||
|
||||
<div className='phb' dangerouslySetInnerHTML={{__html:Markdown(this.state.text)}} />
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Homebrew;
|
||||
141
client/naturalCrit/homebrew/homebrew.less
Normal file
141
client/naturalCrit/homebrew/homebrew.less
Normal file
@@ -0,0 +1,141 @@
|
||||
|
||||
@font-face {
|
||||
font-family : BookInsanity;
|
||||
src : url('/assets/naturalCrit/homebrew/assets/Bookinsanity.otf');
|
||||
}
|
||||
@font-face {
|
||||
font-family : BookInsanityBold;
|
||||
src : url('/assets/naturalCrit/homebrew/assets/Bookinsanity Bold.otf');
|
||||
}
|
||||
@font-face {
|
||||
font-family : BookInsanityItalic;
|
||||
src : url('/assets/naturalCrit/homebrew/assets/Bookinsanity Italic.otf');
|
||||
}
|
||||
@font-face {
|
||||
font-family : BookInsanityBoldItalic;
|
||||
src : url('/assets/naturalCrit/homebrew/assets/Bookinsanity Bold Italic.otf');
|
||||
}
|
||||
@font-face {
|
||||
font-family : ScalaSans;
|
||||
src : url('/assets/naturalCrit/homebrew/assets/Scaly Sans.otf');
|
||||
}
|
||||
@font-face {
|
||||
font-family : Solbera;
|
||||
src : url('/assets/naturalCrit/homebrew/assets/Solbera Imitation.otf');
|
||||
}
|
||||
@font-face {
|
||||
font-family : MrEaves;
|
||||
src : url('/assets/naturalCrit/homebrew/assets/MrsEavesSmallCaps_Regular.ttf') format('truetype'),
|
||||
url('/assets/naturalCrit/homebrew/assets/Mr Eaves Small Caps.otf') format('otf');
|
||||
}
|
||||
.homebrew{
|
||||
.phb{
|
||||
|
||||
@background : #f2ece4;
|
||||
@green : #e0e5c1;
|
||||
@headerUnderline : #c9ad6a;
|
||||
@horizontalRule : #9c2b1b;
|
||||
@header : #58180D;
|
||||
|
||||
|
||||
|
||||
background-image : url('/assets/naturalCrit/homebrew/assets/PHB-background.png');
|
||||
padding : 30px;
|
||||
|
||||
-webkit-column-count: 2; /* Chrome, Safari, Opera */
|
||||
-moz-column-count: 2; /* Firefox */
|
||||
column-count: 2;
|
||||
|
||||
-webkit-column-width: 200px;
|
||||
-moz-column-width: 200px;
|
||||
column-width: 200px;
|
||||
|
||||
column-fill : auto;
|
||||
|
||||
height : 500px;
|
||||
|
||||
|
||||
text-rendering : optimizeLegibility;
|
||||
|
||||
p {
|
||||
line-height: 1.2em;
|
||||
font-family : BookInsanity;
|
||||
font-size : 9pt;
|
||||
-webkit-column-break-inside:avoid;
|
||||
-moz-column-break-inside:avoid;
|
||||
-o-column-break-inside:avoid;
|
||||
-ms-column-break-inside:avoid;
|
||||
column-break-inside:avoid;
|
||||
padding-bottom: 1em;
|
||||
strong{
|
||||
font-family : BookInsanityBold;
|
||||
em{
|
||||
font-family : BookInsanityBoldItalic;
|
||||
}
|
||||
}
|
||||
em{
|
||||
font-family : BookInsanityItalic;
|
||||
}
|
||||
}
|
||||
p + p{
|
||||
text-indent: 1em;
|
||||
margin-top: -1em;
|
||||
}
|
||||
|
||||
table{
|
||||
font-family: ScalaSans;
|
||||
font-size: 10pt;
|
||||
width : 100%;
|
||||
thead{
|
||||
font-weight: 800;
|
||||
}
|
||||
tr:nth-child(even){
|
||||
background: @green;
|
||||
}
|
||||
}
|
||||
|
||||
blockquote{
|
||||
background-color: @green;
|
||||
font-family: ScalaSans;
|
||||
column-span: all;
|
||||
-webkit-column-span: all;
|
||||
}
|
||||
|
||||
|
||||
h1,h2,h3,h4{
|
||||
font-family : MrEaves;
|
||||
color : #58180D;
|
||||
margin: 0.2em 0em;
|
||||
}
|
||||
h1{
|
||||
font-size : 24pt;
|
||||
column-span: all;
|
||||
-webkit-column-span: all;
|
||||
&+p{
|
||||
&::first-letter{
|
||||
font-family: Solbera;
|
||||
float :left;
|
||||
font-size: 5em;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
h2{
|
||||
font-size : 20pt;
|
||||
}
|
||||
h3{
|
||||
font-size : 15pt;
|
||||
border-bottom : 3px solid #D8A866;
|
||||
}
|
||||
h4{
|
||||
font-size : 12pt;
|
||||
}
|
||||
h5{
|
||||
|
||||
font-family: ScalaSans;
|
||||
font-weight: 800;
|
||||
font-size: 12pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,146 +1,35 @@
|
||||
var React = require('react');
|
||||
var _ = require('lodash');
|
||||
var cx = require('classnames');
|
||||
var CreateRouter = require('pico-router').createRouter;
|
||||
|
||||
var Sidebar = require('./sidebar/sidebar.jsx');
|
||||
var Encounter = require('./encounter/encounter.jsx');
|
||||
var CombatManager = require('./combatManager/combatManager.jsx');
|
||||
var Homebrew = require('./homebrew/homebrew.jsx');
|
||||
|
||||
var encounters = [
|
||||
{
|
||||
name : 'The Big Bad',
|
||||
desc : 'The big fight!',
|
||||
reward : 'gems',
|
||||
enemies : ['goblin', 'goblin'],
|
||||
reserve : ['goblin'],
|
||||
},
|
||||
{
|
||||
name : 'Demon Goats',
|
||||
desc : 'Gross fight',
|
||||
reward : 'curved horn, goat sac',
|
||||
enemies : ['demon_goat', 'demon_goat', 'demon_goat'],
|
||||
unique : {
|
||||
demon_goat : {
|
||||
"hp" : 140,
|
||||
"ac" : 16,
|
||||
"attr" : {
|
||||
"str" : 8,
|
||||
"con" : 8,
|
||||
"dex" : 8,
|
||||
"int" : 8,
|
||||
"wis" : 8,
|
||||
"cha" : 8
|
||||
},
|
||||
"attacks" : {
|
||||
"charge" : {
|
||||
"atk" : "1d20+5",
|
||||
"dmg" : "1d8+5",
|
||||
"type" : "bludge"
|
||||
}
|
||||
},
|
||||
"abilities" : ["charge"],
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
var defaultMonsterManual = require('naturalCrit/defaultMonsterManual.js');
|
||||
|
||||
var attrMod = function(attr){
|
||||
return Math.floor(attr/2) - 5;
|
||||
}
|
||||
var Router = CreateRouter({
|
||||
'/' : <CombatManager />,
|
||||
'/combat' : <CombatManager />,
|
||||
'/homebrew' : <Homebrew />,
|
||||
});
|
||||
|
||||
|
||||
var NaturalCrit = React.createClass({
|
||||
|
||||
getInitialState: function() {
|
||||
var self = this;
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
selectedEncounterIndex : 0,
|
||||
encounters : JSON.parse(localStorage.getItem('encounters')) || encounters,
|
||||
monsterManual : JSON.parse(localStorage.getItem('monsterManual')) || defaultMonsterManual,
|
||||
|
||||
players : localStorage.getItem('players') || 'jasper 13\nzatch 19'
|
||||
|
||||
url : '/'
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
handleEncounterJSONChange : function(encounterIndex, json){
|
||||
this.state.encounters[encounterIndex] = json;
|
||||
this.setState({
|
||||
encounters : this.state.encounters
|
||||
})
|
||||
localStorage.setItem("encounters", JSON.stringify(this.state.encounters));
|
||||
},
|
||||
handleMonsterManualJSONChange : function(json){
|
||||
this.setState({
|
||||
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){
|
||||
console.log(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;
|
||||
|
||||
if(this.state.selectedEncounterIndex != null && this.state.encounters[this.state.selectedEncounterIndex]){
|
||||
var selectedEncounter = this.state.encounters[this.state.selectedEncounterIndex]
|
||||
return <Encounter
|
||||
key={selectedEncounter.name}
|
||||
{...selectedEncounter}
|
||||
monsterManual={this.state.monsterManual}
|
||||
players={this.state.players}
|
||||
/>
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
render : function(){
|
||||
var self = this;
|
||||
return(
|
||||
<div className='naturalCrit'>
|
||||
<Sidebar
|
||||
selectedEncounter={this.state.selectedEncounterIndex}
|
||||
encounters={this.state.encounters}
|
||||
monsterManual={this.state.monsterManual}
|
||||
players={this.state.players}
|
||||
|
||||
onSelectEncounter={this.handleSelectedEncounterChange}
|
||||
onRemoveEncounter={this.handleRemoveEncounter}
|
||||
onJSONChange={this.handleEncounterJSONChange}
|
||||
onMonsterManualChange={this.handleMonsterManualJSONChange}
|
||||
onPlayerChange={this.handlePlayerChange}
|
||||
/>
|
||||
|
||||
|
||||
{this.renderSelectedEncounter()}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <div className='naturalCrit'>
|
||||
<Router initialUrl={this.props.url} />
|
||||
</div>
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NaturalCrit;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@import 'naturalCrit/reset.less';
|
||||
//@import 'naturalCrit/elements.less';
|
||||
@import 'naturalCrit/animations.less';
|
||||
@import 'naturalCrit/colors.less';
|
||||
@import 'naturalCrit/styles/reset.less';
|
||||
//@import 'naturalCrit/styles/elements.less';
|
||||
@import 'naturalCrit/styles/animations.less';
|
||||
@import 'naturalCrit/styles/colors.less';
|
||||
|
||||
|
||||
@sidebarWidth : 250px;
|
||||
@@ -20,10 +20,6 @@ body{
|
||||
color : #333;
|
||||
background-color: #eee;
|
||||
|
||||
.encounterContainer{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.noselect(){
|
||||
|
||||
11
gulpfile.js
11
gulpfile.js
@@ -6,14 +6,17 @@ var gulp = require("gulp");
|
||||
|
||||
var gulp = vitreumTasks(gulp, {
|
||||
entryPoints: ["./client/naturalCrit"],
|
||||
|
||||
DEV: true,
|
||||
|
||||
buildPath: "./build/",
|
||||
pageTemplate: "./client/template.dot",
|
||||
|
||||
projectModules: ["./shared/naturalCrit"],
|
||||
|
||||
additionalRequirePaths : ['./shared'],
|
||||
assetExts: ["*.svg", "*.png", "*.jpg", "*.pdf", "*.eot", "*.otf", "*.woff", "*.woff2", "*.ico"],
|
||||
|
||||
assetExts: ["*.svg", "*.png", "*.jpg", "*.pdf", "*.eot", "*.otf", "*.woff", "*.woff2", "*.ico", "*.ttf"],
|
||||
|
||||
serverWatchPaths: ["server"],
|
||||
serverScript: "server.js",
|
||||
@@ -22,7 +25,11 @@ var gulp = vitreumTasks(gulp, {
|
||||
"react-dom",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"jsoneditor"
|
||||
"jsoneditor",
|
||||
|
||||
"marked",
|
||||
"pico-router",
|
||||
"pico-flux"
|
||||
],
|
||||
clientLibs: [],
|
||||
});
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"gulp": "^3.9.0",
|
||||
"jsoneditor": "^4.2.1",
|
||||
"lodash": "^3.10.1",
|
||||
"marked": "^0.3.5",
|
||||
"pico-router": "^1.0.0",
|
||||
"react": "^0.14.2",
|
||||
"react-dom": "^0.14.2",
|
||||
"vitreum": "^3.1.1"
|
||||
|
||||
23
shared/naturalCrit/combat.actions.js
Normal file
23
shared/naturalCrit/combat.actions.js
Normal file
@@ -0,0 +1,23 @@
|
||||
var dispatch = require('pico-flux').dispatch;
|
||||
|
||||
module.exports = {
|
||||
updateMonsterManual : function(json){
|
||||
dispatch('UDPATE_MONSTER_MANUAL', json);
|
||||
},
|
||||
addEncounter : function(){
|
||||
dispatch('ADD_ENCOUNTER');
|
||||
},
|
||||
updateEncounter : function(index, json){
|
||||
dispatch('UPDATE_ENCOUNTER', index, json);
|
||||
},
|
||||
removeEncounter : function(index){
|
||||
dispatch('REMOVE_ENCOUNTER', index);
|
||||
},
|
||||
updatePlayers : function(text){
|
||||
dispatch('UPDATE_PLAYERS', text);
|
||||
},
|
||||
selectEncounter : function(index){
|
||||
dispatch('SELECT_ENCOUNTER', index);
|
||||
},
|
||||
|
||||
}
|
||||
69
shared/naturalCrit/combat.store.js
Normal file
69
shared/naturalCrit/combat.store.js
Normal file
@@ -0,0 +1,69 @@
|
||||
var flux = require('pico-flux');
|
||||
var _ = require('lodash');
|
||||
|
||||
var defaultMonsterManual = require('naturalCrit/defaultMonsterManual.js');
|
||||
var GetRandomEncounter = require('naturalCrit/randomEncounter.js');
|
||||
|
||||
var Store = {
|
||||
selectedEncounterIndex : 0,
|
||||
encounters : JSON.parse(localStorage.getItem('encounters')) || [GetRandomEncounter()],
|
||||
monsterManual : JSON.parse(localStorage.getItem('monsterManual')) || defaultMonsterManual,
|
||||
players : localStorage.getItem('players') || 'jasper 13\nzatch 19',
|
||||
};
|
||||
|
||||
|
||||
module.exports = flux.createStore({
|
||||
UDPATE_MONSTER_MANUAL : function(json){
|
||||
Store.monsterManual = json;
|
||||
return true;
|
||||
},
|
||||
ADD_ENCOUNTER : function(){
|
||||
Store.encounters.push(GetRandomEncounter());
|
||||
return true;
|
||||
},
|
||||
UPDATE_ENCOUNTER : function(index, json){
|
||||
Store.encounters[index] = json;
|
||||
return true;
|
||||
},
|
||||
REMOVE_ENCOUNTER : function(index){
|
||||
Store.encounters.splice(index, 1);
|
||||
return true;
|
||||
},
|
||||
UPDATE_PLAYERS : function(text){
|
||||
Store.players = text;
|
||||
return true;
|
||||
},
|
||||
SELECT_ENCOUNTER : function(index){
|
||||
Store.selectedEncounterIndex = index;
|
||||
return true;
|
||||
},
|
||||
|
||||
},{
|
||||
getMonsterManual : function(){
|
||||
return Store.monsterManual;
|
||||
},
|
||||
getSelectedEncounterIndex : function(){
|
||||
return Store.selectedEncounterIndex;
|
||||
},
|
||||
getSelectedEncounter : function(){
|
||||
return Store.encounters[Store.selectedEncounterIndex];
|
||||
},
|
||||
getEncounter : function(index){
|
||||
return Store.encounters[index];
|
||||
},
|
||||
getEncounters : function(index){
|
||||
return Store.encounters;
|
||||
},
|
||||
getPlayersText : function(){
|
||||
return Store.players;
|
||||
},
|
||||
getPlayers : function(){
|
||||
return _.reduce(Store.players.split('\n'), function(r, line){
|
||||
var idx = line.lastIndexOf(' ');
|
||||
if(idx !== -1){
|
||||
r[line.substring(0, idx)] = line.substring(idx)*1;
|
||||
}
|
||||
return r;
|
||||
}, {})
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user