Added skills sheet

This commit is contained in:
Lukas Obermann
2016-12-28 16:06:39 +13:00
parent f6a1afd091
commit da52c1dcfd
22 changed files with 1434 additions and 312 deletions
+845 -119
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
<path display="none" fill="#1D1D1B" d="M38.5,14v10.91l-13-11.14V8h-1v42h1V39.09l13,11.141V56h1V14H38.5z M25.5,15.08L38.23,26
L25.5,36.91V15.08z M31.5,42.91L25.77,38l5.73-4.91V42.91z M38.5,48.91l-6-5.141V32.23l6-5.14V48.91z"/>
<path fill="#1D1D1B" d="M38.5,14v10.91l-13-11.14V8h-1v42h1V39.09l13,11.141V56h1V14H38.5z M25.5,15.08L38.23,26L25.5,36.91V15.08z
M31.5,42.91L25.77,38l5.73-4.91V42.91z M38.5,48.91l-6-5.141V32.23l6-5.14V48.91z"/>
<polygon display="none" fill="#1D1D1B" points="25.5,37.77 25.5,38.23 25.23,38 "/>
<polygon display="none" fill="#1D1D1B" points="40.77,26 40.5,26.23 40.5,25.77 "/>
<path display="none" fill="#1D1D1B" d="M37.5,13v12.79l-11-10.99V9h-1v44h1V40.21l11,10.99V57h1V13H37.5z M26.5,16.2L37.29,27
L26.5,37.79V16.2z M31.5,43.79L26.71,39l4.79-4.79V43.79z M37.5,49.8l-5-5.01V33.21l5-5V49.8z"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+1 -1
View File
@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<link href="bundle.min.css" rel="stylesheet">
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon">
<link href="favicon.png" rel="icon" type="image/png" size="267x267">
</head>
<body>
+1 -1
View File
@@ -9,7 +9,7 @@ h2, h3, h4, h5, h6 {
letter-spacing: 0.05em;
&:first-child {
margin-top: 0 !important;
margin-top: 0;
}
}
+2 -2
View File
@@ -9,8 +9,8 @@ export default class Talent extends Skill {
constructor(args) {
super(args);
let { enc, spec, spec_input } = args;
this.enc = enc;
let { be, spec, spec_input } = args;
this.enc = be;
this.spec = spec;
this.spec_input = spec_input;
+1 -1
View File
@@ -21,6 +21,6 @@
@import "profile/MainSheet";
@import "profile/Sheets";
@import "profile/SpellsSheet";
@import "profile/TalentsSheet";
@import "profile/SkillsSheet";
@import "rcp/RCP";
@import "skills/Skills";
+46
View File
@@ -0,0 +1,46 @@
import AttributeStore from '../../stores/AttributeStore';
import classNames from 'classnames';
import React, { Component, PropTypes } from 'react';
import TextBox from '../../components/TextBox';
export default class AttributeCheckMods extends Component {
render() {
const attributes = AttributeStore.getAll();
return (
<TextBox className="attribute-check-mods" label="Eigenschaftsmodifikationen">
<table>
<thead>
<tr>
<td className="name"></td>
<td>-3</td>
<td>-2</td>
<td>-1</td>
<td className="null">0</td>
<td>+1</td>
<td>+2</td>
<td>+3</td>
</tr>
</thead>
<tbody>
{attributes.map(obj => {
const { id, short, value } = obj;
return (<tr key={id} className={id}>
<td className="name">{short}</td>
<td>{value - 3}</td>
<td>{value - 2}</td>
<td>{value - 1}</td>
<td className="null">{value}</td>
<td>{value + 1}</td>
<td>{value + 2}</td>
<td>{value + 3}</td>
</tr>);
})}
</tbody>
</table>
</TextBox>
);
}
}
+73
View File
@@ -0,0 +1,73 @@
.attribute-check-mods {
h3 {
margin-bottom: 4mm;
}
.ATTR_1 .null {
background-color: transparentize(red, .75);
}
.ATTR_2 .null {
background-color: transparentize(#90c, .75);
}
.ATTR_3 .null {
background-color: transparentize(#3c3, .75);
}
.ATTR_4 .null {
background-color: transparentize(black, .75);
}
.ATTR_5 .null {
background-color: transparentize(yellow, .75);
}
.ATTR_6 .null {
background-color: transparentize(blue, .75);
}
.ATTR_7 .null {
background-color: transparentize(white, .75);
}
.ATTR_8 .null {
background-color: transparentize(#f60, .75);
}
td {
width: 9mm;
border-style: solid;
border-color: #c8c8c8;
&.null {
border-left-width: 0.3mm;
border-right-width: 0.3mm;
border-left-color: grey;
border-right-color: grey;
}
}
td:nth-child(2n) {
background: rgba(0, 0, 0, 0.1);
}
thead td {
height: 5mm;
border-width: 0.3mm 0;
font: bold 10px/1 Alegreya SC;
text-align: center;
border-color: grey;
}
tbody td {
height: 4.5mm;
border-width: 0.15mm 0;
font: 500 11px/1 Alegreya Sans;
padding: 0 1mm;
&:not(.name) {
text-align: center;
}
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ export default class ChantSheet extends Component {
return (
<div className="sheet chants">
<SheetHeader title="Liturgien & Zeremonien" add={addHeader} />
<SheetHeader title="Liturgien & Zeremonien" add={[]} />
<div className="upper">
<TextBox label="Liturgien & Zeremonien">
</TextBox>
+4 -30
View File
@@ -1,41 +1,15 @@
import AttributeStore from '../../stores/AttributeStore';
import APStore from '../../stores/APStore';
import CultureStore from '../../stores/CultureStore';
import DisAdvStore from '../../stores/DisAdvStore';
import ELStore from '../../stores/ELStore';
import ProfessionStore from '../../stores/ProfessionStore';
import ProfessionVariantStore from '../../stores/ProfessionVariantStore';
import RaceStore from '../../stores/RaceStore';
import React, { Component } from 'react';
import SheetHeader from './SheetHeader';
import * as secondaryAttributes from '../../utils/secondaryAttributes';
import TextBox from '../../components/TextBox';
export default class CombatSheet extends Component {
render() {
const source = {
attributes: AttributeStore.getAll(),
baseValues: AttributeStore.getBaseValues(),
race: RaceStore.getCurrentName(),
culture: CultureStore.getCurrentName(),
profession: ProfessionVariantStore.getCurrentName() !== null ? `${ProfessionStore.getCurrentName()} (${ProfessionVariantStore.getCurrentName()})` : ProfessionStore.getCurrentName(),
el: ELStore.getStart().name,
apTotal: APStore.getTotal(),
apUsed: APStore.getSpent(),
advActive: DisAdvStore.getActiveForView(true),
disadvActive: DisAdvStore.getActiveForView(false)
};
const addHeader = secondaryAttributes.getAll();
const { attributes, baseValues, race, culture, profession, el, apTotal, apUsed, advActive, disadvActive } = source;
const addHeader = attributes.length > 0 ? [
{ short: 'LE', value: baseValues.le + attributes[6].value * 2 },
{ short: 'AW', value: Math.round(attributes[5].value / 2) },
{ short: 'INI', value: Math.round((attributes[0].value + attributes[5].value) / 2) },
{ short: 'SK', value: baseValues.sk + Math.round((attributes[0].value + attributes[1].value + attributes[2].value) / 6) },
{ short: 'ZK', value: baseValues.zk + Math.round((attributes[6].value * 2 + attributes[7].value) / 6) },
{ short: 'WS', value: Math.round(attributes[6].value / 2) }
] : [];
addHeader.splice(1, 2);
return (
<div className="sheet combat">
+1 -1
View File
@@ -69,7 +69,7 @@
}
.box {
font: bold 24px/40px Alegreya Sans;
font: bold 24px/9.6mm Alegreya Sans;
text-align: center;
width: 2cm;
}
+1
View File
@@ -24,6 +24,7 @@ export default class SheetHeader extends Component {
<div className="sheet-title">
<h1>Heldendokument</h1>
<p>{title}</p>
<img src="images/logo.svg" alt="" />
</div>
<div className="sheet-attributes">
{
+10
View File
@@ -11,6 +11,7 @@
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
h1, p {
text-align: center;
@@ -20,10 +21,19 @@
font: 17px/13px Alegreya SC;
margin-top: 5px;
}
img {
position: absolute;
width: 4cm;
opacity: .2;
left: calc(50% - 2cm);
top: -2.2cm
}
}
.sheet-attributes {
flex: none;
display: flex;
flex-wrap: wrap-reverse;
width: 126.1mm;
}
+2 -2
View File
@@ -5,7 +5,7 @@ import MainSheet from './MainSheet';
import React, { Component } from 'react';
import Scroll from '../../components/Scroll';
import SpellsSheet from './SpellsSheet';
import TalentsSheet from './TalentsSheet';
import SkillsSheet from './SkillsSheet';
export default class Sheets extends Component {
@@ -16,7 +16,7 @@ export default class Sheets extends Component {
<div className="page" id="sheets">
<Scroll className="sheet-wrapper">
<MainSheet />
<TalentsSheet />
<SkillsSheet />
<CombatSheet />
<InventorySheet />
<SpellsSheet />
+2
View File
@@ -53,11 +53,13 @@
h3 {
font: bold 16px Alegreya;
letter-spacing: 0;
width: 100%;
}
}
@import "SheetHeader";
@import "SheetHeaderAttribute";
@import "AttributeCheckMods";
// #sheets {
// flex-flow: column nowrap;
+197
View File
@@ -0,0 +1,197 @@
import AttributeCheckMods from './AttributeCheckMods';
import Categories from '../../constants/Categories';
import { get, getAllByCategory } from '../../stores/ListStore';
import React, { Component } from 'react';
import SheetHeader from './SheetHeader';
import TextBox from '../../components/TextBox';
const getRoutineValue = (sr, attributes) => {
if (sr > 0 ) {
const lessAttrPoints = attributes.map(e => e < 13 ? 13 - e : 0).reduce((a,b) => a + b, 0);
const flatRoutineLevel = Math.floor((sr - 1) / 3);
const checkMod = flatRoutineLevel * -1 + 3;
const dependentCheckMod = checkMod + lessAttrPoints;
return dependentCheckMod < 4 ? [ dependentCheckMod, lessAttrPoints > 0 ] : false;
}
return false;
};
const iterateList = arr => arr.map(obj => {
const { id, name, check, enc, ic, value } = obj;
const checkValues = check.map(e => get(e).value);
const checkString = check.map(e => get(e).short).join('/');
const encString = enc === 'true' ? 'Ja' : enc === 'false' ? 'Nein' : 'Evtl';
const ics = ['A','B','C','D'];
const routine = getRoutineValue(value, checkValues);
const routineSign = routine[0] > 0 ? '+' : '';
return (<tr key={id}>
<td className="name">{name}</td>
<td className="check">{checkString}</td>
<td className="enc">{encString}</td>
<td className="ic">{ics[ic - 1]}</td>
<td className="sr">{value}</td>
<td className="routine">{routineSign}{Array.isArray(routine) ? routine[0] : '-'}{routine[1] ? '!' : ''}</td>
<td className="comment"></td>
</tr>);
});
export default class SkillsSheet extends Component {
render() {
const talents = getAllByCategory(Categories.TALENTS);
const talentGroups = [[],[],[],[],[]];
talents.forEach(obj => talentGroups[obj.gr - 1].push(obj));
const groupChecksIds = [['COU','AGI','STR'],['INT','CHA','CHA'],['COU','AGI','CON'],['SGC','SGC','INT'],['DEX','DEX','CON']];
const groupChecks = groupChecksIds.map(arr => arr.map(e => get(e).short).join('/'));
return (
<div className="sheet" id="skills-sheet">
<SheetHeader title="Spielwerte" />
<TextBox label="Fertigkeiten">
<div className="upper">
<table>
<thead>
<tr>
<td className="name">Talent</td>
<td className="check">Probe</td>
<td className="enc">BE</td>
<td className="ic">Sf.</td>
<td className="sr">Fw</td>
<td className="routine">R</td>
<td className="comment">Anmerkung</td>
</tr>
</thead>
<tbody>
<tr className="group">
<td className="name">Körpertalente</td>
<td className="check">{groupChecks[0]}</td>
<td className="enc"></td>
<td className="ic"></td>
<td className="sr"></td>
<td className="routine"></td>
<td className="comment">S. 188-194</td>
</tr>
{iterateList(talentGroups[0])}
<tr><td/><td/><td/><td/><td/><td/><td/></tr>
<tr className="group">
<td className="name">Gesellschaftstalente</td>
<td className="check">{groupChecks[1]}</td>
<td className="enc"></td>
<td className="ic"></td>
<td className="sr"></td>
<td className="routine"></td>
<td className="comment">S. 194-198</td>
</tr>
{iterateList(talentGroups[1])}
<tr><td/><td/><td/><td/><td/><td/><td/></tr>
<tr className="group">
<td className="name">Naturtalente</td>
<td className="check">{groupChecks[2]}</td>
<td className="enc"></td>
<td className="ic"></td>
<td className="sr"></td>
<td className="routine"></td>
<td className="comment">S. 198-201</td>
</tr>
{iterateList(talentGroups[2])}
</tbody>
</table>
<table>
<thead>
<tr>
<td className="name">Talent</td>
<td className="check">Probe</td>
<td className="enc">BE</td>
<td className="ic">Sf.</td>
<td className="sr">Fw</td>
<td className="routine">R</td>
<td className="comment">Anmerkung</td>
</tr>
</thead>
<tbody>
<tr className="group">
<td className="name">Wissenstalente</td>
<td className="check">{groupChecks[3]}</td>
<td className="enc"></td>
<td className="ic"></td>
<td className="sr"></td>
<td className="routine"></td>
<td className="comment">S. 201-206</td>
</tr>
{iterateList(talentGroups[3])}
<tr><td/><td/><td/><td/><td/><td/><td/></tr>
<tr className="group">
<td className="name">Handwerkstalente</td>
<td className="check">{groupChecks[4]}</td>
<td className="enc"></td>
<td className="ic"></td>
<td className="sr"></td>
<td className="routine"></td>
<td className="comment">S. 206-213</td>
</tr>
{iterateList(talentGroups[4])}
</tbody>
</table>
</div>
</TextBox>
<div className="lower">
<div className="abilites">
<TextBox label="Sprachen">
<table className="languages-list">
<tbody>
{get('SA_30').active.map(e => [ get('SA_30').sel[e[0] - 1][0], e[1], get('SA_30').sel[e[0] - 1][1]]).sort((a,b) => a[1] < b[1] ? 1 : a[1] > b[1] ? -1 : a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0).map(e => <tr key={`lang-${e[2]}`}>
<td>{e[0]}</td>
<td>{e[1] === 4 ? 'MS' : e[1]}</td>
</tr>)}
</tbody>
</table>
</TextBox>
<TextBox label="Schriften">
<div className="scripts-list">
{get('SA_28').active.map(e => get('SA_28').sel[e - 1][0]).sort().join(', ')}
</div>
</TextBox>
</div>
<AttributeCheckMods />
<TextBox className="routine-checks" label="Routineproben">
<p>Alle Proben-Eigenschaften auf 13+</p>
<p>Optional:</p>
<p>Je fehlendem Eigenschaftspunkt</p>
<p>Fw um drei höher als angegeben</p>
<table>
<thead>
<tr><td><div>Proben-<br/>Mod.</div></td><td><div>Nötiger<br/>Fw</div></td><td><div>Proben-<br/>Mod.</div></td><td><div>Nötiger<br/>Fw</div></td></tr>
</thead>
<tbody>
<tr><td>ab +3</td><td>1</td><td>-1</td><td>13</td></tr>
<tr><td>+2</td><td>4</td><td>-2</td><td>16</td></tr>
<tr><td>+1</td><td>7</td><td>-3</td><td>19</td></tr>
<tr><td>+/-0</td><td>10</td><td></td><td></td></tr>
</tbody>
</table>
</TextBox>
<TextBox className="quality-levels" label="Qualitätsstufen">
<table>
<thead>
<tr><td><div>Fertigkeits-<br/>punkte</div></td><td><div>Qualitäts-<br/>stufe</div></td></tr>
</thead>
<tbody>
<tr><td>0-3</td><td>1</td></tr>
<tr><td>4-6</td><td>2</td></tr>
<tr><td>7-9</td><td>3</td></tr>
<tr><td>10-12</td><td>4</td></tr>
<tr><td>13-15</td><td>5</td></tr>
<tr><td>16+</td><td>6</td></tr>
</tbody>
</table>
</TextBox>
</div>
</div>
);
}
}
+219
View File
@@ -0,0 +1,219 @@
#skills-sheet {
> .textbox {
flex-wrap: wrap;
h3 {
margin-bottom: 4mm;
}
}
.upper {
display: flex;
width: 100%;
table {
width: 50%;
}
table:first-child tbody tr {
border-right: 0.3mm solid grey;
}
thead td {
height: 5mm;
border-width: 0.3mm 0;
font: bold 10px/1 Alegreya SC;
text-align: center;
border-color: grey;
}
tbody td {
height: 4.5mm;
border-width: 0.15mm 0;
&.check, &.enc, &.ic, &.sr, &.routine {
text-align: center;
}
&.name, &.sr {
font: 500 11px/1 Alegreya Sans;
}
&.comment, &.routine {
font: 400 11px/1 Alegreya Sans;
}
&.check, &.enc, &.ic {
font: 8px/1 Alegreya SC;
}
}
tbody tr.group td {
font-weight: bold;
}
td {
border-style: solid;
border-color: #c8c8c8;
&.ic {
width: 4.5mm;
}
&.routine {
width: 3mm;
}
&.name, &.check, &.enc, &.sr, &.comment {
padding: 0 1mm;
}
&.comment {
width: 28mm;
}
&:nth-child(2n) {
background: rgba(0, 0, 0, 0.1);
}
}
}
.lower {
flex: 1 1 auto;
display: flex;
position: relative;
> div {
flex: none;
}
}
.abilites {
display: flex;
flex-direction: column;
.textbox {
flex: 1 1 auto;
height: 50%;
}
h3 {
margin-top: 4.5mm;
}
}
.languages-list, .scripts-list {
font: 400 11px/4.5mm Alegreya Sans;
width: 68.2mm;
}
.languages-list {
td:last-child {
width: 10.4mm;
border-left: 0.15mm solid #c8c8c8;
text-align: center;
}
tr:not(:last-child) td {
height: 4.5mm;
border-bottom: 0.15mm solid #c8c8c8;
}
}
.quality-levels, .routine-checks {
table {
width: auto;
}
thead div {
word-wrap: break-word;
}
td {
text-align: center;
border-style: solid;
border-color: #c8c8c8;
}
td:nth-child(2n) {
background: rgba(0, 0, 0, 0.1);
}
thead td {
border-width: 0.3mm 0;
font: bold 10px/1 Alegreya SC;
border-color: grey;
}
tbody td {
height: 4.5mm;
border-width: 0.15mm 0;
font: 500 11px/1 Alegreya Sans;
padding: 0 1mm;
}
}
.routine-checks {
position: absolute;
width: 50%;
right: 0;
top: -9mm;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: flex-end;
height: 24mm;
h3, p {
text-align: right;
width: 44mm;
}
p {
font: bold 10px/1 Alegreya SC;
margin-top: 1mm;
white-space: pre-wrap;
letter-spacing: 0;
}
thead td {
height: 8mm;
}
td {
width: 11mm;
&:nth-child(2) {
border-right: 0.3mm solid grey;
}
&:nth-child(3) {
border-left: 0.3mm solid grey;
}
}
table {
flex: none;
}
}
.attribute-check-mods {
align-self: flex-end;
}
.quality-levels {
align-self: flex-end;
h3 {
margin-bottom: 4mm;
}
thead td {
height: 10mm;
}
td {
width: 18mm;
}
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ export default class SpellsSheet extends Component {
return (
<div className="sheet spells">
<SheetHeader title="Zauber & Rituale" add={addHeader} />
<SheetHeader title="Zauber & Rituale" add={[]} />
<div className="upper">
<TextBox label="Zauber & Rituale">
</TextBox>
-41
View File
@@ -1,41 +0,0 @@
import AttributeStore from '../../stores/AttributeStore';
import APStore from '../../stores/APStore';
import CultureStore from '../../stores/CultureStore';
import DisAdvStore from '../../stores/DisAdvStore';
import ELStore from '../../stores/ELStore';
import ProfessionStore from '../../stores/ProfessionStore';
import ProfessionVariantStore from '../../stores/ProfessionVariantStore';
import RaceStore from '../../stores/RaceStore';
import React, { Component } from 'react';
import SheetHeader from './SheetHeader';
import TextBox from '../../components/TextBox';
export default class TalentsSheet extends Component {
render() {
const source = {
attributes: AttributeStore.getAll(),
baseValues: AttributeStore.getBaseValues(),
race: RaceStore.getCurrentName(),
culture: CultureStore.getCurrentName(),
profession: ProfessionVariantStore.getCurrentName() !== null ? `${ProfessionStore.getCurrentName()} (${ProfessionVariantStore.getCurrentName()})` : ProfessionStore.getCurrentName(),
el: ELStore.getStart().name,
apTotal: APStore.getTotal(),
apUsed: APStore.getSpent(),
advActive: DisAdvStore.getActiveForView(true),
disadvActive: DisAdvStore.getActiveForView(false)
};
const { attributes, baseValues, race, culture, profession, el, apTotal, apUsed, advActive, disadvActive } = source;
return (
<div className="sheet talents">
<SheetHeader title="Spielwerte" />
<div className="upper">
<TextBox label="Fertigkeiten">
</TextBox>
</div>
</div>
);
}
}
-111
View File
@@ -1,111 +0,0 @@
#sheets .sheet-wrapper .sheet.talents {
position: relative;
.inline-table {
thead > tr > td:first-child > span {
padding-left: 5px;
}
tbody {
font-size: 9px;
}
h3 {
line-height: inherit;
display: inline-block;
}
tr.specs {
font-style: italic;
td {
padding-left: 30px !important;
}
}
td {
height: 18px;
line-height: 18px;
&.se {
width: 14px;
div {
@include size(8px);
border: 1px solid black;
border-radius: 5px;
}
}
&.name {
text-transform: none;
span:last-child {
float: right;
padding-right: 15px;
}
}
&.skt {
width: 18px;
}
&.be {
width: 30px;
}
&.at, &.pa {
width: 24px;
}
&.taw {
width: 40px;
}
}
}
.skill-categories {
margin-top: 0;
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: space-between;
height: calc(100% - 40px);
width: calc(100% + 20px);
> * {
margin: 20px 0 0 !important;
width: 50%;
padding-right: 20px;
padding-bottom: 40px;
border-spacing: 0;
}
> div {
margin-top: 20px;
> h3 {
line-height: 18px;
}
}
}
.left {
float: left;
padding-right: 10px;
> table:nth-child(2) {
flex: 0.2;
}
}
.right {
float: right;
padding-left: 10px;
> table:last-child {
flex: none;
}
}
}