Commit 31fb8e8f authored by Joe Ziemba's avatar Joe Ziemba
Browse files

refactoring

parent ecdeb9fa
......@@ -3999,9 +3999,9 @@
"integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4="
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "3.2.1",
......@@ -4365,11 +4365,6 @@
"integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
"dev": true
},
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
......@@ -6921,11 +6916,18 @@
}
},
"domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz",
"integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==",
"requires": {
"domelementtype": "1"
"domelementtype": "^2.2.0"
},
"dependencies": {
"domelementtype": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
}
}
},
"domutils": {
......@@ -9559,22 +9561,40 @@
}
},
"htmlparser2": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
"requires": {
"domelementtype": "^1.3.1",
"domhandler": "^2.3.0",
"domutils": "^1.5.1",
"entities": "^1.1.1",
"inherits": "^2.0.1",
"readable-stream": "^3.1.1"
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"domutils": "^2.5.2",
"entities": "^2.0.0"
},
"dependencies": {
"entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
"dom-serializer": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
}
},
"domelementtype": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
},
"domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"requires": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
}
}
}
},
......@@ -12661,6 +12681,11 @@
"integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
"dev": true
},
"js-guid": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/js-guid/-/js-guid-1.0.0.tgz",
"integrity": "sha512-PdPqvtk8tDAcbyOXKnL+NJKVED5FyJwm5HE1N/v9TPD7AeVcJEFFrox7//OJyOYn5Vqtsc1B3Nxm1ntW9TutVQ=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
......@@ -16874,15 +16899,15 @@
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
},
"renderkid": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz",
"integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==",
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz",
"integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==",
"requires": {
"css-select": "^2.0.2",
"dom-converter": "^0.2",
"htmlparser2": "^3.10.1",
"lodash": "^4.17.20",
"strip-ansi": "^3.0.0"
"css-select": "^4.1.3",
"dom-converter": "^0.2.0",
"htmlparser2": "^6.1.0",
"lodash": "^4.17.21",
"strip-ansi": "^3.0.1"
},
"dependencies": {
"ansi-regex": {
......@@ -16890,6 +16915,56 @@
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"css-select": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
"integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==",
"requires": {
"boolbase": "^1.0.0",
"css-what": "^5.0.0",
"domhandler": "^4.2.0",
"domutils": "^2.6.0",
"nth-check": "^2.0.0"
}
},
"css-what": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz",
"integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg=="
},
"dom-serializer": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
}
},
"domelementtype": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
},
"domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"requires": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
}
},
"nth-check": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
"requires": {
"boolbase": "^1.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
......@@ -20126,9 +20201,9 @@
}
},
"tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
"integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE="
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="
},
"to-arraybuffer": {
"version": "1.0.1",
......@@ -21583,11 +21658,18 @@
}
},
"ws": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
"integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"requires": {
"async-limiter": "~1.0.0"
},
"dependencies": {
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
}
}
}
}
......
......@@ -5,11 +5,12 @@ import "react-toastify/dist/ReactToastify.css"
import { UserContext } from "context"
import { CharacterBuilder, Home, StatblockGenerator } from "views"
import { TopBar } from "components"
import { firebase } from "services/Firebase"
import { RedesignAnnounceModal } from "components/pfcb/_modals/RedesignAnnounceModal"
import { Home } from "views/Home"
import { StatblockGenerator } from "views/StatblockGenerator"
import { CharacterBuilder } from "views/CharacterBuilder"
const App = () => {
const [currentUser, setUser] = useState(null)
......
......@@ -2,16 +2,16 @@ import React, { useContext } from "react"
import { NavButton } from "components"
import { StatblockContext } from "context"
import AttackForm from "./AttackForm"
import { FeatureBlock } from "./FeatureBlock"
import AttackForm from "../../components/sbg/AttackForm"
import { FeatureBlock } from "../../components/sbg/FeatureBlock"
export const Actions = ({ legendary }) => {
export const ActionsForm = ({ legendary }) => {
const { stats, updateAction, deleteAction, addAction } =
useContext(StatblockContext)
return (
<React.Fragment>
{stats.actions.map((action, i) => {
if (action.attack) {
if (action) {
return (
<AttackForm
action={action}
......
import { StatblockContext } from "context"
import React, { useContext } from "react"
import { Typeahead } from "react-bootstrap-typeahead"
import "react-bootstrap-typeahead/css/Typeahead.css"
export const PropertyForm = () => {
const { stats, updatePropertyList } = useContext(StatblockContext)
return (
<div className="text-sm">
<label>Condition Immunities</label>
<Typeahead
multiple
options={global.conditions}
selected={stats.conditionImmune}
onChange={(selected) =>
updatePropertyList(selected, "conditionImmune")
}
/>
<label>Damage Immunities</label>
<Typeahead
multiple
options={global.damageTypes}
selected={stats.immune}
onChange={(selected) => updatePropertyList(selected, "immune")}
/>
<label>Resistances</label>
<Typeahead
multiple
options={global.damageTypes}
selected={stats.resists}
onChange={(selected) => updatePropertyList(selected, "resists")}
/>
<label>Vulnerabilities</label>
<Typeahead
multiple
options={global.damageTypes}
selected={stats.vulnerable}
onChange={(selected) => updatePropertyList(selected, "vulnerable")}
/>
<label>Skill Proficiencies</label>
<Typeahead
multiple
options={global.skills.map((skill) => skill.name)}
selected={stats.skills}
onChange={(selected) => updatePropertyList(selected, "skills")}
/>
<label>Languages</label>
<Typeahead
multiple
options={global.languages}
selected={stats.langs}
onChange={(selected) => updatePropertyList(selected, "langs")}
/>
</div>
)
}
import React from "react"
import { Property } from "components"
import { DisplayProperty } from "components"
export class StatBlockDisplay extends React.Component {
renderAbilities() {
......@@ -8,7 +8,7 @@ export class StatBlockDisplay extends React.Component {
let orderedAbilities = ["str", "dex", "con", "int", "wis", "cha"]
return orderedAbilities.map((ability) => {
let score = abilities[ability]
let mod = this.getAbilityMod(score)
let mod = abilities[ability + "Mod"]
return (
<div className="ability" key={ability}>
......@@ -27,7 +27,7 @@ export class StatBlockDisplay extends React.Component {
return features.map((feature) => {
return (
<Property
<DisplayProperty
key={feature.title}
title={feature.title}
content={feature.content}
......@@ -37,10 +37,6 @@ export class StatBlockDisplay extends React.Component {
})
}
getAbilityMod(score) {
return Math.floor((score - 10) / 2)
}
renderActions(legendary) {
let { actions } = this.props.stats
......@@ -49,19 +45,15 @@ export class StatBlockDisplay extends React.Component {
}
return actions.map((action, i) => {
if (action.attack) {
let { dieNum, dmgDie, prof, dex, reach, targets, dmgType } =
action.attack
if (["Melee", "Ranged"].includes(action.type)) {
let { dieNum, dmgDie, prof, dex, reach, targets, dmgType } = action
// Get hit mod
let toHit
let toHit = this.props.stats.abilities.strMod
if (dex) {
toHit = this.getAbilityMod(this.props.stats.abilities.dex)
} else {
toHit = this.getAbilityMod(this.props.stats.abilities.str)
toHit = this.props.stats.abilities.dexMod
}
// Get Damage Mod
let avg = (dieNum * dmgDie) / 2 + toHit
let operator = "+"
......@@ -84,10 +76,10 @@ export class StatBlockDisplay extends React.Component {
{action.title}.{" "}
</span>
<span className="italic">
{action.attack.type} Weapon Attack.{" "}
{action.type} Weapon Attack.{" "}
</span>
{`${toHit >= 0 ? "+" : ""}${toHit}`} to Hit.&ensp;
{action.attack.type === "Ranged" ? "Range" : "Reach"} {reach}
{action.type === "Ranged" ? "Range" : "Reach"} {reach}
ft.&ensp;
{targets} target{targets > 1 ? "s" : ""}.&ensp; Damage:&ensp;
{damage}
......@@ -95,9 +87,9 @@ export class StatBlockDisplay extends React.Component {
)
}
if (!action.attack) {
if (!action) {
return (
<Property
<DisplayProperty
block
key={i}
title={action.title}
......@@ -110,21 +102,18 @@ export class StatBlockDisplay extends React.Component {
}
render() {
let { stats } = this.props
let { abilities } = stats
let { hitDie, dieNum, manualHp } = stats.hp
let {
abilities,
hp: { hitDie, dieNum },
calculatedHP,
} = this.props.stats
let conMod = Math.floor((abilities.con - 10) / 2)
hitDie = parseInt(hitDie)
dieNum = parseInt(dieNum)
let totalHp =
(hitDie * dieNum) / 2 + Math.ceil(dieNum * 0.5) + dieNum * conMod
let mod = dieNum * conMod
let hitPoints = `${totalHp} (${dieNum}d${hitDie} ${
let hitPoints = `${calculatedHP} (${dieNum}d${hitDie} ${
mod < 0 ? "-" : "+"
} ${mod < 0 ? mod * -1 : mod})`
......@@ -145,18 +134,23 @@ export class StatBlockDisplay extends React.Component {
<div className="statblock__section red">
<div className="statblock__property">
<span className="statblock__property-name">Armor Class</span>
{stats.ac.score}
{stats.ac.support && ` (${stats.ac.support})`}
{this.props.stats.ac.score}
{this.props.stats.ac.support &&
` (${this.props.stats.ac.support})`}
</div>
<div className="statblock__property">
<span className="statblock__property-name">Hit Points</span>{" "}
{manualHp ? manualHp : hitPoints}
{hitPoints}
</div>
<div className="statblock__property">
<span className="statblock__property-name">Speed</span>
{stats.speed}ft
{stats.flySpeed > 0 ? `, ${stats.flySpeed}ft (Fly)` : ""}
{stats.swimSpeed > 0 ? `, ${stats.swimSpeed}ft (Swim)` : ""}
{this.props.stats.speed}ft
{this.props.stats.flySpeed > 0
? `, ${this.props.stats.flySpeed}ft (Fly)`
: ""}
{this.props.stats.swimSpeed > 0
? `, ${this.props.stats.swimSpeed}ft (Swim)`
: ""}
</div>
</div>
......@@ -165,38 +159,47 @@ export class StatBlockDisplay extends React.Component {
</div>
<div className="statblock__section red">
{stats.conditionImmune.length > 0 && (
<Property
{this.props.stats.conditionImmune.length > 0 && (
<DisplayProperty
title="Condition Immunities"
content={stats.conditionImmune.join(", ")}
content={this.props.stats.conditionImmune.join(", ")}
/>
)}
{stats.immune.length > 0 && (
<Property
{this.props.stats.immune.length > 0 && (
<DisplayProperty
title="Damage Immunities"
content={stats.immune.join(", ")}
content={this.props.stats.immune.join(", ")}
/>
)}
{stats.resists.length > 0 && (
<Property
{this.props.stats.resists.length > 0 && (
<DisplayProperty
title="Damage Resistances"
content={stats.resists.join(", ")}
content={this.props.stats.resists.join(", ")}
/>
)}
{stats.vulnerable.length > 0 && (
<Property
{this.props.stats.vulnerable.length > 0 && (
<DisplayProperty
title="Damage Vulnerabilities"
content={stats.vulnerable.join(", ")}
content={this.props.stats.vulnerable.join(", ")}
/>
)}
{stats.skills.length > 0 && (
<Property title="Skills" content={stats.skills.join(", ")} />
{this.props.stats.skills.length > 0 && (
<DisplayProperty
title="Skills"
content={this.props.stats.skills.join(", ")}
/>
)}
{stats.senses.length > 0 && (
<Property title="Senses" content={stats.senses.join(", ")} />
{this.props.stats.senses.length > 0 && (
<DisplayProperty
title="Senses"
content={this.props.stats.senses.join(", ")}
/>
)}
{stats.langs.length > 0 && (
<Property title="Languages" content={stats.langs.join(", ")} />
{this.props.stats.langs.length > 0 && (
<DisplayProperty
title="Languages"
content={this.props.stats.langs.join(", ")}
/>
)}
</div>
......@@ -210,16 +213,24 @@ export class StatBlockDisplay extends React.Component {
{this.props.stats.legendaryActions.length > 0 && (
<div className="statblock__section statblock__section--with-heading">
<h3>Legendary Actions</h3>
<p>
<p className="mb-1 text-sm">
{this.props.stats.name} can take{" "}
{this.props.stats.legendaryActPerRound} legendary action
<b>{this.props.stats.legendaryActPerRound}</b> legendary
action
{this.props.stats.legendaryActPerRound === 1 ? "" : "s"},
choosing from the options below. Only one legendary action
option can be used at a time and only at the end of another
creature&apos;s turn. They regain spent legendary actions at
the start of their turn.
</p>
{this.renderActions("legendary")}
{this.props.stats.legendaryActions.map((action, i) => (
<DisplayProperty
block
key={i + action.title}
title={action.title}
content={action.content}
/>
))}
</div>
)}
</div>
......
import React from "react"
import "react-bootstrap-typeahead/css/Typeahead.css"
import { Typeahead } from "react-bootstrap-typeahead"
import {
Accordion,
AbilityScoresForm,
LegendaryActionsForm,
BasicsForm,
FeatureForm,
Actions,
} from "components"
export const StatBlockForm = (props) => {
import { Accordion } from "components"
import { BasicsForm } from "./FormSections/BasicsForm"
import { AbilityScoresForm } from "./FormSections/AbilityScoresForm"
import { FeatureForm } from "./FormSections/FeatureForm"
import { ActionsForm } from "./FormSections/ActionsForm"
import { LegendaryActionsForm } from "./FormSections/LegendaryActionsForm"
import { PropertyForm } from "./FormSections/PropertiesForm"
export const StatBlockForm = () => {
return (
<div id="StatBlockForm" className="w-11/12 text-sm">
<Accordion title="Basic Details" open>
<BasicsForm />
</Accordion>
<Accordion title="Ability Scores">
<AbilityScoresForm />
</Accordion>
<Accordion title="Properties" className="text-md">
<div className="text-sm">
<label>Condition Immunities</label>
<Typeahead
multiple
options={global.conditions}
selected={props.stats.conditionImmune}
onChange={(selected) =>
props.updatePropertyList(selected, "conditionImmune")
}
/>
<label>Damage Immunities</label>
<Typeahead
multiple
options={global.damageTypes}
selected={props.stats.immune}
onChange={(selected) =>
props.updatePropertyList(selected, "immune")
}
/>
<label>Resistences</label>
<Typeahead
multiple
options={global.damageTypes}
selected={props.stats.resists}
onChange={(selected) =>
props.updatePropertyList(selected, "resists")
}
/>
<label>Vulnerabilities</label>
<Typeahead
multiple
options={global.damageTypes}
selected={props.stats.vulnerable}
onChange={(selected) =>
props.updatePropertyList(selected, "vulnerable")
}
/>
<label>Skill Proficiencies</label>
<Typeahead
multiple
options={global.skills.map((skill) => skill.name)}
selected={props.stats.skills}
onChange={(selected) =>
props.updatePropertyList(selected, "skills")
}
/>
<label>Languages</label>
<Typeahead
multiple
options={global.languages}
selected={props.stats.langs}
onChange={(selected) =>
props.updatePropertyList(selected, "langs")
}
/>
</div>
<Accordion title="Properties">
<PropertyForm />
</Accordion>
<Accordion title="Features">
......@@ -89,7 +27,7 @@ export const StatBlockForm = (props) => {
</Accordion>
<Accordion title="Actions">
<Actions />
<ActionsForm />
</Accordion>
<Accordion title="Legendary Actions">
......
export { StatBlockDisplay } from "./StatBlockDisplay"
export { StatBlockForm } from "./StatBlockForm"
import { Guid } from "js-guid"
export class StatblockAction {
constructor(title = "", content = "") {
this.id = Guid.newGuid()
this.title = title
this.content = content
this.type = "General"
}
}
import { StatblockAction } from "./StatblockAction"
export class StatblockAttack extends StatblockAction {
constructor(title, content, type = "Melee") {
super(title, content)
this.type = type
this.prof = true
this.reach = 0
this.targets = 0
this.dmgDie = 4
this.dieNum = 0
this.dmgType = ""
this.dex = false
}
}
......@@ -9,17 +9,12 @@ export { Textarea } from "./common/Textarea"
export { Modal } from "./common/Modal"
// Statblock Benerator (SBG)
export { Property } from "./sbg/Property"
export { DisplayProperty } from "./sbg/DisplayProperty"
export { SBG_Input } from "./sbg/SBG_Input"
export { SBG_Select } from "./sbg/SBG_Select"
export { AbilityScoresForm } from "./sbg/FormSections/AbilityScoresForm"
export { BasicsForm } from "./sbg/FormSections/BasicsForm"
export { FeatureForm } from "./sbg/FormSections/FeatureForm"
export { LegendaryActionsForm } from "./sbg/FormSections/LegendaryActionsForm"
export { GeneratorNav } from "./sbg/GeneratorNav"
export { FeatureBlock } from "./sbg/FeatureBlock"
export { AttackForm } from "./sbg/AttackForm"
export { Actions } from "./sbg/Actions"
// Pathfinder Character Builder (PFCB)
export { AbilityScoreSection } from "./pfcb/AbilityScoresSection"
......
......@@ -26,7 +26,7 @@ export const AttackForm = (props) => {
id={"attack-type"}
fieldName={"type"}
options={["Melee", "Ranged"]}
value={props.action.attack.type}
value={props.action.type}
onChange={(e) =>
props.updateAction(e, props.action.id, props.legendary)
}
......@@ -37,7 +37,7 @@ export const AttackForm = (props) => {
label={"Targets"}
fieldName={"targets"}
type="number"
value={props.action.attack.targets}
value={props.action.targets}
onChange={(e) =>
props.updateAction(e, props.action.id, props.legendary)
}
......@@ -45,10 +45,10 @@ export const AttackForm = (props) => {
</div>
<div className="col-span-1">
<SBG_Input
label={props.action.attack.type === "Ranged" ? "Range" : "Reach"}
label={props.action.type === "Ranged" ? "Range" : "Reach"}
fieldName={"reach"}
type="number"
value={props.action.attack.reach}
value={props.action.reach}
onChange={(e) =>
props.updateAction(e, props.action.id, props.legendary)
}
......@@ -60,7 +60,7 @@ export const AttackForm = (props) => {
label={"#"}
type="number"
fieldName={"dieNum"}
value={props.action.attack.dieNum}
value={props.action.dieNum}
onChange={(e) =>
props.updateAction(e, props.action.id, props.legendary)
}
......@@ -71,7 +71,7 @@ export const AttackForm = (props) => {
label={"Dmg Die"}
fieldName={"dmgDie"}
options={[4, 6, 8, 10, 12]}
value={props.action.attack.dmgDie}
value={props.action.dmgDie}
onChange={(e) =>
props.updateAction(e, props.action.id, props.legendary)
}
......@@ -82,7 +82,7 @@ export const AttackForm = (props) => {
label={"Dmg Type"}
fieldName={"dmgType"}
options={global.damageTypes}
value={props.action.attack.dmgType}
value={props.action.dmgType}
onChange={(e) =>
props.updateAction(e, props.action.id, props.legendary)
}
......@@ -95,16 +95,16 @@ export const AttackForm = (props) => {
</label>
<div
className={`dex-check ${
props.action.attack.dex ? "checked" : ""
props.action.dex ? "checked" : ""
}`}
name={"dex-" + props.action.id}
value={!props.action.attack.dex}
value={!props.action.dex}
onClick={() =>
props.updateAction(
{
target: {
name: "dex",
value: !props.action.attack.dex,
value: !props.action.dex,
},
},
props.action.id,
......
import React from "react"
export const Property = ({ title, content, block }) => {
export const DisplayProperty = ({ title, content, block }) => {
if (block) {
return (
<div className="statblock__property statblock__property--block">
......
......@@ -42,8 +42,14 @@ export class GeneratorNav extends React.Component {
}
async saveStatblock(statblock) {
const newId = await firebase.saveStatblock(statblock)
this.props.history.push("/dnd5e/statblock-generator/" + newId)
const savedStatblock = await firebase.saveStatblock(statblock)
if (savedStatblock) {
savedStatblock.uid = savedStatblock.id
this.props.setStatblock(savedStatblock)
this.props.history.push(
"/dnd5e/statblock-generator/" + savedStatblock.id
)
}
}
async deleteStatblock(statblock) {
......
......@@ -84,7 +84,7 @@ class Firebase {
async saveStatblock(statblock) {
console.log("save")
if (statblock.uid) {
await this.db
let response = await this.db
.collection("5e-statblocks")
.doc(statblock.uid)
.update(statblock)
......@@ -92,6 +92,7 @@ class Firebase {
toast.success("Updated " + statblock.name, {
autoClose: 1000,
})
return response
} else {
let response = await this.load5eStatblocksForUser()
if (response.docs.length >= 5) {
......@@ -103,7 +104,7 @@ class Firebase {
toast.success("Saved " + statblock.name, {
autoClose: 1000,
})
return response.id
return response
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment