15 Commits
main ... v12.0

Author SHA1 Message Date
803604c1fe Merge dice-roller branch 2024-07-26 14:15:51 +02:00
193c097882 v12 support 2024-07-26 12:51:32 +02:00
3aab5959fb Rework folder organization 2024-07-26 09:22:11 +02:00
575bb63d2f Rework folder organization 2024-07-26 09:20:48 +02:00
03fffa2f19 Merge pull request #7 from Cynicide/added-skill-category-import
Added system to skill category import
2022-10-25 22:05:07 +11:00
53c5b2ee6e Added system to skill category import
Initial Exhaustion Calculations
Fix for Skill Categories with two stats
Added Racial Bonuses for Resistances
2022-10-25 22:03:59 +11:00
8bc535cf35 Merge pull request #6 from Cynicide/added-spells-to-player-sheet
Added spells to player sheet
2022-09-23 00:52:51 +10:00
8d01c8f172 removed old readme 2022-09-23 00:52:21 +10:00
5fc1484484 Added spells and documentation 2022-09-23 00:51:21 +10:00
5f29bf1787 Merge pull request #5 from Cynicide/new-ranks-early-inventory
Add New Ranks chceckboxes
2022-09-18 21:31:40 +10:00
cab5aa07f3 Add New Ranks chceckboxes
Fix Updates for Skill/Skill Category Totals
Inventory Implementation
2022-09-18 21:31:15 +10:00
cfc645d888 Merge pull request #4 from Cynicide/add-skill-designations
Add skill designations
2022-09-14 20:01:17 +10:00
44996e945c Add skill designations
Fix drag and drop for skills and skill categories named the same
Set sane default values for attributes
Removed deprecated no grid sheets
2022-09-14 20:00:23 +10:00
08fd1f0fd6 Merge pull request #3 from Cynicide/Calculate-Skill-Totals
Calculate skill total bonuses
2022-09-12 06:25:03 +10:00
d5d5785383 Calculate skill total bonuses 2022-09-12 06:22:55 +10:00
146 changed files with 5143 additions and 1962 deletions

View File

@ -1,20 +1,33 @@
# Rolemaster Standard System for Foundry VTT
## Intro
## Introduction
This is an in-development implementation of the Rolemaster Standard System for FoundryVTT. All rights to the system remain property of Iron Crown Enterprises (http://ironcrown.com/). This system will not include any of the book content and aims to provide only what is on the character sheet.
This is an in development implementation of the Rolemaster Standard System for FoundryVTT. All rights to the system remain property of Iron Crown Enterprises (http://ironcrown.com/). This system will not include any of the book content and aims to provide only what is on the reproducable character sheet. If you need access to the Rolemaster Standard System please purchase a copy of the PDF's via Drive Thru RPG (https://www.drivethrurpg.com/browse/pub/461/Iron-Crown-Enterprises).
If you need access to the Rolemaster Standard System you may be out of luck as the system has been out of print for some time. However it's successor Rolemaster Fantasy Roleplaying is broadly compatible and can be purchased as a PDF via Drive Thru RPG here: https://www.drivethrurpg.com/product/91995/Rolemaster-Fantasy-Role-Playing?cPath=1361_6495
Early project goals include:
## How to Use
Download the latest release from this repository and then extract the rmss folder. Drag it into the systems folder of your FoundryVTT Data Directory. More detailed instructions can be found [here](docs/INSTALL.md) in the docs directory.
If you are using this system I highly recommend the "Simple Dice Roller" module which will allow you to roll dice easily while this feature is in development. You can install it in the Foundry Modules section or you can visit the following link for more instructions: https://foundryvtt.com/packages/simple-dice-roller/
Further information on how the system works can be found [here](docs/USAGE.md)
## Goals/ToDo
Project goals include:
- A functionaing character sheet that automates some of the basic maths.
- A dice roller that allows you to perform the most common rolls in the system.
- A basic combat tracker
## Credits
I maintain a public Trello board here where I log my work items: https://trello.com/b/JkXd5EGx/rmss-for-foundryvtt-features
## About Me
My name is Anthony, I'm a DevOps Engineer who has been playing Roleplaying Games since the mid 80's. I've been involved in numerous small programming projects. This system is by far the largest thing I've done. If the code here is awful it's because I'm learning CSS/Javascript as I go.
## Credits
This system is based on:
- the Foundry VTT Boilerplate system by XXX
- The Foundry VTT Boilerplate system by Asacolips. (https://gitlab.com/asacolips-projects/foundry-mods/boilerplate)
- The video tutorials by Cédric Hauteville you can watch them here: https://www.youtube.com/playlist?list=PLFV9z59nkHDccUbRXVt623UdloPTclIrz
Icons have been provided by https://game-icons.net
Icons used in this system have been sourced from https://game-icons.net
This system uses less for CSS you can see a good installation guide for VSCode at https://code.visualstudio.com/docs/languages/css#_transpiling-sass-and-less-into-css
This system uses less for CSS. If you change the CSS and need to rebuild it you can see a good installation guide for Less on VSCode at https://code.visualstudio.com/docs/languages/css#_transpiling-sass-and-less-into-css

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1 @@
<svg style="height: 512px; width: 512px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><g class="" style="" transform="translate(0,0)"><path d="M488 348.78h-70.24l-15.1 87.44-48.78-87.44H169v-50h190v-157h129zm-145-273v207H158.13l-48.79 87.47-15.11-87.47H24v-207zM136.724 215.324c0-10.139-12.257-15.214-19.425-8.046-7.168 7.168-2.093 19.426 8.046 19.426 6.285 0 11.38-5.095 11.38-11.38zm60.945 0c-.068-10.12-12.32-15.122-19.452-7.943-7.131 7.18-2.047 19.399 8.073 19.399 6.314 0 11.422-5.141 11.38-11.456zm60.945 0c0-10.139-12.257-15.214-19.425-8.046-7.169 7.168-2.093 19.426 8.046 19.426 6.284 0 11.38-5.095 11.38-11.38z" fill="#fff" fill-opacity="1"></path></g></svg>

After

Width:  |  Height:  |  Size: 680 B

View File

Before

Width:  |  Height:  |  Size: 996 B

After

Width:  |  Height:  |  Size: 996 B

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/fonts/PragRoman.ttf Normal file

Binary file not shown.

Binary file not shown.

68
assets/icons/R.svg Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="10mm"
height="10mm"
viewBox="0 0 10 10"
version="1.1"
id="svg8"
sodipodi:docname="R.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.2"
inkscape:cx="22.566968"
inkscape:cy="24.072623"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1672"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-287)">
<g
aria-label="R"
transform="matrix(0.26458333,0,0,0.26458333,-39.157593,262.07008)"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="flowRoot4539">
<path
d="m 161.01484,115.06095 q 1.08,0 2.28,0.92 1.24,0.88 2.4,2.08 1.2,1.2 2.28,2.44 1.08,1.2 1.92,1.88 2.08,1.68 4.16,3.32 2.08,1.6 4.2,3.24 0.56,0.44 1.04,0.8 0.48,0.4 0.96,0.68 0.52,0.28 1.08,0.44 0.6,0.16 1.36,0.16 0.56,0 0.68,-0.32 0.12,-0.28 0.12,-0.72 0,-0.8 -0.64,-1.8 -0.6,-1.04 -1.48,-2.04 -0.84,-1.04 -1.72,-1.96 -0.88,-0.92 -1.4,-1.52 -1.88,-2.2 -3.84,-4.4 -1.92,-2.2 -4,-4.24 0,-0.24 0,-0.4 0.04,-0.2 0.28,-0.36 1.32,-0.88 2.88,-1.68 1.56,-0.8 2.88,-1.8 1.32,-1.04 2.2,-2.4 0.92,-1.36 0.92,-3.28 0,-2.08 -0.72,-3.52 -0.72,-1.480002 -1.92,-2.440002 -1.2,-1 -2.76,-1.56 -1.56,-0.6 -3.28,-0.88 -1.72,-0.32 -3.48,-0.4 -1.72,-0.08 -3.28,-0.08 h -3.64 q -1.16,0 -2.36,0.12 -1.2,0.12 -2.36,0.12 -0.56,0 -1.44,-0.04 -0.88,-0.04 -1.72,0.08 -0.84,0.12 -1.44,0.52 -0.6,0.4 -0.6,1.28 0,0.56 0.48,0.84 0.48,0.24 1.12,0.4 0.64,0.12 1.28,0.24 0.68,0.12 1.04,0.36 -0.12,2.440002 -0.04,4.880002 0.08,2.44 0.2,4.92 0.12,2.44 0.24,4.92 0.12,2.44 0.12,4.88 0,1.8 -0.16,3.52 -0.12,1.72 -0.12,3.52 -0.4,0.48 -1.16,0.72 -0.72,0.2 -1.48,0.44 -0.72,0.2 -1.28,0.6 -0.52,0.36 -0.52,1.12 0,0.32 0.28,0.48 0.32,0.16 0.52,0.32 1.4,-0.04 2.72,-0.28 1.36,-0.24 2.76,-0.24 2.16,0 4.32,0.12 2.16,0.12 4.32,0.12 h 1.8 q 0.32,-0.16 0.56,-0.4 0.24,-0.24 0.24,-0.64 0,-0.72 -0.8,-1.08 -0.8,-0.4 -1.88,-0.6 -1.08,-0.2 -2.16,-0.28 -1.04,-0.08 -1.52,-0.2 -0.12,-0.04 -0.44,-0.12 -0.28,-0.12 -0.28,-0.32 v -10.2 z m 0,-2.08 q 0,-3.48 0.24,-6.92 0.28,-3.44 0.28,-6.920002 l 0.28,-0.52 0.24,-0.28 q 0.68,-0.04 1.28,-0.16 0.64,-0.12 1.32,-0.12 h 0.28 q 1.68,0.24 3.04,0.56 1.36,0.32 2.32,1 0.96,0.680002 1.44,1.880002 0.52,1.16 0.52,3.12 0,1.92 -0.36,3.2 -0.36,1.24 -1.04,2.04 -0.64,0.8 -1.56,1.28 -0.92,0.44 -2.04,0.76 -1.08,0.28 -2.36,0.6 -1.24,0.28 -2.56,0.76 -0.12,0 -0.36,0 -0.2,0 -0.44,0 -0.2,-0.04 -0.36,-0.08 -0.16,-0.08 -0.16,-0.2 z"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:40px;font-family:PragRoman;-inkscape-font-specification:'PragRoman, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start"
id="path4571"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,354 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" id="svg2" sodipodi:docname="_svgclean2.svg" viewBox="0 0 1015.8 687.24" version="1.1" inkscape:version="0.48.3.1 r9886">
<sodipodi:namedview id="namedview4" fit-margin-left="0" inkscape:zoom="0.75585938" borderopacity="1" inkscape:current-layer="svg2" inkscape:cx="600.99803" inkscape:guide-bbox="true" inkscape:window-maximized="0" showgrid="false" fit-margin-right="0" inkscape:snap-global="false" showguides="true" bordercolor="#666666" inkscape:window-x="0" guidetolerance="10" objecttolerance="10" inkscape:window-y="0" fit-margin-bottom="0" inkscape:window-width="512" inkscape:pageopacity="0" inkscape:pageshadow="2" pagecolor="#ffffff" gridtolerance="10" inkscape:cy="-21.199467" inkscape:window-height="452" fit-margin-top="0">
<sodipodi:guide id="guide3103" position="629.48057,1441.0961" orientation="1,0"/>
<sodipodi:guide id="guide3111" position="-942.56933,2326.5579" orientation="0,1"/>
<sodipodi:guide id="guide3113" position="-402.76913,1796.2278" orientation="0,1"/>
<sodipodi:guide id="guide3115" position="520.57347,2132.4192" orientation="1,0"/>
<sodipodi:guide id="guide3117" position="1817.9882,1403.2154" orientation="1,0"/>
<sodipodi:guide id="guide3133" position="449.54717,1138.0503" orientation="0,1"/>
<sodipodi:guide id="guide3135" position="501.63317,754.50797" orientation="0,1"/>
<sodipodi:guide id="guide3137" position="747.85787,228.91293" orientation="0,1"/>
<sodipodi:guide id="guide3263" position="261.91917,1110.2316" orientation="0,1"/>
<sodipodi:guide id="guide3265" position="256.00037,898.92817" orientation="0,1"/>
<sodipodi:guide id="guide3267" position="325.02107,1065.5962" orientation="0,1"/>
<sodipodi:guide id="guide3269" position="363.72367,1167.6446" orientation="0,1"/>
<sodipodi:guide id="guide3271" position="362.53987,840.33147" orientation="0,1"/>
<sodipodi:guide id="guide3273" position="31.675468,1096.0264" orientation="1,0"/>
<sodipodi:guide id="guide3275" position="453.34934,2.6762529" orientation="1,0"/>
<sodipodi:guide id="guide3277" position="257.77597,1086.5562" orientation="1,0"/>
<sodipodi:guide id="guide3279" position="112.17197,1149.888" orientation="1,0"/>
<sodipodi:guide id="guide3281" position="556.88497,1225.4735" orientation="1,0"/>
<sodipodi:guide id="guide3297" position="271.86817,863.02927" orientation="0,1"/>
<sodipodi:guide id="guide3308" position="390.35847,1003.1002" orientation="0,1"/>
<sodipodi:guide id="guide3310" position="352.47777,1062.2889" orientation="0,1"/>
<sodipodi:guide id="guide3319" position="161.79567,945.06047" orientation="0,1"/>
</sodipodi:namedview>
<flowRoot id="flowRoot3321" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="translate(1784.8 -879.48)">
<flowRegion id="flowRegion3323">
<rect id="rect3325" y="-1082" width="1098.5" x="-634.5" height="454.57"/>
</flowRegion>
<flowPara id="flowPara3327"/>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-9-8" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="translate(2745 74.666)">
<flowRegion id="flowRegion3331-4-2-5-9-3-4">
<rect id="rect3333-2-1-7-5-1-1" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-9-4" style="font-size:220px;font-weight:bold">Hit</flowPara>
</flowRoot>
<g id="g3579" transform="matrix(.38287 0 0 .38287 239.73 585.89)">
<path id="path3007" d="m-565.54-286.65 6.1004-89.981 150.68-85.405 155.86 91.506 0.91503 95.166-158.91 83.575-155.25-86.93z" style="stroke:#000000;stroke-width:5.8303;fill:none" inkscape:connector-curvature="0"/>
<path id="path3009" d="m-256.96-274.7-53.92 21.137-102.23 48.744-106.55-51.763 110-203.17 100.94 203.6" style="stroke:#000000;stroke-width:2.9152;fill:none" inkscape:connector-curvature="0"/>
<path id="path3017" d="m-565.82-280.74 46.587 23.725" style="stroke:#000000;stroke-width:2.9152;fill:none" inkscape:connector-curvature="0"/>
</g>
<g id="g3584" transform="matrix(.35906 0 0 .35906 227.8 591.51)">
<g id="g3034" transform="translate(-1094.9 127.23)">
<path id="path2989" sodipodi:nodetypes="cccccc" style="stroke:#000000;stroke-width:6;fill:none" inkscape:connector-curvature="0" d="m1176.4-341.82-229.98-18.579 2.0085-260.61 240.52 14.562 15.566 68.29z"/>
<path id="path2991" sodipodi:nodetypes="ccccc" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m947.44-360.91 9.5406-27.617 95.405-12.553 58.248-99.925 92.895-36.154"/>
<path id="path2993" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m1112.1-501.5-158.63-119.51"/>
<path id="path2995" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m956.48-387.02-5.5235-231.48"/>
<path id="path2997" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m1053.4-401.08 123.52 58.248"/>
</g>
</g>
<g id="g3592" transform="matrix(.34290 0 0 .34290 201.53 549.71)">
<g id="g3041" transform="translate(-837.05 478.79)">
<path id="path2999" style="stroke:#000000;stroke-width:10;fill:none" inkscape:connector-curvature="0" d="m310.86-215.78 32.639-179.76 181.77-94.401 160.68 138.59-22.596 178.26-185.79 90.384z"/>
<path id="path3001" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m313.37-215.78 164.2 24.102 182.78 15.064"/>
<path id="path3003" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m476.06-82.71 4.0171-108.96-92.393-200.35 230.48 25.609-137.58 175.24"/>
<path id="path3005" sodipodi:nodetypes="ccccc" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m315.38-217.28 72.307-175.75 138.59-92.393 91.388 118 44.69 188.3"/>
<path id="path3007-1" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m345-394.54 46.196 2.0085"/>
<path id="path3009-7" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m616.66-367.92 69.294 19.081"/>
</g>
</g>
<g id="g3242" transform="matrix(.25983 0 0 .25983 477.3 823.96)">
<g id="g3210" transform="matrix(.91589 0 0 .91589 -381.67 -74.793)">
<path id="path3172" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 -20.089)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
<path id="path3172-5" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 111.33)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
<path id="path3172-5-5" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 242.75)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
</g>
<g id="g3210-1" transform="matrix(.91589 0 0 .91589 -192.21 -74.793)">
<path id="path3172-7" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 -20.089)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
<path id="path3172-5-1" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 111.33)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
<path id="path3172-5-5-1" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 242.75)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
</g>
</g>
<path id="path3073" style="stroke:#000000;stroke-width:3.2246;fill:#ff0000" inkscape:connector-curvature="0" d="m1.6123 100.14 4.0557 3.8171h112.37l2.5592-4.4327-55.283-97.914h-4.5329z"/>
<flowRoot id="flowRoot3329" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 588.84 503.3)">
<flowRegion id="flowRegion3331">
<rect id="rect3333" y="-1096.2" width="421.42" x="-643.97" height="303.05"/>
</flowRegion>
<flowPara id="flowPara3391" style="font-size:220px;font-weight:bold">D4</flowPara>
</flowRoot>
<g id="g3129" transform="matrix(.19571 0 0 .19571 523.21 201.56)">
<path id="path3073-2" d="m-2354.9-392.57-296.96 338.75-1.0158-1.2344c100.54 117.51 199.33 237.47 298.62 356.38l3.2576-0.0829c98.3-117.58 189.88-243.49 288.16-360.29l-288.62-333.37z" sodipodi:nodetypes="cccccccc" style="stroke:#000000;stroke-width:16;fill:#ff0000" inkscape:connector-curvature="0"/>
<path id="path3105" d="m-2650.5-53.343 587.74-4.7351" style="stroke:#000000;stroke-width:6;fill:#ff0000" inkscape:connector-curvature="0"/>
</g>
<flowRoot id="flowRoot3329-5" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 762.98 504.82)">
<flowRegion id="flowRegion3331-2">
<rect id="rect3333-7" y="-1096.2" width="279.37" x="-643.97" height="222.55"/>
</flowRegion>
<flowPara id="flowPara3337-6" style="font-size:200px;font-weight:bold">D8</flowPara>
</flowRoot>
<rect id="rect3075" style="stroke:#000000;stroke-width:3.1257;fill:#ff0000" rx="6.3636" ry="9.4969" height="95.104" width="91.404" y="10.349" x="167.39"/>
<flowRoot id="flowRoot3329-1" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 675.87 501.87)">
<flowRegion id="flowRegion3331-4">
<rect id="rect3333-2" y="-1096.2" width="312.52" x="-643.97" height="227.28"/>
</flowRegion>
<flowPara id="flowPara3391-3" style="font-size:220px;font-weight:bold">D6</flowPara>
</flowRoot>
<g id="g3028" style="fill:#ff0000" transform="matrix(.18846 0 0 .18846 58.843 93.476)">
<path id="path2999-4" d="m531.52 523.73 19.011-70.352 277.45-258.73h9.4784l282.8 263.72 23.945 90.327-310.5 292.66-8.8497-0.47531-301.66-290.1z" sodipodi:nodetypes="cccccccccc" style="stroke:#000000;stroke-width:16;fill:#ff0000" inkscape:connector-curvature="0"/>
<path id="path3001-0" d="m519.04 547.65 111.3-61.37 199.64-291.63 198.72 300.99-200.72 95.89-199.72-107.33" sodipodi:nodetypes="cccccc" style="stroke:#000000;stroke-width:6;fill:#ff0000" inkscape:connector-curvature="0"/>
<path id="path3003-9" d="m1028.7 493.56 114.42 54.092" style="stroke:#000000;stroke-width:6;fill:#ff0000" inkscape:connector-curvature="0"/>
<path id="path3005-4" d="m828.72 591.66-0.73554 250.68" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:5.6871;fill:#ff0000" inkscape:connector-curvature="0"/>
</g>
<flowRoot id="flowRoot3329-1-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 846.66 499.81)">
<flowRegion id="flowRegion3331-4-2">
<rect id="rect3333-2-1" y="-1096.2" width="411.95" x="-643.97" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3391-3-6" style="font-size:220px;font-weight:bold">D10</flowPara>
</flowRoot>
<path id="path3283" sodipodi:nodetypes="ccccccccccc" style="stroke:#000000;stroke-width:4.9521;fill:#ff0000" inkscape:connector-curvature="0" d="m66.604 384.13 33.97-8.3455 23.883-36.237-2.749-31.304-22.247-26.861-32.307-6.8007-34.44 7.5108-21.433 27.662-3.1143 30.043 21.983 35.539z"/>
<path id="path3285" sodipodi:nodetypes="cccccc" style="stroke:#000000;stroke-width:1.7613;fill:#ff0000" inkscape:connector-curvature="0" d="m33.765 323.86 10.228 36.563 43.896 0.16485 10.249-36.599-30.919-23.74z"/>
<path id="path3287" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m67.154 274.95-0.18318 25.83"/>
<path id="path3289" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m34.287 325.37-24.377-15.72"/>
<path id="path3291" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m44.233 360.16-14.45 16.64"/>
<path id="path3293" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m87.683 360.71 13.267 15.263"/>
<path id="path3295" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m98.251 324.45 22.939-15.93"/>
<flowRoot id="flowRoot3329-1-2-8" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 966.57 498.37)">
<flowRegion id="flowRegion3331-4-2-5">
<rect id="rect3333-2-1-7" y="-1096.2" width="411.95" x="-643.97" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3391-3-6-6" style="font-size:220px;font-weight:bold">D12</flowPara>
</flowRoot>
<g id="g3162" transform="matrix(.25983 0 0 .25983 463.76 280.15)">
<path id="path3007-8" d="m-1160.8 71.357 208.07-122.82 208.03 122.23-11.16 232.13-197.46 122.23-196.88-119.29z" style="stroke:#000000;stroke-width:16;fill:#ff0000" inkscape:connector-curvature="0"/>
<g id="g3032" style="fill:#ff0000" transform="matrix(.39948 0 0 .39948 -1174.3 -120.6)">
<path id="path3017-8" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccccccc" style="stroke:#000000;stroke-width:8;fill:none" d="m560.49 177.48-4.4133 214.78m-314.82 594.33 639.93 7.35m-817.93 70.66 179.47-76.54 310.4 373.64 325.11-370.7 142.56 48.4m-960.32-541.11 497.07-104.55 491.15 106.02-177.81 489.77-317.76-597.27-314.81 592.86z"/>
</g>
</g>
<flowRoot id="flowRoot3329-1-2-8-1" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1080.1 499.13)">
<flowRegion id="flowRegion3331-4-2-5-8">
<rect id="rect3333-2-1-7-9" y="-1096.2" width="411.95" x="-643.97" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3391-3-6-6-2" style="font-size:220px;font-weight:bold">D20</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 469.73 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9">
<rect id="rect3333-2-1-7-5" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611" style="font-size:220px;font-weight:bold">1</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 529.34 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9-1">
<rect id="rect3333-2-1-7-5-2" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-3" style="font-size:220px;font-weight:bold">2</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 594.64 315.86)">
<flowRegion id="flowRegion3331-4-2-5-9-11">
<rect id="rect3333-2-1-7-5-3" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8" style="font-size:220px;font-weight:bold">3</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-7" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 637.31 382.27)">
<flowRegion id="flowRegion3331-4-2-5-9-4">
<rect id="rect3333-2-1-7-5-27" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-7" style="font-size:220px;font-weight:bold">14</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-9" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 720.27 381.86)">
<flowRegion id="flowRegion3331-4-2-5-9-3">
<rect id="rect3333-2-1-7-5-1" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-9" style="font-size:220px;font-weight:bold">15</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-8" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 803.23 381.97)">
<flowRegion id="flowRegion3331-4-2-5-9-6">
<rect id="rect3333-2-1-7-5-5" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-0" style="font-size:220px;font-weight:bold">16</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 886.19 382.38)">
<flowRegion id="flowRegion3331-4-2-5-9-8">
<rect id="rect3333-2-1-7-5-6" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-02" style="font-size:220px;font-weight:bold">17</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-4" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 969.15 381.74)">
<flowRegion id="flowRegion3331-4-2-5-9-86">
<rect id="rect3333-2-1-7-5-50" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-90" style="font-size:220px;font-weight:bold">18</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-0" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1052.1 381.79)">
<flowRegion id="flowRegion3331-4-2-5-9-61">
<rect id="rect3333-2-1-7-5-38" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-93" style="font-size:220px;font-weight:bold">19</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-44" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1138.2 382.08)">
<flowRegion id="flowRegion3331-4-2-5-9-60">
<rect id="rect3333-2-1-7-5-66" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-1" style="font-size:220px;font-weight:bold">20</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-8" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 661.45 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9-11-4">
<rect id="rect3333-2-1-7-5-3-9" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-6" style="font-size:220px;font-weight:bold">4</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 727.92 315.86)">
<flowRegion id="flowRegion3331-4-2-5-9-11-7">
<rect id="rect3333-2-1-7-5-3-8" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-8" style="font-size:220px;font-weight:bold">5</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 794.08 315.86)">
<flowRegion id="flowRegion3331-4-2-5-9-11-9">
<rect id="rect3333-2-1-7-5-3-1" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-3" style="font-size:220px;font-weight:bold">6</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-5" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 859.94 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9-11-98">
<rect id="rect3333-2-1-7-5-3-4" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-0" style="font-size:220px;font-weight:bold">7</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-7" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 925.41 315.83)">
<flowRegion id="flowRegion3331-4-2-5-9-11-6">
<rect id="rect3333-2-1-7-5-3-3" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-61" style="font-size:220px;font-weight:bold">8</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-54" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 991.35 315.83)">
<flowRegion id="flowRegion3331-4-2-5-9-11-2">
<rect id="rect3333-2-1-7-5-3-0" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-9" style="font-size:220px;font-weight:bold">9</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-73" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1054.5 315.86)">
<flowRegion id="flowRegion3331-4-2-5-9-11-72">
<rect id="rect3333-2-1-7-5-3-6" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-01" style="font-size:220px;font-weight:bold">10</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-6" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1149.3 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9-11-5">
<rect id="rect3333-2-1-7-5-3-7" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-5" style="font-size:220px;font-weight:bold">11</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-4" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 471.39 382.49)">
<flowRegion id="flowRegion3331-4-2-5-9-11-1">
<rect id="rect3333-2-1-7-5-3-2" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-00" style="font-size:220px;font-weight:bold">12</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-1" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 554.35 382.19)">
<flowRegion id="flowRegion3331-4-2-5-9-11-46">
<rect id="rect3333-2-1-7-5-3-07" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-1" style="font-size:220px;font-weight:bold">13</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-7-7" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 637.66 450.97)">
<flowRegion id="flowRegion3331-4-2-5-9-4-7">
<rect id="rect3333-2-1-7-5-27-7" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-7-7" style="font-size:220px;font-weight:bold">40</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-9-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 720.62 450.56)">
<flowRegion id="flowRegion3331-4-2-5-9-3-3">
<rect id="rect3333-2-1-7-5-1-5" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-9-9" style="font-size:220px;font-weight:bold">50</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-8-9" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 803.58 450.67)">
<flowRegion id="flowRegion3331-4-2-5-9-6-8">
<rect id="rect3333-2-1-7-5-5-1" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-0-8" style="font-size:220px;font-weight:bold">60</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-2-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 886.54 451.08)">
<flowRegion id="flowRegion3331-4-2-5-9-8-6">
<rect id="rect3333-2-1-7-5-6-6" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-02-0" style="font-size:220px;font-weight:bold">70</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-4-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 969.5 450.44)">
<flowRegion id="flowRegion3331-4-2-5-9-86-8">
<rect id="rect3333-2-1-7-5-50-0" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-90-1" style="font-size:220px;font-weight:bold">80</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-0-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1052.5 450.49)">
<flowRegion id="flowRegion3331-4-2-5-9-61-5">
<rect id="rect3333-2-1-7-5-38-0" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-93-9" style="font-size:220px;font-weight:bold">90</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-44-4" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1138.5 450.78)">
<flowRegion id="flowRegion3331-4-2-5-9-60-7">
<rect id="rect3333-2-1-7-5-66-8" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-1-3" style="font-size:220px;font-weight:bold"> 0</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-4-5" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 471.74 451.19)">
<flowRegion id="flowRegion3331-4-2-5-9-11-1-1">
<rect id="rect3333-2-1-7-5-3-2-2" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-00-0" style="font-size:220px;font-weight:bold">00</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-1-1" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 554.7 450.89)">
<flowRegion id="flowRegion3331-4-2-5-9-11-46-6">
<rect id="rect3333-2-1-7-5-3-07-4" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-1-0" style="font-size:220px;font-weight:bold">30</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-7-6" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 558.19 623.85)">
<flowRegion id="flowRegion3331-4-2-5-9-4-1">
<rect id="rect3333-2-1-7-5-27-8" y="-1200.4" width="374.07" x="-691.32" height="303.05"/>
</flowRegion>
<flowPara id="flowPara3611-7-9" style="font-size:300px;font-weight:bold">*</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-8-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 487.23 618.05)">
<flowRegion id="flowRegion3331-4-2-5-9-6-9">
<rect id="rect3333-2-1-7-5-5-8" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-0-80" style="font-size:220px;font-weight:bold">X</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-4-9" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 466.81 522.55)">
<flowRegion id="flowRegion3331-4-2-5-9-11-1-6">
<rect id="rect3333-2-1-7-5-3-2-8" ry="0" height="298.31" width="255.7" y="-1205.2" x="-691.32"/>
</flowRegion>
<flowPara id="flowPara3611-8-00-3" style="font-size:300px;font-weight:bold"> - </flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-1-4" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 539.31 524.4)">
<flowRegion id="flowRegion3331-4-2-5-9-11-46-8">
<rect id="rect3333-2-1-7-5-3-07-49" y="-1200.4" width="303.05" x="-691.32" height="307.78"/>
</flowRegion>
<flowPara id="flowPara3611-8-1-9" style="font-size:300px;font-weight:bold">+</flowPara>
</flowRoot>
<metadata id="metadata241">
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/>
<dc:publisher>
<cc:Agent rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 31 KiB

22
docs/INSTALL.md Normal file
View File

@ -0,0 +1,22 @@
# Installing the Rolemaster FoundryVTT System
## Download the System
As the system has not been officially released yet you won't be able to download it via the in game System browser. To install it you must download the System from the github repository and extract it to the right place in your FoundryVTT Data Directory.
Go to https://github.com/Cynicide/RMSS-FoundryVTT and click the green "Code" button from there click "Download Zip".
![Downloading the Zip](img/download.jpg)
## Extract and install the System
Using your favorite ZIP extractor (or Windows Explorer if you have none) you must find and extract the "rmss" directory and place it in the "systems" directory in your FoundryVTT Data Directory. As you are free to place this folder anywhere you want I can't tell you where it is. It's the same folder your Worlds go to when you create them in Foundry.
![Locating the rmss directory](img/locate.jpg)
![Installing the RMSS Directory](img/install.jpg)
## Checking you have installed properly
If you have installed the folder properly you should see Rolemaster under the Systems tab when you start Foundry.
![Installing the RMSS Directory](img/installed.jpg)
## Create a World
When you create a world you can now select Rolemaster Standard System from the System dropdown.
![Installing the RMSS Directory](img/create_world.jpg)

77
docs/USAGE.md Normal file
View File

@ -0,0 +1,77 @@
# Rolemaster Standard System for Foundry VTT Usage
## Understanding Foundry Data
In Foundry VTT characters, NPC's and Creatures are called Actors and almost everything else is referred to as an Item. As a result of this things in Rolemaster that you would associate with Characters like Skills and Skill Categories are actually items.
## Creating a Character
To create a character click on the Actor tab and click "Create Actor". You can choose between an NPC and a Character, however the NPC is unfinished at this point.
![Installing the RMSS Directory](img/create_actor.jpg)
Once you have create your Character you can view the character sheet.
![Installing the RMSS Directory](img/actor_sheet.jpg)
From here you can start filling out fields. Most fields are cosmetic at this point however as you start filling out your stats you will notice the Stat Bonus is auto calculated and Foundry will also attempt to calculate your Resistance Rolls (Racial Bonuses are not supported yet).
Skill Categories and Skills are considered Items by Foundry, see the following section.
## Understanding Items Types
When you create an item you will see the following drop down:
![Installing the RMSS Directory](img/create_item.jpg)
The items you can create are as follows:
- Skill Category
- Skill
- Spell
- Item
- Armor
- Weapon
- Transport (Not complete)
- Herb or Poison
Every item on this list can be dragged onto the character sheet and added to a character. Rather than making an item for each character, consider building a library of items that you can drag on to any character you want.
## Creating a Skill Category
When you create a Skill Category you can set the three dropdowns at the top to mark a stat as being applicable to this skill category. After you have done this Foundry will attempt to auto calculate the Stat Bonus when the Skill Category has been dragged onto a character sheet.
As you fill out the other fields Foundry will attempt to calculate the Total Bonus for this Skill Category.
![Installing the RMSS Directory](img/skill_category.jpg)
If you click on the Compendiums Tab you will find a compendium with the skill categories from the character sheet ready for you to use.
![Installing the RMSS Directory](img/skill_category_compendium.jpg)
## Dragging a Skill Category onto your Character Sheet
If you drag a skill category onto your character sheet that has the Applicable Stats set you can see that Foundry will apply the appropriate Stat Bonus to the Skill Category. Things like Ranks, Rank Bonuses, Profession Bonuses and Special Bonuses are manually entered but will be taken into account when the Total bonus is calculated.
If you make a mistake selecting the applicable stats you can just click the pencil icon to edit it.
![Installing the RMSS Directory](img/skill_category_stat_bonus.jpg)
## Creating a Skill
When you create a skill you will be unable to select a skill category as the skill has no owner and Foundry does not know what skill categories are available to it.
![Installing the RMSS Directory](img/create_skill.jpg)
Once you have dragged the Skill onto the character sheet you will be able select a skill category and Foundry will start to apply the Category Bonus. Like Skill Categories; things like Ranks, Rank Bonuses, Items Bonuses and Special Bonuses are manually entered but will be taken into account when the Total bonus is calculated.
![Installing the RMSS Directory](img/owned_skill.jpg)
When you select a skill as a favorite you can see it added to the front page of the character sheet for quick reference
![Installing the RMSS Directory](img/skill_favorite.jpg)
## Adding Items
Items such as mundane Items, Weapons, Armor and Herbs can be created in Foundry and then dragged to the Equipment Screen on the character sheet. Additionally they can be created directly on the sheet if need be. Items to not have any direct functionality yet and appear for record keeping purposes only.
![Installing the RMSS Directory](img/equipment.jpg)
## Adding Spells
Spells can be added to the Spells tab in much the same way that items can. They can be favorited and will appear on the front page of the character sheet. Spells to not have any direct functionality yet and appear for record keeping purposes only.
![Installing the RMSS Directory](img/spells.jpg)

BIN
docs/img/actor_sheet.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
docs/img/create_actor.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
docs/img/create_item.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
docs/img/create_skill.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
docs/img/create_world.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
docs/img/download.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
docs/img/equipment.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
docs/img/install.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/img/installed.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
docs/img/locate.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/img/owned_skill.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
docs/img/skill_category.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
docs/img/skill_favorite.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
docs/img/spells.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -1,5 +1,5 @@
var gulp = require('gulp');
var less = require('gulp.less');
var less = require('gulp-less');
gulp.task('less', function (cb) {
gulp
@ -15,4 +15,4 @@ gulp.task(
gulp.watch('less/*.less', gulp.series('less'));
cb();
})
);
);

View File

@ -33,11 +33,15 @@
"stat_total": "Total"
}
},
"pc_sheet": {
"import_skillcat": "Import"
},
"pc_sheet_tabs": {
"record": "Record",
"skill_categories": "Skill Categories",
"skills": "Skills",
"equipment": "Equipment",
"spells": "Spells",
"status_record": "Status Record",
"experience_points": "Experience Points"
},
@ -127,9 +131,11 @@
"prof_bonus": "Prof Bonus",
"special_bonus": "Special Bonus",
"total_bonus": "Total Bonus",
"add_skillcat": "Add Skill Category"
"import_skillcat": "Import Skill Categories"
},
"pc_sheet_items": {
"equipped": "Equipped",
"worn": "Worn",
"favorite": "Favorite",
"quantity": "Quantity",
"item_name": "Item Name",
@ -137,6 +143,21 @@
"cost": "Cost",
"add_item": "Add Item"
},
"pc_sheet_spell": {
"favorite": "Favorite",
"level": "Level",
"name": "Name",
"spell_list": "Spell List",
"area_of_effect": "Area of Effect",
"duration": "Duration",
"range": "Range",
"type": "Type"
},
"pc_sheet_language": {
"name": "Name",
"spoken": "Spoken",
"written": "Written"
},
"entity_sheet": {
"spell": "RMSS Spell",
"weapon": "RMSS Weapon",
@ -159,11 +180,13 @@
"cp": "Copper Pieces"
},
"item": {
"worn": "Worn",
"description": "Other Notes",
"quantity": "Quantity",
"weight": "Weight",
"cost": "Cost",
"prod_time": "Production Time"
"prod_time": "Production Time",
"equipped": "Equipped"
},
"armor": {
"at": "AT",
@ -178,7 +201,8 @@
"weight": "Weight",
"breakage_range": "B#s",
"strength": "Str",
"fumble_range": "Fumble"
"fumble_range": "Fumble",
"equipped": "Equipped"
},
"herb_or_poison": {
"codes": "Codes",
@ -198,6 +222,7 @@
"offensive_bonus": "OB"
},
"spell": {
"favorite": "Favorite",
"spell_list": "Spell List",
"level": "Level",
"area_of_effect": "Area of Effect",
@ -230,6 +255,11 @@
"special_bonus_2": "Special Bonus 2:",
"total_bonus": "Total Bonus:",
"description": "Description:"
},
"language": {
"spoken": "Spoken",
"written": "Written",
"description": "Description"
}
}
}

View File

@ -0,0 +1,44 @@
.armor-grid-container {
display: grid;
grid-template-columns: [name] 30% [equipped] 12% [at] 12% [quantity] 12% [weight] 12% [cost] 12% [controls] 10%;
}
.armor-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.armor-grid-container > div:nth-child(14n+1),
.armor-grid-container > div:nth-child(14n+2),
.armor-grid-container > div:nth-child(14n+3),
.armor-grid-container > div:nth-child(14n+4),
.armor-grid-container > div:nth-child(14n+5),
.armor-grid-container > div:nth-child(14n+6),
.armor-grid-container > div:nth-child(14n+7)
{
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.armor-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}

View File

@ -0,0 +1,44 @@
.herbs-grid-container {
display: grid;
grid-template-columns: [name] 30% [quantity] 11% [codes] 12% [af] 12% [weight] 12% [cost] 11% [controls] 12%;
}
.herbs-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.herbs-grid-container > div:nth-child(14n+1),
.herbs-grid-container > div:nth-child(14n+2),
.herbs-grid-container > div:nth-child(14n+3),
.herbs-grid-container > div:nth-child(14n+4),
.herbs-grid-container > div:nth-child(14n+5),
.herbs-grid-container > div:nth-child(14n+6),
.herbs-grid-container > div:nth-child(14n+7)
{
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.herbs-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}

View File

@ -0,0 +1,43 @@
.items-grid-container {
display: grid;
grid-template-columns: [worn] 10% [name] 30% [quantity] 15% [weight] 15% [cost] 15% [controls] 15%;
}
.items-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.items-grid-container > div:nth-child(12n+1),
.items-grid-container > div:nth-child(12n+2),
.items-grid-container > div:nth-child(12n+3),
.items-grid-container > div:nth-child(12n+4),
.items-grid-container > div:nth-child(12n+5),
.items-grid-container > div:nth-child(12n+6)
{
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.items-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}

View File

@ -0,0 +1,9 @@
.money-column {
flex-direction: column;
}
.money-container {
flex-direction: column;
flex-shrink: 1;
padding-left: 10px;
}

View File

@ -0,0 +1,18 @@
.resistances-grid-container {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
display: grid;
grid-template-columns: [Name] 40% [Value] 20% [Race_Mod] 20% [Total] 20%;
}
.resistances-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.resistance-input {
width: 50%
}

View File

@ -0,0 +1,49 @@
.skillcat-grid-container {
display: grid;
grid-template-columns: [skill-category-name] 10% [applicable-stats] 10% [dev-cost] 8% [num-ranks] 8% [new-ranks] 8% [rank-bonus] 8% [stat-bonus] 8% [prof-bonus] 8% [special-bonus-1] 8% [special-bonus-2] 8% [total-bonus] 8% [controls] 8%;
}
.skillcat-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
//flex-direction: column;
justify-content: center;
}
.skillcat-grid-container > div:nth-child(24n+1),
.skillcat-grid-container > div:nth-child(24n+2),
.skillcat-grid-container > div:nth-child(24n+3),
.skillcat-grid-container > div:nth-child(24n+4),
.skillcat-grid-container > div:nth-child(24n+5),
.skillcat-grid-container > div:nth-child(24n+6),
.skillcat-grid-container > div:nth-child(24n+7),
.skillcat-grid-container > div:nth-child(24n+8),
.skillcat-grid-container > div:nth-child(24n+9),
.skillcat-grid-container > div:nth-child(24n+10),
.skillcat-grid-container > div:nth-child(24n+11),
.skillcat-grid-container > div:nth-child(24n+12)
{
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
//flex-direction: column;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.skillcat-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}

View File

@ -0,0 +1,48 @@
.skills-grid-container {
display: grid;
grid-template-columns: [favorite] 9% [skill-name] 11% [num-ranks] 9% [new-ranks] 9% [rank-bonus] 9% [category-bonus] 9% [item-bonus] 9% [special-bonus-1] 9% [special-bonus-2] 9% [total-bonus] 9% [controls] 8%;
}
.skills-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: column;
justify-content: center;
}
.skills-grid-container > div:nth-child(22n+1),
.skills-grid-container > div:nth-child(22n+2),
.skills-grid-container > div:nth-child(22n+3),
.skills-grid-container > div:nth-child(22n+4),
.skills-grid-container > div:nth-child(22n+5),
.skills-grid-container > div:nth-child(22n+6),
.skills-grid-container > div:nth-child(22n+7),
.skills-grid-container > div:nth-child(22n+8),
.skills-grid-container > div:nth-child(22n+9),
.skills-grid-container > div:nth-child(22n+10),
.skills-grid-container > div:nth-child(22n+11)
{
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: column;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.skills-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}

View File

@ -0,0 +1,46 @@
.spell-grid-container {
display: grid;
grid-template-columns: [favorite] 9% [level] 8% [name] 30% [spell_list] 9% [area_of_effect] 9% [duration] 9% [range] 9% [type] 9% [controls] 8%;
}
.spell-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.spell-grid-container > div:nth-child(18n+1),
.spell-grid-container > div:nth-child(18n+2),
.spell-grid-container > div:nth-child(18n+3),
.spell-grid-container > div:nth-child(18n+4),
.spell-grid-container > div:nth-child(18n+5),
.spell-grid-container > div:nth-child(18n+6),
.spell-grid-container > div:nth-child(18n+7),
.spell-grid-container > div:nth-child(18n+8),
.spell-grid-container > div:nth-child(18n+9)
{
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.spell-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}

View File

@ -0,0 +1,46 @@
.weapons-grid-container {
display: grid;
grid-template-columns: [name] 30% [equipped] 8% [breakage_range] 9% [fumble_range] 9% [strength] 9% [quantity] 9% [weight] 9% [cost] 9% [controls] 8%;
}
.weapons-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.weapons-grid-container > div:nth-child(18n+1),
.weapons-grid-container > div:nth-child(18n+2),
.weapons-grid-container > div:nth-child(18n+3),
.weapons-grid-container > div:nth-child(18n+4),
.weapons-grid-container > div:nth-child(18n+5),
.weapons-grid-container > div:nth-child(18n+6),
.weapons-grid-container > div:nth-child(18n+7),
.weapons-grid-container > div:nth-child(18n+8),
.weapons-grid-container > div:nth-child(18n+9)
{
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.weapons-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}

View File

@ -0,0 +1,173 @@
// General Elements
.container {
display: flex;
}
.rm-heading {
font-size: 1.0em;
font-family: PragRoman;
border-bottom: 0px;
}
// Header CSS
.actor-icon {
flex-shrink: 1;
}
.favorite-container {
padding: 5px;
}
.header-container {
flex-grow: 2;
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.header-text {
display: flex;
align-items: center;
padding: 1px;
}
.settings-button, .playersheet-settings {
font-family: Signika, sans-serif;
font-size: 12px;
margin-right: 6px
}
// Resource Elements in Headers
.resource-container {
display: flex;
flex-direction: row;
flex-grow: 3;
text-align: -webkit-center;
}
.resource-container > * {
flex: 1 1 0;
}
.resource-entry {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.resource-entry input{
width: 50px;
border: none;
}
.stat-container {
flex-direction: column;
flex-shrink: 1;
}
.stat-row {
align-items: center;
}
.equipment-container {
flex-direction: column;
flex-grow: 1;
}
.stat-block {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.stat-name, .money-name {
width: 75px;
border: none;
font-family: Signika, sans-serif;
font-size: 12px;
}
.stat-name input {
border: none;
}
.stat-header {
font-family: Signika, sans-serif;
font-size: 12px;
}
// Fixed Info CSS
.fixed-info-container {
flex-grow: 3;
flex-direction: row;
font-family: Signika, sans-serif;
font-size: 12px;
}
.fixed-info-section {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.armor-block {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.race-stat-fixed-info-block {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.role-traits-block {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.background-info-block {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
// Remove Me
.resistance-block {
outline: 1px solid; /* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
// Debugging
.red {
background-color: orangered;
}
.blue {
background-color: lightblue;
}
.grey {
background-color: lightgrey;
}
.green {
background-color: lightseagreen;
}

68
less/icons/R.svg Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="10mm"
height="10mm"
viewBox="0 0 10 10"
version="1.1"
id="svg8"
sodipodi:docname="R.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.2"
inkscape:cx="22.566968"
inkscape:cy="24.072623"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1672"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-287)">
<g
aria-label="R"
transform="matrix(0.26458333,0,0,0.26458333,-39.157593,262.07008)"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="flowRoot4539">
<path
d="m 161.01484,115.06095 q 1.08,0 2.28,0.92 1.24,0.88 2.4,2.08 1.2,1.2 2.28,2.44 1.08,1.2 1.92,1.88 2.08,1.68 4.16,3.32 2.08,1.6 4.2,3.24 0.56,0.44 1.04,0.8 0.48,0.4 0.96,0.68 0.52,0.28 1.08,0.44 0.6,0.16 1.36,0.16 0.56,0 0.68,-0.32 0.12,-0.28 0.12,-0.72 0,-0.8 -0.64,-1.8 -0.6,-1.04 -1.48,-2.04 -0.84,-1.04 -1.72,-1.96 -0.88,-0.92 -1.4,-1.52 -1.88,-2.2 -3.84,-4.4 -1.92,-2.2 -4,-4.24 0,-0.24 0,-0.4 0.04,-0.2 0.28,-0.36 1.32,-0.88 2.88,-1.68 1.56,-0.8 2.88,-1.8 1.32,-1.04 2.2,-2.4 0.92,-1.36 0.92,-3.28 0,-2.08 -0.72,-3.52 -0.72,-1.480002 -1.92,-2.440002 -1.2,-1 -2.76,-1.56 -1.56,-0.6 -3.28,-0.88 -1.72,-0.32 -3.48,-0.4 -1.72,-0.08 -3.28,-0.08 h -3.64 q -1.16,0 -2.36,0.12 -1.2,0.12 -2.36,0.12 -0.56,0 -1.44,-0.04 -0.88,-0.04 -1.72,0.08 -0.84,0.12 -1.44,0.52 -0.6,0.4 -0.6,1.28 0,0.56 0.48,0.84 0.48,0.24 1.12,0.4 0.64,0.12 1.28,0.24 0.68,0.12 1.04,0.36 -0.12,2.440002 -0.04,4.880002 0.08,2.44 0.2,4.92 0.12,2.44 0.24,4.92 0.12,2.44 0.12,4.88 0,1.8 -0.16,3.52 -0.12,1.72 -0.12,3.52 -0.4,0.48 -1.16,0.72 -0.72,0.2 -1.48,0.44 -0.72,0.2 -1.28,0.6 -0.52,0.36 -0.52,1.12 0,0.32 0.28,0.48 0.32,0.16 0.52,0.32 1.4,-0.04 2.72,-0.28 1.36,-0.24 2.76,-0.24 2.16,0 4.32,0.12 2.16,0.12 4.32,0.12 h 1.8 q 0.32,-0.16 0.56,-0.4 0.24,-0.24 0.24,-0.64 0,-0.72 -0.8,-1.08 -0.8,-0.4 -1.88,-0.6 -1.08,-0.2 -2.16,-0.28 -1.04,-0.08 -1.52,-0.2 -0.12,-0.04 -0.44,-0.12 -0.28,-0.12 -0.28,-0.32 v -10.2 z m 0,-2.08 q 0,-3.48 0.24,-6.92 0.28,-3.44 0.28,-6.920002 l 0.28,-0.52 0.24,-0.28 q 0.68,-0.04 1.28,-0.16 0.64,-0.12 1.32,-0.12 h 0.28 q 1.68,0.24 3.04,0.56 1.36,0.32 2.32,1 0.96,0.680002 1.44,1.880002 0.52,1.16 0.52,3.12 0,1.92 -0.36,3.2 -0.36,1.24 -1.04,2.04 -0.64,0.8 -1.56,1.28 -0.92,0.44 -2.04,0.76 -1.08,0.28 -2.36,0.6 -1.24,0.28 -2.56,0.76 -0.12,0 -0.36,0 -0.2,0 -0.44,0 -0.2,-0.04 -0.36,-0.08 -0.16,-0.08 -0.16,-0.2 z"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:40px;font-family:PragRoman;-inkscape-font-specification:'PragRoman, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start"
id="path4571"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,354 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" id="svg2" sodipodi:docname="_svgclean2.svg" viewBox="0 0 1015.8 687.24" version="1.1" inkscape:version="0.48.3.1 r9886">
<sodipodi:namedview id="namedview4" fit-margin-left="0" inkscape:zoom="0.75585938" borderopacity="1" inkscape:current-layer="svg2" inkscape:cx="600.99803" inkscape:guide-bbox="true" inkscape:window-maximized="0" showgrid="false" fit-margin-right="0" inkscape:snap-global="false" showguides="true" bordercolor="#666666" inkscape:window-x="0" guidetolerance="10" objecttolerance="10" inkscape:window-y="0" fit-margin-bottom="0" inkscape:window-width="512" inkscape:pageopacity="0" inkscape:pageshadow="2" pagecolor="#ffffff" gridtolerance="10" inkscape:cy="-21.199467" inkscape:window-height="452" fit-margin-top="0">
<sodipodi:guide id="guide3103" position="629.48057,1441.0961" orientation="1,0"/>
<sodipodi:guide id="guide3111" position="-942.56933,2326.5579" orientation="0,1"/>
<sodipodi:guide id="guide3113" position="-402.76913,1796.2278" orientation="0,1"/>
<sodipodi:guide id="guide3115" position="520.57347,2132.4192" orientation="1,0"/>
<sodipodi:guide id="guide3117" position="1817.9882,1403.2154" orientation="1,0"/>
<sodipodi:guide id="guide3133" position="449.54717,1138.0503" orientation="0,1"/>
<sodipodi:guide id="guide3135" position="501.63317,754.50797" orientation="0,1"/>
<sodipodi:guide id="guide3137" position="747.85787,228.91293" orientation="0,1"/>
<sodipodi:guide id="guide3263" position="261.91917,1110.2316" orientation="0,1"/>
<sodipodi:guide id="guide3265" position="256.00037,898.92817" orientation="0,1"/>
<sodipodi:guide id="guide3267" position="325.02107,1065.5962" orientation="0,1"/>
<sodipodi:guide id="guide3269" position="363.72367,1167.6446" orientation="0,1"/>
<sodipodi:guide id="guide3271" position="362.53987,840.33147" orientation="0,1"/>
<sodipodi:guide id="guide3273" position="31.675468,1096.0264" orientation="1,0"/>
<sodipodi:guide id="guide3275" position="453.34934,2.6762529" orientation="1,0"/>
<sodipodi:guide id="guide3277" position="257.77597,1086.5562" orientation="1,0"/>
<sodipodi:guide id="guide3279" position="112.17197,1149.888" orientation="1,0"/>
<sodipodi:guide id="guide3281" position="556.88497,1225.4735" orientation="1,0"/>
<sodipodi:guide id="guide3297" position="271.86817,863.02927" orientation="0,1"/>
<sodipodi:guide id="guide3308" position="390.35847,1003.1002" orientation="0,1"/>
<sodipodi:guide id="guide3310" position="352.47777,1062.2889" orientation="0,1"/>
<sodipodi:guide id="guide3319" position="161.79567,945.06047" orientation="0,1"/>
</sodipodi:namedview>
<flowRoot id="flowRoot3321" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="translate(1784.8 -879.48)">
<flowRegion id="flowRegion3323">
<rect id="rect3325" y="-1082" width="1098.5" x="-634.5" height="454.57"/>
</flowRegion>
<flowPara id="flowPara3327"/>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-9-8" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="translate(2745 74.666)">
<flowRegion id="flowRegion3331-4-2-5-9-3-4">
<rect id="rect3333-2-1-7-5-1-1" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-9-4" style="font-size:220px;font-weight:bold">Hit</flowPara>
</flowRoot>
<g id="g3579" transform="matrix(.38287 0 0 .38287 239.73 585.89)">
<path id="path3007" d="m-565.54-286.65 6.1004-89.981 150.68-85.405 155.86 91.506 0.91503 95.166-158.91 83.575-155.25-86.93z" style="stroke:#000000;stroke-width:5.8303;fill:none" inkscape:connector-curvature="0"/>
<path id="path3009" d="m-256.96-274.7-53.92 21.137-102.23 48.744-106.55-51.763 110-203.17 100.94 203.6" style="stroke:#000000;stroke-width:2.9152;fill:none" inkscape:connector-curvature="0"/>
<path id="path3017" d="m-565.82-280.74 46.587 23.725" style="stroke:#000000;stroke-width:2.9152;fill:none" inkscape:connector-curvature="0"/>
</g>
<g id="g3584" transform="matrix(.35906 0 0 .35906 227.8 591.51)">
<g id="g3034" transform="translate(-1094.9 127.23)">
<path id="path2989" sodipodi:nodetypes="cccccc" style="stroke:#000000;stroke-width:6;fill:none" inkscape:connector-curvature="0" d="m1176.4-341.82-229.98-18.579 2.0085-260.61 240.52 14.562 15.566 68.29z"/>
<path id="path2991" sodipodi:nodetypes="ccccc" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m947.44-360.91 9.5406-27.617 95.405-12.553 58.248-99.925 92.895-36.154"/>
<path id="path2993" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m1112.1-501.5-158.63-119.51"/>
<path id="path2995" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m956.48-387.02-5.5235-231.48"/>
<path id="path2997" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m1053.4-401.08 123.52 58.248"/>
</g>
</g>
<g id="g3592" transform="matrix(.34290 0 0 .34290 201.53 549.71)">
<g id="g3041" transform="translate(-837.05 478.79)">
<path id="path2999" style="stroke:#000000;stroke-width:10;fill:none" inkscape:connector-curvature="0" d="m310.86-215.78 32.639-179.76 181.77-94.401 160.68 138.59-22.596 178.26-185.79 90.384z"/>
<path id="path3001" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m313.37-215.78 164.2 24.102 182.78 15.064"/>
<path id="path3003" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m476.06-82.71 4.0171-108.96-92.393-200.35 230.48 25.609-137.58 175.24"/>
<path id="path3005" sodipodi:nodetypes="ccccc" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m315.38-217.28 72.307-175.75 138.59-92.393 91.388 118 44.69 188.3"/>
<path id="path3007-1" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m345-394.54 46.196 2.0085"/>
<path id="path3009-7" style="stroke:#000000;stroke-width:2;fill:none" inkscape:connector-curvature="0" d="m616.66-367.92 69.294 19.081"/>
</g>
</g>
<g id="g3242" transform="matrix(.25983 0 0 .25983 477.3 823.96)">
<g id="g3210" transform="matrix(.91589 0 0 .91589 -381.67 -74.793)">
<path id="path3172" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 -20.089)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
<path id="path3172-5" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 111.33)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
<path id="path3172-5-5" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 242.75)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
</g>
<g id="g3210-1" transform="matrix(.91589 0 0 .91589 -192.21 -74.793)">
<path id="path3172-7" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 -20.089)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
<path id="path3172-5-1" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 111.33)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
<path id="path3172-5-5-1" sodipodi:rx="31.808037" sodipodi:ry="31.808037" style="stroke:#000000;stroke-width:16;fill:#000000" sodipodi:type="arc" d="m-1044.6-963.58c0 17.567-14.241 31.808-31.808 31.808s-31.808-14.241-31.808-31.808 14.241-31.808 31.808-31.808 31.808 14.241 31.808 31.808z" transform="translate(336.5 242.75)" sodipodi:cy="-963.58374" sodipodi:cx="-1076.4509"/>
</g>
</g>
<path id="path3073" style="stroke:#000000;stroke-width:3.2246;fill:#ff0000" inkscape:connector-curvature="0" d="m1.6123 100.14 4.0557 3.8171h112.37l2.5592-4.4327-55.283-97.914h-4.5329z"/>
<flowRoot id="flowRoot3329" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 588.84 503.3)">
<flowRegion id="flowRegion3331">
<rect id="rect3333" y="-1096.2" width="421.42" x="-643.97" height="303.05"/>
</flowRegion>
<flowPara id="flowPara3391" style="font-size:220px;font-weight:bold">D4</flowPara>
</flowRoot>
<g id="g3129" transform="matrix(.19571 0 0 .19571 523.21 201.56)">
<path id="path3073-2" d="m-2354.9-392.57-296.96 338.75-1.0158-1.2344c100.54 117.51 199.33 237.47 298.62 356.38l3.2576-0.0829c98.3-117.58 189.88-243.49 288.16-360.29l-288.62-333.37z" sodipodi:nodetypes="cccccccc" style="stroke:#000000;stroke-width:16;fill:#ff0000" inkscape:connector-curvature="0"/>
<path id="path3105" d="m-2650.5-53.343 587.74-4.7351" style="stroke:#000000;stroke-width:6;fill:#ff0000" inkscape:connector-curvature="0"/>
</g>
<flowRoot id="flowRoot3329-5" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 762.98 504.82)">
<flowRegion id="flowRegion3331-2">
<rect id="rect3333-7" y="-1096.2" width="279.37" x="-643.97" height="222.55"/>
</flowRegion>
<flowPara id="flowPara3337-6" style="font-size:200px;font-weight:bold">D8</flowPara>
</flowRoot>
<rect id="rect3075" style="stroke:#000000;stroke-width:3.1257;fill:#ff0000" rx="6.3636" ry="9.4969" height="95.104" width="91.404" y="10.349" x="167.39"/>
<flowRoot id="flowRoot3329-1" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 675.87 501.87)">
<flowRegion id="flowRegion3331-4">
<rect id="rect3333-2" y="-1096.2" width="312.52" x="-643.97" height="227.28"/>
</flowRegion>
<flowPara id="flowPara3391-3" style="font-size:220px;font-weight:bold">D6</flowPara>
</flowRoot>
<g id="g3028" style="fill:#ff0000" transform="matrix(.18846 0 0 .18846 58.843 93.476)">
<path id="path2999-4" d="m531.52 523.73 19.011-70.352 277.45-258.73h9.4784l282.8 263.72 23.945 90.327-310.5 292.66-8.8497-0.47531-301.66-290.1z" sodipodi:nodetypes="cccccccccc" style="stroke:#000000;stroke-width:16;fill:#ff0000" inkscape:connector-curvature="0"/>
<path id="path3001-0" d="m519.04 547.65 111.3-61.37 199.64-291.63 198.72 300.99-200.72 95.89-199.72-107.33" sodipodi:nodetypes="cccccc" style="stroke:#000000;stroke-width:6;fill:#ff0000" inkscape:connector-curvature="0"/>
<path id="path3003-9" d="m1028.7 493.56 114.42 54.092" style="stroke:#000000;stroke-width:6;fill:#ff0000" inkscape:connector-curvature="0"/>
<path id="path3005-4" d="m828.72 591.66-0.73554 250.68" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:5.6871;fill:#ff0000" inkscape:connector-curvature="0"/>
</g>
<flowRoot id="flowRoot3329-1-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 846.66 499.81)">
<flowRegion id="flowRegion3331-4-2">
<rect id="rect3333-2-1" y="-1096.2" width="411.95" x="-643.97" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3391-3-6" style="font-size:220px;font-weight:bold">D10</flowPara>
</flowRoot>
<path id="path3283" sodipodi:nodetypes="ccccccccccc" style="stroke:#000000;stroke-width:4.9521;fill:#ff0000" inkscape:connector-curvature="0" d="m66.604 384.13 33.97-8.3455 23.883-36.237-2.749-31.304-22.247-26.861-32.307-6.8007-34.44 7.5108-21.433 27.662-3.1143 30.043 21.983 35.539z"/>
<path id="path3285" sodipodi:nodetypes="cccccc" style="stroke:#000000;stroke-width:1.7613;fill:#ff0000" inkscape:connector-curvature="0" d="m33.765 323.86 10.228 36.563 43.896 0.16485 10.249-36.599-30.919-23.74z"/>
<path id="path3287" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m67.154 274.95-0.18318 25.83"/>
<path id="path3289" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m34.287 325.37-24.377-15.72"/>
<path id="path3291" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m44.233 360.16-14.45 16.64"/>
<path id="path3293" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m87.683 360.71 13.267 15.263"/>
<path id="path3295" sodipodi:nodetypes="cc" style="stroke:#000000;stroke-width:1.857;fill:#ff0000" inkscape:connector-curvature="0" d="m98.251 324.45 22.939-15.93"/>
<flowRoot id="flowRoot3329-1-2-8" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 966.57 498.37)">
<flowRegion id="flowRegion3331-4-2-5">
<rect id="rect3333-2-1-7" y="-1096.2" width="411.95" x="-643.97" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3391-3-6-6" style="font-size:220px;font-weight:bold">D12</flowPara>
</flowRoot>
<g id="g3162" transform="matrix(.25983 0 0 .25983 463.76 280.15)">
<path id="path3007-8" d="m-1160.8 71.357 208.07-122.82 208.03 122.23-11.16 232.13-197.46 122.23-196.88-119.29z" style="stroke:#000000;stroke-width:16;fill:#ff0000" inkscape:connector-curvature="0"/>
<g id="g3032" style="fill:#ff0000" transform="matrix(.39948 0 0 .39948 -1174.3 -120.6)">
<path id="path3017-8" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccccccc" style="stroke:#000000;stroke-width:8;fill:none" d="m560.49 177.48-4.4133 214.78m-314.82 594.33 639.93 7.35m-817.93 70.66 179.47-76.54 310.4 373.64 325.11-370.7 142.56 48.4m-960.32-541.11 497.07-104.55 491.15 106.02-177.81 489.77-317.76-597.27-314.81 592.86z"/>
</g>
</g>
<flowRoot id="flowRoot3329-1-2-8-1" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1080.1 499.13)">
<flowRegion id="flowRegion3331-4-2-5-8">
<rect id="rect3333-2-1-7-9" y="-1096.2" width="411.95" x="-643.97" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3391-3-6-6-2" style="font-size:220px;font-weight:bold">D20</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 469.73 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9">
<rect id="rect3333-2-1-7-5" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611" style="font-size:220px;font-weight:bold">1</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 529.34 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9-1">
<rect id="rect3333-2-1-7-5-2" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-3" style="font-size:220px;font-weight:bold">2</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 594.64 315.86)">
<flowRegion id="flowRegion3331-4-2-5-9-11">
<rect id="rect3333-2-1-7-5-3" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8" style="font-size:220px;font-weight:bold">3</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-7" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 637.31 382.27)">
<flowRegion id="flowRegion3331-4-2-5-9-4">
<rect id="rect3333-2-1-7-5-27" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-7" style="font-size:220px;font-weight:bold">14</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-9" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 720.27 381.86)">
<flowRegion id="flowRegion3331-4-2-5-9-3">
<rect id="rect3333-2-1-7-5-1" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-9" style="font-size:220px;font-weight:bold">15</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-8" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 803.23 381.97)">
<flowRegion id="flowRegion3331-4-2-5-9-6">
<rect id="rect3333-2-1-7-5-5" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-0" style="font-size:220px;font-weight:bold">16</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 886.19 382.38)">
<flowRegion id="flowRegion3331-4-2-5-9-8">
<rect id="rect3333-2-1-7-5-6" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-02" style="font-size:220px;font-weight:bold">17</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-4" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 969.15 381.74)">
<flowRegion id="flowRegion3331-4-2-5-9-86">
<rect id="rect3333-2-1-7-5-50" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-90" style="font-size:220px;font-weight:bold">18</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-0" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1052.1 381.79)">
<flowRegion id="flowRegion3331-4-2-5-9-61">
<rect id="rect3333-2-1-7-5-38" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-93" style="font-size:220px;font-weight:bold">19</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-44" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1138.2 382.08)">
<flowRegion id="flowRegion3331-4-2-5-9-60">
<rect id="rect3333-2-1-7-5-66" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-1" style="font-size:220px;font-weight:bold">20</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-8" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 661.45 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9-11-4">
<rect id="rect3333-2-1-7-5-3-9" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-6" style="font-size:220px;font-weight:bold">4</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 727.92 315.86)">
<flowRegion id="flowRegion3331-4-2-5-9-11-7">
<rect id="rect3333-2-1-7-5-3-8" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-8" style="font-size:220px;font-weight:bold">5</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 794.08 315.86)">
<flowRegion id="flowRegion3331-4-2-5-9-11-9">
<rect id="rect3333-2-1-7-5-3-1" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-3" style="font-size:220px;font-weight:bold">6</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-5" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 859.94 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9-11-98">
<rect id="rect3333-2-1-7-5-3-4" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-0" style="font-size:220px;font-weight:bold">7</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-7" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 925.41 315.83)">
<flowRegion id="flowRegion3331-4-2-5-9-11-6">
<rect id="rect3333-2-1-7-5-3-3" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-61" style="font-size:220px;font-weight:bold">8</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-54" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 991.35 315.83)">
<flowRegion id="flowRegion3331-4-2-5-9-11-2">
<rect id="rect3333-2-1-7-5-3-0" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-9" style="font-size:220px;font-weight:bold">9</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-73" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1054.5 315.86)">
<flowRegion id="flowRegion3331-4-2-5-9-11-72">
<rect id="rect3333-2-1-7-5-3-6" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-01" style="font-size:220px;font-weight:bold">10</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-6" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1149.3 316.56)">
<flowRegion id="flowRegion3331-4-2-5-9-11-5">
<rect id="rect3333-2-1-7-5-3-7" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-5" style="font-size:220px;font-weight:bold">11</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-4" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 471.39 382.49)">
<flowRegion id="flowRegion3331-4-2-5-9-11-1">
<rect id="rect3333-2-1-7-5-3-2" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-00" style="font-size:220px;font-weight:bold">12</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-1" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 554.35 382.19)">
<flowRegion id="flowRegion3331-4-2-5-9-11-46">
<rect id="rect3333-2-1-7-5-3-07" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-1" style="font-size:220px;font-weight:bold">13</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-7-7" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 637.66 450.97)">
<flowRegion id="flowRegion3331-4-2-5-9-4-7">
<rect id="rect3333-2-1-7-5-27-7" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-7-7" style="font-size:220px;font-weight:bold">40</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-9-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 720.62 450.56)">
<flowRegion id="flowRegion3331-4-2-5-9-3-3">
<rect id="rect3333-2-1-7-5-1-5" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-9-9" style="font-size:220px;font-weight:bold">50</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-8-9" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 803.58 450.67)">
<flowRegion id="flowRegion3331-4-2-5-9-6-8">
<rect id="rect3333-2-1-7-5-5-1" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-0-8" style="font-size:220px;font-weight:bold">60</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-2-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 886.54 451.08)">
<flowRegion id="flowRegion3331-4-2-5-9-8-6">
<rect id="rect3333-2-1-7-5-6-6" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-02-0" style="font-size:220px;font-weight:bold">70</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-4-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 969.5 450.44)">
<flowRegion id="flowRegion3331-4-2-5-9-86-8">
<rect id="rect3333-2-1-7-5-50-0" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-90-1" style="font-size:220px;font-weight:bold">80</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-0-2" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1052.5 450.49)">
<flowRegion id="flowRegion3331-4-2-5-9-61-5">
<rect id="rect3333-2-1-7-5-38-0" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-93-9" style="font-size:220px;font-weight:bold">90</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-44-4" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 1138.5 450.78)">
<flowRegion id="flowRegion3331-4-2-5-9-60-7">
<rect id="rect3333-2-1-7-5-66-8" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-1-3" style="font-size:220px;font-weight:bold"> 0</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-4-5" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 471.74 451.19)">
<flowRegion id="flowRegion3331-4-2-5-9-11-1-1">
<rect id="rect3333-2-1-7-5-3-2-2" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-00-0" style="font-size:220px;font-weight:bold">00</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-1-1" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 554.7 450.89)">
<flowRegion id="flowRegion3331-4-2-5-9-11-46-6">
<rect id="rect3333-2-1-7-5-3-07-4" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-8-1-0" style="font-size:220px;font-weight:bold">30</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-7-6" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 558.19 623.85)">
<flowRegion id="flowRegion3331-4-2-5-9-4-1">
<rect id="rect3333-2-1-7-5-27-8" y="-1200.4" width="374.07" x="-691.32" height="303.05"/>
</flowRegion>
<flowPara id="flowPara3611-7-9" style="font-size:300px;font-weight:bold">*</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-8-3" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 487.23 618.05)">
<flowRegion id="flowRegion3331-4-2-5-9-6-9">
<rect id="rect3333-2-1-7-5-5-8" y="-1200.4" width="288.84" x="-691.32" height="250.96"/>
</flowRegion>
<flowPara id="flowPara3611-0-80" style="font-size:220px;font-weight:bold">X</flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-4-9" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 466.81 522.55)">
<flowRegion id="flowRegion3331-4-2-5-9-11-1-6">
<rect id="rect3333-2-1-7-5-3-2-8" ry="0" height="298.31" width="255.7" y="-1205.2" x="-691.32"/>
</flowRegion>
<flowPara id="flowPara3611-8-00-3" style="font-size:300px;font-weight:bold"> - </flowPara>
</flowRoot>
<flowRoot id="flowRoot3329-1-2-8-7-34-1-4" xml:space="preserve" style="letter-spacing:0px;color:#000000;word-spacing:0px;line-height:125%;fill:#000000" transform="matrix(.25983 0 0 .25983 539.31 524.4)">
<flowRegion id="flowRegion3331-4-2-5-9-11-46-8">
<rect id="rect3333-2-1-7-5-3-07-49" y="-1200.4" width="303.05" x="-691.32" height="307.78"/>
</flowRegion>
<flowPara id="flowPara3611-8-1-9" style="font-size:300px;font-weight:bold">+</flowPara>
</flowRoot>
<metadata id="metadata241">
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/>
<dc:publisher>
<cc:Agent rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 31 KiB

24
less/rmss.less Normal file
View File

@ -0,0 +1,24 @@
// Actor Sheet
@import "./actor-sheet/actor-sheet-skillcat.less";
@import "./actor-sheet/actor-sheet.less";
@import "./actor-sheet/actor-sheet-skills.less";
@import "./actor-sheet/actor-sheet-money.less";
@import "./actor-sheet/actor-sheet-items.less";
@import "./actor-sheet/actor-sheet-weapons.less";
@import "./actor-sheet/actor-sheet-armor.less";
@import "./actor-sheet/actor-sheet-herbs.less";
@import "./actor-sheet/actor-sheet-spells.less";
@import "./actor-sheet/actor-sheet-resistances.less";
//Skill Category Sheet
@import "./skillcat-sheet/skillcat-sheet.less";
@import "./skillcat-sheet/applicable-stats-grid.less";
//Apps
@import "./tools/dice-roller.less";
// Generics
@import "./item-sheet.less";

View File

@ -0,0 +1,19 @@
.applicable-stats-grid-container {
display: grid;
grid-template-columns: [app-stat-1] 33% [app-stat-2] 33% [app-stat-3] 33%;
}
.applicable-stats-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: column;
justify-content: center;
}

View File

@ -0,0 +1,30 @@
//.skillcat-icons {
// display: flex;
// justify-content: space-around;
// flex-direction: row;
// align-items: center;
//}
.skillcat-name, .skill-name, .item-name, .spell-name, .equipable-name {
font-family: Signika, sans-serif;
font-size: 12px;
font-weight: bold;
text-align: center;
}
.skillcat-entry, .skill-entry, .item-entry, .spell-entry, .equipable-entry {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
}
.skillcat-headeritem, .skill-headeritem, .item-headeritem, .spell-headeritem, .equipable-headeritem {
text-align: center;
font-weight: bold;
}
.skillcat-controls, .skill-controls, .item-controls {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
}

View File

@ -0,0 +1,20 @@
.dice-roller-options {
display: flex;
flex-direction: column;
}
.dice-roller-item {
display: flex;
align-items: center;
margin:5px;
}
.dice-roller-item div {
flex: 1;
}
.roll-button-container {
display: flex;
flex-direction: column;
justify-content: flex-end;
}

60
module/config.js Normal file
View File

@ -0,0 +1,60 @@
export const rmss = {};
rmss.curreny_type = {
mp: "rmss.curreny_type.mp",
pp: "rmss.curreny_type.pp",
gp: "rmss.curreny_type.gp",
sp: "rmss.curreny_type.sp",
bp: "rmss.curreny_type.bp",
cp: "rmss.curreny_type.cp"
};
rmss.stats = {
agility: {
fullname: "Agility",
shortname: "Ag"
},
constitution: {
fullname: "Constitution",
shortname: "Co"
},
memory: {
fullname: "Memory",
shortname: "Me"
},
reasoning: {
fullname: "Reasoning",
shortname: "Re"
},
self_discipline: {
fullname: "Self Discipline",
shortname: "SD"
},
empathy: {
fullname: "Empathy",
shortname: "Em"
},
intuition: {
fullname: "Intuition",
shortname: "In"
},
presence: {
fullname: "Presence",
shortname: "Pr"
},
quickness: {
fullname: "Quickness",
shortname: "Qu"
},
strength: {
fullname: "Strength",
shortname: "St"
}
};
rmss.skill_designations = {
None: "None",
Occupational: "Occupational",
Everyman: "Everyman",
Restricted: "Restricted"
};

26
module/controls.js vendored Normal file
View File

@ -0,0 +1,26 @@
export function registerGetSceneControlButtonsHook() {
Hooks.on("getSceneControlButtons", getSceneControlButtons);
}
function getSceneControlButtons(controls) {
if (canvas == null) {
return;
}
controls.push({
name: "fvtt-rolemaster-frp",
title: "Rolemaster FRP System",
icon: "fas fa-r",
layer: "ControlsLayer",
tools: [
{
name: "rmmsdiceroller",
title: "Dice Roller",
icon: "fas fa-dice",
onClick: () => { return new game.rmss.applications.RMSSToolsDiceRoller().render(true); },
button: true
}
],
activeTool: "rmmsdiceroller"
});
}

300
module/documents/actor.js Normal file
View File

@ -0,0 +1,300 @@
export class RMSSActor extends Actor {
/** @override */
prepareData() {
// Prepare data for the actor. Calling the super version of this executes
// the following, in order: data reset (to clear active effects),
// prepareBaseData(), prepareEmbeddedDocuments() (including active effects),
// prepareDerivedData().
super.prepareData();
}
prepareDerivedData() {
const actorData = this;
const systemData = actorData.system;
const flags = actorData.flags.rmss || {};
// Make separate methods for each Actor type (character, npc, etc.) to keep
// things organized.
this._prepareCharacterData(actorData);
this._prepareNpcData(actorData);
}
/**
* Prepare Character specific data.
* @param {Actor} actorData The NPC Object to prepare data for
*/
_prepareCharacterData(actorData) {
if (actorData.type !== "character") return;
this.calculateBasicStatBonus(actorData);
// Calculate Stat Bonuses for the Actor
this.calculateStatBonuses(actorData);
// Calculate Resistance Rolls for the Actor
this.calculateResistanceRolls(actorData);
// Iterate through and apply Stat bonuses for Skill Category Items
this.calculateSkillCategoryStatBonuses();
// Iterate through and apply Skill Category Bonuses for Skill items
this.calculateSkillBonuses();
}
/**
* Prepare NPC specific data.
* @param {Actor} actorData The NPC Object to prepare data for
*/
_prepareNpcData(actorData) {
if (actorData.type !== "npc") return;
// Make modifications to data here. For example:
const data = actorData.data;
}
// This checks to see if you have a Rollable Table called "Basic Stat Bonus Table" and uses it to calculate the basic stat bonuses.
calculateBasicStatBonus(actorData) {
const systemData = actorData.system;
for (const table of game.tables) {
if (table.name === "Basic Stat Bonus Table") {
for (const result of table.results) {
if (actorData.system.stats.agility.temp >= Number(result.range[0]) && actorData.system.stats.agility.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.agility.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.constitution.temp >= Number(result.range[0]) && actorData.system.stats.constitution.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.constitution.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.memory.temp >= Number(result.range[0]) && actorData.system.stats.memory.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.memory.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.reasoning.temp >= Number(result.range[0]) && actorData.system.stats.reasoning.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.reasoning.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.self_discipline.temp >= Number(result.range[0]) && actorData.system.stats.self_discipline.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.self_discipline.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.empathy.temp >= Number(result.range[0]) && actorData.system.stats.empathy.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.empathy.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.intuition.temp >= Number(result.range[0]) && actorData.system.stats.intuition.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.intuition.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.presence.temp >= Number(result.range[0]) && actorData.system.stats.presence.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.presence.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.quickness.temp >= Number(result.range[0]) && actorData.system.stats.quickness.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.quickness.basic_bonus = parseInt(result.text, 10);
}
if (actorData.system.stats.strength.temp >= Number(result.range[0]) && actorData.system.stats.strength.basic_bonus <= Number(result.range[1])) {
actorData.system.stats.strength.basic_bonus = parseInt(result.text, 10);
}
}
}
}
}
// Tally each stat bonus and populate the total field.
calculateStatBonuses(actorData) {
const systemData = actorData.system;
actorData.system.stats.agility.stat_bonus = Number(systemData.stats.agility.racial_bonus)
+ Number(systemData.stats.agility.special_bonus)
+ Number(systemData.stats.agility.basic_bonus);
actorData.system.stats.constitution.stat_bonus = Number(systemData.stats.constitution.racial_bonus)
+ Number(systemData.stats.constitution.special_bonus)
+ Number(systemData.stats.constitution.basic_bonus);
actorData.system.stats.memory.stat_bonus = Number(systemData.stats.memory.racial_bonus)
+ Number(systemData.stats.memory.special_bonus)
+ Number(systemData.stats.memory.basic_bonus);
actorData.system.stats.reasoning.stat_bonus = Number(systemData.stats.reasoning.racial_bonus)
+ Number(systemData.stats.reasoning.special_bonus)
+ Number(systemData.stats.reasoning.basic_bonus);
actorData.system.stats.self_discipline.stat_bonus = Number(systemData.stats.self_discipline.racial_bonus)
+ Number(systemData.stats.self_discipline.special_bonus)
+ Number(systemData.stats.self_discipline.basic_bonus);
actorData.system.stats.empathy.stat_bonus = Number(systemData.stats.empathy.racial_bonus)
+ Number(systemData.stats.empathy.special_bonus)
+ Number(systemData.stats.empathy.basic_bonus);
actorData.system.stats.intuition.stat_bonus = Number(systemData.stats.intuition.racial_bonus)
+ Number(systemData.stats.intuition.special_bonus)
+ Number(systemData.stats.intuition.basic_bonus);
actorData.system.stats.presence.stat_bonus = Number(systemData.stats.presence.racial_bonus)
+ Number(systemData.stats.presence.special_bonus)
+ Number(systemData.stats.presence.basic_bonus);
actorData.system.stats.quickness.stat_bonus = Number(systemData.stats.quickness.racial_bonus)
+ Number(systemData.stats.quickness.special_bonus)
+ Number(systemData.stats.quickness.basic_bonus);
actorData.system.stats.strength.stat_bonus = Number(systemData.stats.strength.racial_bonus)
+ Number(systemData.stats.strength.special_bonus)
+ Number(systemData.stats.strength.basic_bonus);
}
// Calculate each Resistance Roll with the formula on the character sheet.
calculateResistanceRolls(actorData) {
const systemData = actorData.system;
actorData.system.resistance_rolls.essence.value = Number(systemData.stats.empathy.stat_bonus * 3);
actorData.system.resistance_rolls.channeling.value = Number(systemData.stats.intuition.stat_bonus * 3);
actorData.system.resistance_rolls.mentalism.value = Number(systemData.stats.presence.stat_bonus * 3);
actorData.system.resistance_rolls.fear.value = Number(systemData.stats.self_discipline.stat_bonus * 3);
actorData.system.resistance_rolls.poison_disease.value = Number(systemData.stats.constitution.stat_bonus * 3);
actorData.system.resistance_rolls.chann_ess.value = Number(systemData.stats.intuition.stat_bonus)
+ Number(systemData.stats.empathy.stat_bonus);
actorData.system.resistance_rolls.chann_ment.value = Number(systemData.stats.intuition.stat_bonus)
+ Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.ess_ment.value = Number(systemData.stats.empathy.stat_bonus)
+ Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.arcane.value = Number(systemData.stats.empathy.stat_bonus)
+ Number(systemData.stats.intuition.stat_bonus)
+ Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.essence.total = actorData.system.resistance_rolls.essence.value
+ actorData.system.resistance_rolls.essence.race_mod;
actorData.system.resistance_rolls.channeling.total = actorData.system.resistance_rolls.channeling.value
+ actorData.system.resistance_rolls.channeling.race_mod;
actorData.system.resistance_rolls.mentalism.total = actorData.system.resistance_rolls.mentalism.value
+ actorData.system.resistance_rolls.mentalism.race_mod;
actorData.system.resistance_rolls.fear.total = actorData.system.resistance_rolls.fear.value
+ actorData.system.resistance_rolls.fear.race_mod;
actorData.system.resistance_rolls.poison_disease.total = actorData.system.resistance_rolls.poison_disease.value
+ actorData.system.resistance_rolls.poison_disease.race_mod;
actorData.system.resistance_rolls.chann_ess.total = actorData.system.resistance_rolls.chann_ess.value
+ actorData.system.resistance_rolls.chann_ess.race_mod;
actorData.system.resistance_rolls.chann_ment.total = actorData.system.resistance_rolls.chann_ment.value
+ actorData.system.resistance_rolls.chann_ment.race_mod;
actorData.system.resistance_rolls.ess_ment.total = actorData.system.resistance_rolls.ess_ment.value
+ actorData.system.resistance_rolls.ess_ment.race_mod;
actorData.system.resistance_rolls.arcane.total = actorData.system.resistance_rolls.arcane.value
+ actorData.system.resistance_rolls.arcane.race_mod;
}
calculateSkillBonuses() {
for (const item of this.items) {
if (item.type === "skill") {
console.log(`rmss | actor.js | Calculating skill bonus for Skill: ${item.name}`);
console.log(`rmss | actor.js | Updating Skill Category Bonus for Skill: ${item.name}`);
item.calculateSelectedSkillCategoryBonus(item);
console.log(`rmss | actor.js | Updating Skill Total Bonus for Skill: ${item.name}`);
item.calculateSkillTotalBonus(item);
}
}
}
// Tallys the bonus for each Stat that is applicable to the Skill Category and then updates the total
calculateSkillCategoryStatBonuses() {
for (const item of this.items) {
if (item.type === "skill_category") {
console.log(`rmss | actor.js | Calculating Skill Category Stat Bonuses for: ${item.name}`);
// Get all the applicable stats for this skill category
let app_stat_1 = item.system.app_stat_1;
let app_stat_2 = item.system.app_stat_2;
let app_stat_3 = item.system.app_stat_3;
// If the first one is None we don't need to do anything further
if (app_stat_1 === "None") {
continue;
}
else
{
let applicable_stat_bonus = 0;
let app_stat_1_found = false;
let app_stat_2_found = false;
let app_stat_3_found = false;
// Iterate through the applicable stats and find their full names
for (const stat in CONFIG.rmss.stats) {
// If the configured App Stat matches the one of the stats in config
if (app_stat_1 === CONFIG.rmss.stats[stat].shortname) {
app_stat_1_found = true;
// Get the Stat Bonus
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
}
if (app_stat_2 === CONFIG.rmss.stats[stat].shortname) {
app_stat_2_found = true;
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
}
if (app_stat_3 === CONFIG.rmss.stats[stat].shortname) {
app_stat_3_found = true;
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
}
}
if (app_stat_1_found === true && app_stat_2_found === true && app_stat_3_found === true) {
// Apply the update if we found stat bonuses for every applicable stat
item.system.stat_bonus = applicable_stat_bonus;
// Update the total in the Item
item.calculateSkillCategoryTotalBonus(item);
}
else if (app_stat_1_found === true && app_stat_2_found === true && app_stat_3_found === false) {
// Apply the update if we found stat bonuses for the first two applicable stats
item.system.stat_bonus = applicable_stat_bonus;
// Update the total in the Item
item.calculateSkillCategoryTotalBonus(item);
}
else if (app_stat_1_found === true && app_stat_2_found === false && app_stat_3_found === false) {
// Apply the update if we found stat bonuses for the first applicable stat
item.system.stat_bonus = applicable_stat_bonus;
// Update the total in the Item
item.calculateSkillCategoryTotalBonus(item);
}
}
}
}
}
// For each skill category return an object in this format.
// {{ _id: "skill category name"}}
// This is the format that the select helper on the skill sheet needs
getOwnedItemsByType(item_type) {
let ownedItems = {None: "None"};
console.log(`rmss | actor.js | Getting owned ${item_type} for: ${this.name}`);
for (const item of this.items) {
if (item.type === item_type) {
ownedItems[item._id] = item.name;
}
}
return (ownedItems);
}
}

120
module/documents/item.js Normal file
View File

@ -0,0 +1,120 @@
export class RMSSItem extends Item {
/** @override */
prepareData() {
// Prepare data for the item. Calling the super version of this executes
// the following, in order: data reset (to clear active effects),
// prepareBaseData(), prepareEmbeddedDocuments() (including active effects),
// prepareDerivedData().
console.log(`rmss | item.js | prepareData for: ${this.name}`);
super.prepareData();
}
// Set the icon images for newly created images.
async _preCreate(data, options, userId) {
await super._preCreate(data, options, userId);
// Do not set on copied items if they have a custom Icon.
if (!data.name.includes("(Copy)"))
{
if (this.type === "armor") {
await this.updateSource({img: "systems/fvtt-rolemaster-frp/assets/default/armor.svg"});
}
else if (this.type === "weapon") {
await this.updateSource({img: "systems/fvtt-rolemaster-frp/assets/default/weapon.svg"});
}
else if (this.type === "skill") {
await this.updateSource({img: "systems/fvtt-rolemaster-frp/assets/default/skill.svg"});
}
else if (this.type === "skill_category") {
await this.updateSource({img: "systems/fvtt-rolemaster-frp/assets/default/skill_category.svg"});
}
else if (this.type === "spell") {
await this.updateSource({img: "systems/fvtt-rolemaster-frp/assets/default/spell.svg"});
}
else if (this.type === "herb_or_poison") {
await this.updateSource({img: "systems/fvtt-rolemaster-frp/assets/default/herb_or_poison.svg"});
}
else if (this.type === "transport") {
await this.updateSource({img: "systems/fvtt-rolemaster-frp/assets/default/transport.svg"});
}
}
}
prepareDerivedData() {
const itemData = this;
const systemData = itemData.system;
const flags = itemData.flags.rmss || {};
// Make separate methods for each item type to keep things organized.
if (itemData.type === "skill") {
this._prepareSkillCategoryData(itemData);
}
if (itemData.type === "skill") {
this._prepareSkillData(itemData);
}
}
_prepareSkillCategoryData(itemData) {
if (itemData.type !== "skill_category") return;
console.log(`rmss | item.js | Preparing Skill Category Data for: ${itemData.name}`);
// Calculate Skill Category Total Bonus
this.calculateSkillCategoryTotalBonus(itemData);
}
_prepareSkillData(itemData) {
if (itemData.type !== "skill") return;
console.log(`rmss | item.js | Preparing Skill Data for: ${itemData.name}`);
// Make modifications to data here. For example:
// const systemData = itemData.system;
// Calculate Skill Category Bonus
this.calculateSelectedSkillCategoryBonus(itemData);
// Calculate Skill Total Bonus
this.calculateSkillTotalBonus(itemData);
}
calculateSkillCategoryTotalBonus(itemData) {
if (this.type === "skill_category") {
console.log(`rmss | item.js | Calculating Skill Category Total Bonus for: ${itemData.name}`);
const systemData = itemData.system;
itemData.system.total_bonus = Number(systemData.rank_bonus)
+ Number(systemData.stat_bonus)
+ Number(systemData.prof_bonus)
+ Number(systemData.special_bonus_1)
+ Number(systemData.special_bonus_2);
}
}
calculateSkillTotalBonus(itemData) {
if (this.type === "skill") {
const systemData = itemData.system;
console.log(`rmss | item.js | Calculating Skill Total Bonus for: ${itemData.name}`);
itemData.system.total_bonus = Number(systemData.rank_bonus)
+ Number(systemData.category_bonus)
+ Number(systemData.item_bonus)
+ Number(systemData.special_bonus_1)
+ Number(systemData.special_bonus_2);
}
}
calculateSelectedSkillCategoryBonus(itemData) {
if (this.isEmbedded === null) {
console.log(`rmss | item.js | Skill ${this.name} has no owner. Not calculating Skill Category bonus`);
}
else
{
const items = this.parent?.items;
console.log(`rmss | item.js | Skill ${this.name} has owner, calculating skill category bonus.`);
if (items) {
for (const item of items) {
if (item.type === "skill_category" && item._id === itemData.system.category) {
console.log(`rmss | item.js | Calculating Skill Category bonus for skill: ${this.name}`);
this.system.category_bonus = item.system.total_bonus;
}
}
}
}
}
}

View File

@ -0,0 +1,394 @@
export default class RMSSPlayerSheet extends ActorSheet {
// Override Default Options, Set CSS Classes, Set Default Sheet, Set up Sheet Tabs
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 860,
height: 780,
template: "systems/fvtt-rolemaster-frp/templates/sheets/actors/rmss-character-sheet.html",
classes: ["rmss", "sheet", "actor"],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "features" }]
});
}
// Make the data available to the sheet template
async getData() {
const context = super.getData();
// Use a safe clone of the actor data for further operations.
const actorData = this.actor.toObject(false);
let enrichedDescription = await TextEditor.enrichHTML(this.actor.system.description, {async: true});
// Add the actor's data to context.data for easier access, as well as flags.
context.system = actorData.system;
context.flags = actorData.flags;
context.enrichedDescription = enrichedDescription;
// Prepare character data and items.
if (actorData.type === "character") {
this._prepareItems(context);
this._prepareCharacterData(context);
}
// Prepare NPC data and items.
if (actorData.type === "npc") {
this._prepareItems(context);
}
return context;
}
// Override this method to check for duplicates when things are dragged to the sheet
// We don't want duplicate skills and skill categories.
async _onDropItem(event, data) {
// Reconstruct the item from the event
const newitem = await Item.implementation.fromDropData(data);
const itemData = newitem.toObject();
// To Do: Seperate Skills and Skill Categories. Increment Counts for items
if (itemData.type === "skill_category") {
// Get the already owned Items from the actor and push into an array
const owneditems = this.object.getOwnedItemsByType("skill_category");
let ownedskillcatlist = Object.values(owneditems);
// Check if the dragged item is not in the array and not owned
if (!ownedskillcatlist.includes(itemData.name)) {
console.log("Not Owned!");
super._onDropItem(event, data);
}
} else if ( itemData.type === "skill") {
// Get the already owned Items from the actor and push into an array
const owneditems = this.object.getOwnedItemsByType("skill");
let ownedskilllist = Object.values(owneditems);
// Check if the dragged item is not in the array and not owned
if (!ownedskilllist.includes(itemData.name)) {
console.log("Not Owned!");
super._onDropItem(event, data);
}
}
else {
super._onDropItem(event, data);
}
}
_prepareCharacterData(context) {
// Calculate Power Point Exhaustion
let powerpointPercentage = (Number(context.system.attributes.power_points.current) / Number(context.system.attributes.power_points.max)) * 100;
console.log(true);
switch (true) {
case (powerpointPercentage < 25):
context.system.attributes.power_points.modifier = "PP Exhaustion Penalty: -30 ";
break;
case (powerpointPercentage < 50):
context.system.attributes.power_points.modifier = "PP Exhaustion Penalty: -20 ";
break;
case (powerpointPercentage < 75):
console.log("Less than 75");
context.system.attributes.power_points.modifier = "PP Exhaustion Penalty: -10 ";
break;
default:
console.log("Setting Default");
context.system.attributes.power_points.modifier = "PP Exhaustion Penalty: 0 ";
}
// Calculate Exhaustion Point Penalty
let exhaustionPercentage = (Number(context.system.attributes.exhaustion_points.current) / Number(context.system.attributes.exhaustion_points.max)) * 100;
console.log(true);
switch (true) {
case (exhaustionPercentage < 1):
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -100 ";
break;
case (exhaustionPercentage < 10):
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -60 ";
break;
case (exhaustionPercentage < 25):
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -30 ";
break;
case (exhaustionPercentage < 50):
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -15 ";
break;
case (exhaustionPercentage < 75):
console.log("Less than 75");
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: -5 ";
break;
default:
console.log("Setting Default");
context.system.attributes.exhaustion_points.modifier = "Exhaustion Penalty: 0 ";
}
}
_prepareItems(context) {
console.log(`rmss | rmss_player_sheet.js | Preparing items for: ${this.name}`);
// Initialize containers.
const gear = [];
const playerskill= [];
const skillcat = [];
const weapons = [];
const armor = [];
const herbs = [];
const spells = [];
const equipables = [];
// Iterate through items, allocating to containers
for (let i of context.items) {
i.img = i.img || DEFAULT_TOKEN;
// Append to gear.
if (i.type === "item") {
gear.push(i);
}
else if (i.type === "weapon") {
weapons.push(i);
}
else if (i.type === "herb_or_poison") {
herbs.push(i);
}
// Append to skill categories.
else if (i.type === "skill_category") {
skillcat.push(i);
}
// Append to playerskill
else if (i.type === "skill") {
playerskill.push(i);
}
else if (i.type === "armor") {
armor.push(i);
}
else if (i.type === "spell") {
spells.push(i);
}
}
// Sort Skill/Skillcat Arrays
skillcat.sort(function(a, b) {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
playerskill.sort(function(a, b) {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
// Assign and return
context.gear = gear;
context.skillcat = skillcat;
context.playerskill = playerskill;
context.weapons = weapons;
context.armor = armor;
context.herbs = herbs;
context.spells = spells;
}
async renderCharacterSettings(data) {
console.log(data);
const configSheet = await renderTemplate("systems/fvtt-rolemaster-frp/templates/sheets/actors/dialogs/app_skill_category_importer.html", data);
return (configSheet);
}
activateListeners(html) {
super.activateListeners(html);
// Render the item sheet for viewing/editing prior to the editable check.
html.find(".item-edit").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
item.sheet.render(true);
});
html.find(".item-roll").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
new game.rmss.applications.RMSSToolsDiceRoller(item.name, item.system.total_bonus).render(true);
});
// -------------------------------------------------------------
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
// Add Item
html.find(".item-create").click(this._onItemCreate.bind(this));
// Delete Item
html.find(".item-delete").click(ev => {
console.log(ev.currentTarget.getAttribute("data-item-id"));
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
item.delete();
});
// Show Skill Category Importer
html.find(".import-skillcats").click(async ev => {
let selectOptions = {};
for (const pack of game.packs) {
selectOptions[pack.metadata.id] = pack.metadata.label;
}
new game.rmss.applications.RMSSToolsSCImporter(selectOptions, this.actor).render(true);
});
// Check/Uncheck Favorite Skill
html.find(".skill-favorite").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log(`Before change: ${item.system.favorite}`);
if (item.system.favorite === true) {
console.log("Setting False");
item.update({system: {favorite: false}});
} else {
console.log("Setting True");
item.update({system: {favorite: true}});
}
console.log(`After change: ${item.system.favorite}`);
});
// Check/Uncheck Favorite Spell
html.find(".spell-favorite").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log(`Before change: ${item.system.favorite}`);
if (item.system.favorite === true) {
console.log("Setting False");
item.update({system: {favorite: false}});
} else {
console.log("Setting True");
item.update({system: {favorite: true}});
}
console.log(`After change: ${item.system.favorite}`);
});
// Equip/Unequip Weapon/Armor
html.find(".equippable").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log(`Before change: ${item.system.equipped}`);
if (item.system.equipped === true) {
console.log("Setting False");
item.update({system: {equipped: false}});
} else {
console.log("Setting True");
item.update({system: {equipped: true}});
}
console.log(`After change: ${item.system.equipped}`);
});
// Wear/Remove Item
html.find(".wearable").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log(item);
console.log(`Before change: ${item.system.equipped}`);
if (item.system.worn === true) {
console.log("Setting False");
item.update({system: {worn: false}});
} else {
console.log("Setting True");
item.update({system: {worn: true}});
}
console.log(`After change: ${item.system.equipped}`);
});
// Change New Ranks value when clicked in player sheet. From 0-3.
html.find(".skill-newrank").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log("Firing in the Player Sheet");
console.log(ev.currentTarget.getAttribute("value"));
console.log(ev.currentTarget.getAttribute("data-item-id"));
switch (ev.currentTarget.getAttribute("value")) {
case "0":
console.log("Skill NewRanks is 0 setting to 1");
item.update({system: {new_ranks: { value: 1 }}});
break;
case "1":
console.log("Skill NewRanks is 1 setting to 2");
item.update({system: {new_ranks: { value: 2 }}});
break;
case "2":
console.log("Skill NewRanks is 2 setting to 3");
item.update({system: {new_ranks: { value: 3 }}});
break;
case "3":
console.log("Skill NewRanks is 3 setting to 0");
item.update({system: {new_ranks: { value: 0 }}});
break;
}
});
// Change New Ranks value when clicked in player sheet. From 0-3.
html.find(".skillcategory-newrank").click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
console.log("Firing in the Player Sheet");
console.log(ev.currentTarget.getAttribute("value"));
console.log(ev.currentTarget.getAttribute("data-item-id"));
switch (ev.currentTarget.getAttribute("value")) {
case "0":
console.log("Skill Category NewRanks is 0 setting to 1");
item.update({system: {new_ranks: { value: 1 }}});
break;
case "1":
console.log("Skill Category NewRanks is 1 setting to 2");
item.update({system: {new_ranks: { value: 2 }}});
break;
case "2":
console.log("Skill Category NewRanks is 2 setting to 3");
item.update({system: {new_ranks: { value: 3 }}});
break;
case "3":
console.log("Skill Category NewRanks is 3 setting to 0");
item.update({system: {new_ranks: { value: 0 }}});
break;
}
});
}
async _onItemCreate(event) {
event.preventDefault();
const header = event.currentTarget;
// Get the type of item to create.
const type = header.dataset.type;
// Grab any data associated with this control.
const data = duplicate(header.dataset);
// Initialize a default name.
const name = `New ${type.capitalize()}`;
// Prepare the item object.
const itemData = {
name: name,
type: type,
data: data
};
// Remove the type from the dataset since it's in the itemData.type prop.
delete itemData.data.type;
// Finally, create the item!
return await Item.create(itemData, {parent: this.actor});
}
}

View File

@ -0,0 +1,55 @@
export default class RMSSActorSheetConfig extends FormApplication {
constructor(selectOptions, character) {
super();
this.selectOptions = selectOptions;
this.character = character;
}
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["form"],
popOut: true,
template: "systems/fvtt-rolemaster-frp/templates/sheets/actors/apps/actor-settings.html"
});
}
getData() {
// Send data to the template
return {
selectOptions: this.selectOptions
};
}
activateListeners(html) {
super.activateListeners(html);
}
async _updateObject(event, formData) {
console.log("Deleting Old Skill Categories.");
for (const item of this.character.items) {
if (item.type === "skill_category") {
item.delete();
}
}
const pack = game.packs.get(formData.selectOptions);
const skillCategoryData = await pack.getIndex();
console.log("Importing New Skill Categories.");
for (const sc of skillCategoryData) {
const newitem = await pack.getDocument(sc._id);
let newDocuments = [];
if (newitem.type === "skill_category") {
console.log(newitem);
newDocuments.push(newitem);
}
if (newDocuments.length > 0) {
await Item.createDocuments(newDocuments, {parent: this.character});
}
}
}
}

View File

@ -0,0 +1,85 @@
import {
roll_one_to_onehundred,
roll_low_open_ended,
roll_high_open_ended,
roll_open_ended
} from "./rmss_dice_roller_rolls.js";
import {
getOpenEndedRollModifier,
processOpenEndedSixtySixRoll,
processOpenEndedRoll,
processHighOpenEndedRoll,
processLowOpenEndedRoll
} from "./rmss_dice_roller_processing.js";
export default class RMSSToolsDiceRoller extends FormApplication {
constructor(itemName, characterBonus) {
super();
this.itemName = itemName;
this.characterBonus = characterBonus;
this.rollType = [
{value: "one_to_onehundred", text: "1-100", selected: false},
{value: "open_ended", text: "Open-Ended", selected: true},
{value: "high_open_ended", text: "High Open-Ended", selected: false},
{value: "low_open_ended", text: "Low Open-Ended", selected: false}
];
}
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["form"],
title: "Rolemaster Dice Roller",
popOut: true,
width: 380,
height: 210,
template: "systems/fvtt-rolemaster-frp/templates/sheets/apps/app_dice_roller.html"
});
}
getData() {
// Send data to the template
return {
itemName: this.itemName,
characterBonus: this.characterBonus,
selectOptions: this.rollType,
};
}
activateListeners(html) {
super.activateListeners(html);
}
async _updateObject(event, formData) {
console.log("Rolling Dice");
console.log(formData);
console.log(event);
switch (formData.rollType) {
case "one_to_onehundred":
this.roll_one_to_onehundred();
break;
case "open_ended":
this.roll_open_ended();
break;
case "high_open_ended":
this.roll_high_open_ended();
break;
case "low_open_ended":
this.roll_low_open_ended();
break;
}
}
}
RMSSToolsDiceRoller.prototype.roll_one_to_onehundred = roll_one_to_onehundred;
RMSSToolsDiceRoller.prototype.roll_low_open_ended = roll_low_open_ended;
RMSSToolsDiceRoller.prototype.roll_high_open_ended = roll_high_open_ended;
RMSSToolsDiceRoller.prototype.roll_open_ended = roll_open_ended;
RMSSToolsDiceRoller.prototype.getOpenEndedRollModifier =
getOpenEndedRollModifier;
RMSSToolsDiceRoller.prototype.processOpenEndedSixtySixRoll =
processOpenEndedSixtySixRoll;
RMSSToolsDiceRoller.prototype.processOpenEndedRoll = processOpenEndedRoll;
RMSSToolsDiceRoller.prototype.processHighOpenEndedRoll =
processHighOpenEndedRoll;
RMSSToolsDiceRoller.prototype.processLowOpenEndedRoll = processLowOpenEndedRoll;

View File

@ -0,0 +1,131 @@
export async function getOpenEndedRollModifier() {
return await new Roll("1d100x>95").roll();
}
export function processOpenEndedSixtySixRoll(baseroll, rolltype) {
// Log the Roll to Chat
let chatOptions = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
rolls: [baseroll],
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode"),
content: "You rolled a 66!",
};
ChatMessage.create(chatOptions);
}
export function processOpenEndedRoll(baseroll, rolltype) {
// Define the Chat Message Template
let chatTemplate = "systems/fvtt-rolemaster-frp/templates/chat/chat_dice_roll.html";
// Pass the Data through to be used in the Chat Message
let chatData = {
baseroll: baseroll,
total: baseroll.result,
highopen: false,
lowopen: false,
};
// Render the Rolls to the Chat Window
renderTemplate(chatTemplate, chatData).then((html) => {
let chatOptions = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
rolls: [baseroll],
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode"),
content: html,
};
ChatMessage.create(chatOptions);
});
}
export async function processHighOpenEndedRoll(baseroll, rolltype) {
// Get the Base Roll followed by the High Open Ended Roll
let originalRoll = baseroll;
let openendedRoll = await this.getOpenEndedRollModifier();
// Create a rolls array for Dice So Nice integration.
let rolls = [originalRoll, openendedRoll];
// Create an Array to hold the High Open Ended Roll Results and set the total to base roll
let openendedResults = [];
let total = Number(originalRoll.result);
// Each time the High Open Ended Roll is triggered add the result to an array and add it to the total.
for (const rollResult of openendedRoll.dice[0].results) {
openendedResults.push(rollResult.result);
total = total + Number(rollResult.result);
}
// Define the Chat Message Template
let chatTemplate = "systems/fvtt-rolemaster-frp/templates/chat/chat_dice_roll.html";
// Pass the Data through to be used in the Chat Message
let chatData = {
baseroll: baseroll,
opeendedresults: [openendedResults],
highopen: true,
lowopen: false,
total: total,
};
// Render the Rolls to the Chat Window
renderTemplate(chatTemplate, chatData).then((html) => {
let chatOptions = {
style: CONST.CHAT_MESSAGE_STYLES.ROLL,
rolls: rolls,
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode"),
content: html,
};
ChatMessage.create(chatOptions);
});
}
export async function processLowOpenEndedRoll(baseroll, rolltype) {
// Get the Base Roll followed by the Low Open Ended Roll
let originalRoll = baseroll;
let openendedRoll = await this.getOpenEndedRollModifier();
// Create a rolls array for Dice So Nice integration.
let rolls = [originalRoll, openendedRoll];
// Create an Array to hold the Low Open Ended Roll Results and set the total to base roll
let openendedResults = [];
let total = Number(originalRoll.result);
// Each time the Low Open Ended Roll is triggered add the result to an array and subtract it from the total.
for (const rollResult of openendedRoll.dice[0].results) {
openendedResults.push(rollResult.result);
total = total - Number(rollResult.result);
}
// Define the Chat Message Template
let chatTemplate = "systems/fvtt-rolemaster-frp/templates/chat/chat_dice_roll.html";
// Pass the Data through to be used in the Chat Message
let chatData = {
baseroll: baseroll,
rolls: rolls,
opeendedresults: [openendedResults],
highopen: false,
lowopen: true,
total: total,
};
// Render the Rolls to the Chat Window
renderTemplate(chatTemplate, chatData).then((html) => {
let chatOptions = {
style: CONST.CHAT_MESSAGE_STYLES.ROLL,
rolls: rolls,
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode"),
content: html,
};
ChatMessage.create(chatOptions);
});
}

View File

@ -0,0 +1,71 @@
export async function roll_one_to_onehundred() {
// Construct the Roll instance
let baseroll = await new Roll("1d100 + @characterBonus", {characterBonus: this.characterBonus}).roll({async: true});
let rolltype = "Roll Type: 1-100";
// Log the Roll to Chat
let chatOptions = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
rolls: [baseroll],
flavor: rolltype,
rollMode: game.settings.get("core", "rollMode")
};
ChatMessage.create(chatOptions);
this.close();
};
export async function roll_low_open_ended() {
// Construct the Roll instance
let baseroll = await new Roll("1d100").roll({async: true});
console.log(baseroll.result);
let rolltype = "Roll Type: Low Open-Ended";
switch (true) {
case (baseroll.result < 6):
this.processLowOpenEndedRoll(baseroll, rolltype);
break;
case (baseroll.result === 66):
this.processOpenEndedSixtySixRoll(baseroll, rolltype);
break;
default:
this.processOpenEndedRoll(baseroll, rolltype);
}
}
export async function roll_high_open_ended() {
// Construct the Roll instance
let baseroll = await new Roll("1d100").roll({async: true});
console.log(baseroll.result);
let rolltype = "Roll Type: High Open-Ended";
switch (true) {
case (baseroll.result === 66):
this.processOpenEndedSixtySixRoll(baseroll, rolltype);
break;
case (baseroll.result > 95):
this.processHighOpenEndedRoll(baseroll, rolltype);
break;
default:
this.processOpenEndedRoll(baseroll, rolltype);
}
}
export async function roll_open_ended() {
// Construct the Roll instance
let baseroll = await new Roll("1d100").roll({async: true});
console.log(baseroll.result);
let rolltype = "Roll Type: Open-Ended";
switch (true) {
case (baseroll.result < 6):
this.processLowOpenEndedRoll(baseroll, rolltype);
break;
case (baseroll.result === 66):
this.processOpenEndedSixtySixRoll(baseroll, rolltype);
break;
case (baseroll.result > 95):
this.processHighOpenEndedRoll(baseroll, rolltype);
break;
default:
this.processOpenEndedRoll(baseroll, rolltype);
}
}

View File

@ -0,0 +1,56 @@
export default class RMSSToolsSCImporter extends FormApplication {
constructor(selectOptions, character) {
super();
this.selectOptions = selectOptions;
this.character = character;
}
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["form"],
popOut: true,
title: "Import Skill Categories",
template: "systems/fvtt-rolemaster-frp/templates/sheets/apps/app_skill_category_importer.html"
});
}
getData() {
// Send data to the template
return {
selectOptions: this.selectOptions
};
}
activateListeners(html) {
super.activateListeners(html);
}
async _updateObject(event, formData) {
console.log("Deleting Old Skill Categories.");
for (const item of this.character.items) {
if (item.type === "skill_category") {
item.delete();
}
}
const pack = game.packs.get(formData.selectOptions);
const skillCategoryData = await pack.getIndex();
console.log("Importing New Skill Categories.");
for (const sc of skillCategoryData) {
const newitem = await pack.getDocument(sc._id);
let newDocuments = [];
if (newitem.type === "skill_category") {
console.log(newitem);
newDocuments.push(newitem);
}
if (newDocuments.length > 0) {
await Item.createDocuments(newDocuments, {parent: this.character});
}
}
}
}

View File

@ -0,0 +1,36 @@
// Our Item Sheet extends the default
export default class RMSSArmorSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-armor-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-armor-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -0,0 +1,36 @@
// Our Item Sheet extends the default
export default class RMSSHerbAndPoisonSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-herb-or-poison-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-herb-or-poison-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -0,0 +1,36 @@
// Our Item Sheet extends the default
export default class RMSSItemSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-item-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-item-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -0,0 +1,36 @@
// Our Item Sheet extends the default
export default class RMSSTransportSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-transport-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-transport-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -0,0 +1,36 @@
// Our Item Sheet extends the default
export default class RMSSWeaponSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-weapon-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return "systems/fvtt-rolemaster-frp/templates/sheets/items/rmss-weapon-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -0,0 +1,133 @@
// Our Item Sheet extends the default
export default class RMSSSkillCategorySheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 580,
height: 440,
template: "systems/fvtt-rolemaster-frp/templates/sheets/skills/rmss-skill-category-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return "systems/fvtt-rolemaster-frp/templates/sheets/skills/rmss-skill-category-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const context = await super.getData();
// Get a list of stats that can be used as applicable stats
let applicableStatList = this.prepareApplicableStatNames(CONFIG);
// Get the currently selected value for all three applicable stats
let firstApplicableStat = this.prepareApplicableSelectedStat("app_stat_1");
let secondApplicableStat = this.prepareApplicableSelectedStat("app_stat_2");
let thirdApplicableStat = this.prepareApplicableSelectedStat("app_stat_3");
// Build and apply the display string for Applicable Stats
let applicableStatText =
this.buildApplicableStatsText(firstApplicableStat, secondApplicableStat, thirdApplicableStat);
context.item.system.applicable_stats = applicableStatText;
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: context.item,
system: context.item.system,
config: CONFIG.rmss,
applicable_stat_list: applicableStatList,
applicable_stat_1_selected: firstApplicableStat,
applicable_stat_2_selected: secondApplicableStat,
applicable_stat_3_selected: thirdApplicableStat,
enrichedDescription: enrichedDescription
};
return sheetData;
}
async _setApplicableStat(item, ev) {
// Build a JSON Object from the selected tag value and selected name (item data attribute key)
let updateKey = ev.currentTarget.getAttribute("name");
let updateData = ev.target.value;
// Update Item Data
await item.update({[updateKey]: updateData});
}
// Each Skill Category can have up to three Applicable Stats that apply to it. We need to get a list of
// the Stat Shortnames from Config so the user can select which stats are applicable to this Skill Category
prepareApplicableStatNames(config) {
let applicableStatList = {None: "None"};
for (const item in config.rmss.stats) {
applicableStatList[config.rmss.stats[item].shortname] = config.rmss.stats[item].shortname;
}
return applicableStatList;
}
// Get the values for the currently selected Applicable Stat so we can display it on the Skill Category Sheet
// If nothing is selected return an empty string.
prepareApplicableSelectedStat(appStat) {
let applicableStatSelected = "";
applicableStatSelected = this.item.system[appStat];
return applicableStatSelected;
}
// The character sheet has an information field that displays the applicable stats in the following format
// St/Ag/St. This method checks the current applicable stats and builds that field so
// it can be displayed to the user.
buildApplicableStatsText(firstAppStat, secondAppStat, thirdAppStat) {
if (firstAppStat === "None") {
return ("None");
}
else if (firstAppStat !== "None" && secondAppStat === "None") {
return (firstAppStat);
}
else if (firstAppStat !== "None" && secondAppStat !== "None" && thirdAppStat === "None" ) {
return (`${firstAppStat}/${secondAppStat}`);
}
else if (firstAppStat !== "None" && secondAppStat !== "None" && thirdAppStat !== "None" ) {
return (`${firstAppStat}/${secondAppStat}/${thirdAppStat}`);
}
else {
return ("None");
}
}
activateListeners(html) {
super.activateListeners(html);
// -------------------------------------------------------------
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
// Every time the user selects one of the Applicable Stat dropdowns
// fire an event to change the value in the Skill Category
html.find(".stat-selector").change(ev => {
this._setApplicableStat(this.item, ev);
});
// Catch the event when the user clicks one of the New Ranks Checkboxes in a Skill Category.
// It will increment by one or wrap back to zero on a value of three
html.find(".skillcategorysheet-newrank").click(ev => {
switch (ev.currentTarget.getAttribute("value")) {
case "0":
this.object.update({system: {new_ranks: { value: 1 }}});
break;
case "1":
this.object.update({system: {new_ranks: { value: 2 }}});
break;
case "2":
this.object.update({system: {new_ranks: { value: 3 }}});
break;
case "3":
this.object.update({system: {new_ranks: { value: 0 }}});
break;
}
});
}
}

View File

@ -0,0 +1,115 @@
// Our Item Sheet extends the default
export default class RMSSSkillSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/fvtt-rolemaster-frp/templates/sheets/skills/rmss-skill-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return "systems/fvtt-rolemaster-frp/templates/sheets/skills/rmss-skill-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
// Get a list of the parent item's skill categories for the dropdown
let ownedSkillCategories = this.prepareSkillCategoryValues();
// Figure out if a valid Skill Category is already selected
let selectedSkillCategory = this.prepareSelectedSkillCategory(ownedSkillCategories, this.object.system.category);
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
owned_skillcats: ownedSkillCategories,
enrichedDescription: enrichedDescription,
selected_skillcat: selectedSkillCategory,
designations: CONFIG.rmss.skill_designations
};
return sheetData;
}
activateListeners(html) {
super.activateListeners(html);
// Catch the event when the user clicks one of the New Ranks Checkboxes in a Skill.
// It will increment by one or wrap back to zero on a value of three
html.find(".skillsheet-newrank").click(ev => {
switch (ev.currentTarget.getAttribute("value")) {
case "0":
this.object.update({system: {new_ranks: { value: 1 }}});
break;
case "1":
this.object.update({system: {new_ranks: { value: 2 }}});
break;
case "2":
this.object.update({system: {new_ranks: { value: 3 }}});
break;
case "3":
this.object.update({system: {new_ranks: { value: 0 }}});
break;
}
});
}
// Skills are related to Skill Categories so we need something to allow the user to choose that relationship
// If this Skill is owned then we will return a list of Skill Categories and allow them to choose
// Otherwise we'll just return 'Skill has no owner'
prepareSkillCategoryValues() {
let skillNoOwner = {None: "Skill Has No Owner"};
if (this.item.isEmbedded === null) {
return (skillNoOwner);
}
else
{
const skillCategories = this.item.parent.getOwnedItemsByType("skill_category");
return (skillCategories);
}
}
// Determine which Skill Category is selected and test that it is in the current list of categories.
// If it isn't set it to None.
prepareSelectedSkillCategory(ownedSkillCategories, selectedSkillCategory) {
let defaultSelectedCategory = "None";
if (Object.keys(ownedSkillCategories).includes(selectedSkillCategory)) {
return (selectedSkillCategory);
} else {
return (defaultSelectedCategory);
}
}
// Populate the Skill Category Bonus field on the Skill Sheet.
// Iterate through the owned skill categories and if one of them matches the item id of currently
// selected skill category then set the Skill Category Bonus field to the Total Bonus field of the Skill Category
prepareSelectedSkillCategoryBonus(selected_skillcat) {
if (this.item.isEmbedded === null) {
console.log("Skill has no owner");
}
else
{
const items = this.object.parent.items;
for (const item of items) {
if (item.type === "skill_category" && item._id === selected_skillcat) {
console.log(`rmss | rmss_skill_sheet | Calculating Skill Category bonus for skill: ${this.object.name}`);
this.object.system.category_bonus = item.system.total_bonus;
}
}
}
}
}

View File

@ -0,0 +1,35 @@
// Our Item Sheet extends the default
export default class RMSSSpellSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
width: 530,
height: 440,
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return "systems/fvtt-rolemaster-frp/templates/sheets/spells/rmss-spell-sheet.html";
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
let enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable: this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

53
packs/skill_categories.db Normal file
View File

@ -0,0 +1,53 @@
{"name":"Weapon • Missile Artillery","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"In/Ag/Re","app_stat_1":"In","app_stat_2":"Ag","app_stat_3":"Re","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.swVilWoSF4JH0yhZ"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898842718,"modifiedTime":1663840828472,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"1HevhbCbvMonyQXe"}
{"name":"Armor • Medium","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Ag/St","app_stat_1":"St","app_stat_2":"Ag","app_stat_3":"St","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.ENiEBop9Kgrn9pBt"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897408501,"modifiedTime":1663840704830,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"2fdM9ICcj7vp8nFd"}
{"name":"Athletic • Gymnastics","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/Qu/Ag","app_stat_1":"Ag","app_stat_2":"Qu","app_stat_3":"Ag","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.TASzGNEwHMQUz1AV"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897573841,"modifiedTime":1663840718046,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"2rw9aaYaiTiuKX6p"}
{"name":"Weapon • Missile","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/St/Ag","app_stat_1":"Ag","app_stat_2":"St","app_stat_3":"Ag","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.8a1d0Z2MfJe0R1Eb"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898823756,"modifiedTime":1663840820736,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"2sTx95Y88soBT6Xm"}
{"name":"Technical/Trade • General","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Re/Me/SD","app_stat_1":"Re","app_stat_2":"Me","app_stat_3":"SD","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.1td9QGD20b4nkD6h"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898674902,"modifiedTime":1663840807018,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"3mHLFWrWHEA8Fmyq"}
{"name":"Lore • Obscure","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Me/Re/Me","app_stat_1":"Me","app_stat_2":"Re","app_stat_3":"Me","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.bsDoIUKcNUeqxQQO"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897997337,"modifiedTime":1663840747755,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"47foBA6Yk70CVg2i"}
{"name":"Weapon • Thown","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/St/Ag","app_stat_1":"Ag","app_stat_2":"St","app_stat_3":"Ag","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.kCtfktVNlH414NL2"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898881742,"modifiedTime":1663840832033,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"5e3r6vHlLHjZzyTu"}
{"name":"Technical/Trade • Professional","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Re/Me/In","app_stat_1":"Re","app_stat_2":"Me","app_stat_3":"In","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.xNTn6oV9yMOmfP0Z"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898699996,"modifiedTime":1663840810513,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"67oz5EUQCrxKsh5e"}
{"name":"Spells • Other Realm Open Lists","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.AUzgIWYzrE15qCt9"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898456160,"modifiedTime":1663840790383,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"7z1BmP1Qlx11GL1C"}
{"name":"Lore • Technical","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Me/Re/Me","app_stat_1":"Me","app_stat_2":"Re","app_stat_3":"Me","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.Tw2FXIQb5HA89kbX"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898032616,"modifiedTime":1663840749775,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"9XA38iy0DxyhUaaC"}
{"name":"Armor • Light","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/St/Ag","app_stat_1":"Ag","app_stat_2":"St","app_stat_3":"Ag","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.TMGapmlYutNuQaw8"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897388838,"modifiedTime":1663840702933,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"AIvpcHWyipCtWLvT"}
{"name":"Combat Maneuvers","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/Qu/SD","app_stat_1":"Ag","app_stat_2":"Qu","app_stat_3":"SD","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.bwL0nMJePO6OQNue"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897819566,"modifiedTime":1663840727979,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"Aa5S1GaRJmkyDjIR"}
{"name":"Awareness • Perceptions","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"In/SD/In","app_stat_1":"In","app_stat_2":"SD","app_stat_3":"In","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.gJHBJS3aEz62XbxE"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897610482,"modifiedTime":1663840719487,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"BJlyds9J8ILwLIyW"}
{"name":"Martial Arts • Sweeps","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/St/Ag","app_stat_1":"Ag","app_stat_2":"St","app_stat_3":"Ag","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.n9WaU79Ctzmf6JbC"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898139942,"modifiedTime":1663840757073,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"Bj3no8mNboD8qKTn"}
{"name":"Crafts","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/Me/SD","app_stat_1":"Ag","app_stat_2":"Me","app_stat_3":"SD","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.6nErPtcQ33WXkyH4"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897865848,"modifiedTime":1663840734368,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"CcUHr6zfVpRuu4xv"}
{"name":"Body Development","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Co/SD/Co","app_stat_1":"Co","app_stat_2":"SD","app_stat_3":"Co","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.cWtQ0YU3kGBhL8iR"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897724809,"modifiedTime":1663840726119,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"DL9XZU3P2Bw87PJa"}
{"name":"Weapon • Pole Arms","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Ag/St","app_stat_1":"St","app_stat_2":"Ag","app_stat_3":"St","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.hpmgFsJPXxBQHJSE"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898862386,"modifiedTime":1663840830247,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"HkZMP2SZyRVqzzCJ"}
{"name":"Self Control","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"SD/Pr/SD","app_stat_1":"SD","app_stat_2":"Pr","app_stat_3":"SD","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.1B82OxRKQ781NEa9"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898315491,"modifiedTime":1663840773057,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"IIQQyaCr7KJeeMGp"}
{"name":"Special Defenses","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.eH1iaAuxyIwDmuA8"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898371453,"modifiedTime":1663840778477,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"JmokU4vzQQ4lPicS"}
{"name":"Spells • Own Realm Open Lists","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.w8xibKSY2EShkDJq"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898482739,"modifiedTime":1663840794007,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"KICAwOwrP1cMTRKf"}
{"name":"Subterfuge • Stealth","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/SD/In","app_stat_1":"Ag","app_stat_2":"SD","app_stat_3":"In","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.FM9stBeKGFVdAPdc"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898591826,"modifiedTime":1663840803256,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"KmFEWAhhqtmRZCQv"}
{"name":"Subterfuge • Mechanics","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"In/Ag/Re","app_stat_1":"In","app_stat_2":"Ag","app_stat_3":"Re","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.O0Zwk5hAhCMx6ajP"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898576285,"modifiedTime":1663840801090,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"P6lna8uCBQeVNgau"}
{"name":"Influence","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Pr/Em/In","app_stat_1":"Pr","app_stat_2":"Em","app_stat_3":"In","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.zOKTXAFd6bK3XJZ5"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897929958,"modifiedTime":1663840741277,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"PnBxiNuUS8b3KjGE"}
{"name":"Spells • Own Realm Other Base Lists","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.HeAonlDHotwBy2lx"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898530167,"modifiedTime":1663840795735,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"QolQRsysF7O5XJo8"}
{"name":"Power Awareness","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Em/In/Pr","app_stat_1":"Em","app_stat_2":"In","app_stat_3":"Pr","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.cnnhsP9vAOoN7VMn"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898233748,"modifiedTime":1663840766010,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"R2wZUOFxekV1mBgc"}
{"name":"Spells • Arcane Open Lists","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.R3lQNaGBdz7C5Fhs"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898407655,"modifiedTime":1663840780153,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"RpiCBmS6DKnI8Pok"}
{"name":"Athletic • Endurance","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Co/Ag/St","app_stat_1":"Co","app_stat_2":"Ag","app_stat_3":"St","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.ldmZhkHo8m4VvV2V"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897539929,"modifiedTime":1663840716358,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"Rug8mq3LdUxGhHXK"}
{"name":"Directed Spells","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/SD/Ag","app_stat_1":"Ag","app_stat_2":"SD","app_stat_3":"Ag","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.RA46DfHavzTTrp99"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897900117,"modifiedTime":1663840738205,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"US94Sx46Vn1Rs9D5"}
{"name":"Lore • Magical","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Me/Re/Me","app_stat_1":"Me","app_stat_2":"Re","app_stat_3":"Me","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.V9otC0Kh0y0B3P8Q"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897982070,"modifiedTime":1663840745751,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"X8RmCDRpojxc6u09"}
{"name":"Weapon • 1-H Concussion","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Ag/St","app_stat_1":"St","app_stat_2":"Ag","app_stat_3":"St","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.CXllZNGgTe80uZRQ"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898744329,"modifiedTime":1663840814331,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"YZw0sLV7fZwXD85n"}
{"name":"Weapon • 1-H Edged","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Ag/St","app_stat_1":"St","app_stat_2":"Ag","app_stat_3":"St","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.MV3UkzR77MTPHTau"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898787439,"modifiedTime":1663840817273,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"ZS8ikAjF41M7eZg5"}
{"name":"Awareness • Searching","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"In/Re/SD","app_stat_1":"In","app_stat_2":"Re","app_stat_3":"SD","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.NZl30XPdtYjHqtwp"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897647294,"modifiedTime":1663840720922,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"ZaUdmzJSrTeI0gsl"}
{"name":"Lore • General","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Me/Re/Me","app_stat_1":"Me","app_stat_2":"Re","app_stat_3":"Me","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.5fCeVMz6xVnkmH8o"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897962808,"modifiedTime":1663840744241,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"brpsxpqHEnUfC8a1"}
{"name":"Science/Analytic • Basic","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Re/Me/Re","app_stat_1":"Re","app_stat_2":"Me","app_stat_3":"Re","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.BfDFjciYPFezmes0"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898290307,"modifiedTime":1663840771526,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"dKHsLzvDinagbTCm"}
{"name":"Power Manipulation","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Em/In/Pr","app_stat_1":"Em","app_stat_2":"In","app_stat_3":"Pr","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.CQX0326xax4K3lEP"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898250959,"modifiedTime":1663840767601,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"g64EdTWn0WxJXJFq"}
{"name":"Subterfuge • Attack","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Ag/SD/In","app_stat_1":"Ag","app_stat_2":"SD","app_stat_3":"In","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.Zva3DO0Zmk3G5xWT"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898559045,"modifiedTime":1663840799076,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"gYP00F897jg2I6pC"}
{"name":"Artistic • Passive","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Em/In/Pr","app_stat_1":"Em","app_stat_2":"In","app_stat_3":"Pr","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.NTMvAPWeh5G55Kjs"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897462965,"modifiedTime":1663840713026,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"hFi8bJUxX2HvSoDj"}
{"name":"Athletic • Brawn","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Co/Ag","app_stat_1":"St","app_stat_2":"Co","app_stat_3":"Ag","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.VufLKW42mP7RtinG"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897509473,"modifiedTime":1663840714620,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"iC37JIsE5RETzyd6"}
{"name":"Spells • Own Realm Own Base Lists","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.eEAr5sqnGKej7eiC"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898544500,"modifiedTime":1663840797285,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"iWL7y95CGF7Y1dAq"}
{"name":"Artistic • Active","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Pr/Em/Ag","app_stat_1":"Pr","app_stat_2":"Em","app_stat_3":"Ag","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.cEffILww7nn8vqJ7"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897441727,"modifiedTime":1663840706776,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"iZn6Hzq4cr0zY7Uk"}
{"name":"Power Point Development","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.Q7rKLS4gJwH2Lygw"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898277091,"modifiedTime":1663840769117,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"jOywgkFX58CVDn7z"}
{"name":"Armor • Heavy","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Ag/St","app_stat_1":"St","app_stat_2":"Ag","app_stat_3":"St","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.7UA8xwzcBrKZfFk9"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897366792,"modifiedTime":1663840700907,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"k4IOyyJU8t7MAySl"}
{"name":"Spells • Other Realm Closed Lists","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.7ka2nD2kPq6ixwWu"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898426199,"modifiedTime":1663840788519,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"kbOWBGenZjWIVqrC"}
{"name":"Awareness • Senses","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"In/SD/In","app_stat_1":"In","app_stat_2":"SD","app_stat_3":"In","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.QplAVXReCFVlKVB8"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897666266,"modifiedTime":1663840724332,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"pApyCNOxQb5sIOsf"}
{"name":"Weapon • 2-Handed","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Ag/St","app_stat_1":"St","app_stat_2":"Ag","app_stat_3":"St","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.JiH6JhVoH9jrqptT"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898804378,"modifiedTime":1663840819146,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"qRNUoJcWrF2EmLSP"}
{"name":"Spells • Own Realm Closed Lists","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.cyNDeZDye15gUFzA"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898478099,"modifiedTime":1663840792427,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"ruxbCKHjuGsdQ79z"}
{"name":"Outdoor • Animal","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Em/Ag/Em","app_stat_1":"Em","app_stat_2":"Ag","app_stat_3":"Em","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.6UjbXeI6IFrsdTEy"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898166391,"modifiedTime":1663840758805,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"v6tHhdaL7amLDnzR"}
{"name":"Outdoor • Environmental","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"SD/In/Me","app_stat_1":"SD","app_stat_2":"In","app_stat_3":"Me","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.49iK0oluVd5Z1fpc"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898214394,"modifiedTime":1663840760505,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"vM8rePr9QRXnG6HK"}
{"name":"Spells • Other Realm Base Lists","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"None","app_stat_1":"None","app_stat_2":"None","app_stat_3":"None","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.Wo1SrqGsgMYNoApO"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898426199,"modifiedTime":1663840786314,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"vlFr24F5zJ9fYzs7"}
{"name":"Urban","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"In/Pr/Re","app_stat_1":"In","app_stat_2":"Pr","app_stat_3":"Re","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.JAY4cM0lv1wZm3vo"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898721300,"modifiedTime":1663840812646,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"xHqAlnQjgEScetvh"}
{"name":"Martial Arts • Striking","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Ag/St","app_stat_1":"St","app_stat_2":"Ag","app_stat_3":"St","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.HVistg0XNoVGsSKZ"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898114714,"modifiedTime":1663840754969,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"xJXObXAQcdPbSXg9"}
{"name":"Communcations","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"Re/Me/Em","app_stat_1":"Re","app_stat_2":"Me","app_stat_3":"Em","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.fh63pdckz6VYGAFc"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662897838640,"modifiedTime":1663840730283,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"xTzO3HPhQe5OS255"}
{"name":"Special Attacks","type":"skill_category","img":"systems/fvtt-rolemaster-frp/assets/default/skill_category.svg","system":{"description":"Description here.","applicable_stats":"St/Ag/SD","app_stat_1":"St","app_stat_2":"Ag","app_stat_3":"SD","development_cost":"0","ranks":0,"new_ranks":{"value":0,"max":3,"max_default":3},"rank_bonus":0,"stat_bonus":0,"prof_bonus":0,"special_bonus_1":0,"special_bonus_2":0,"total_bonus":0,"favorite":false},"effects":[],"ownership":{"default":0,"jFAyH93PxEe1ncxK":3},"flags":{"core":{"sourceId":"Item.by1LH6XYGWd5d9bs"}},"_stats":{"systemId":"rmss","systemVersion":"0.0.2","coreVersion":"10.285","createdTime":1662898332987,"modifiedTime":1663840775989,"lastModifiedBy":"jFAyH93PxEe1ncxK"},"folder":null,"sort":0,"_id":"yRIFroc5VC9Oj3qY"}

Binary file not shown.

View File

@ -0,0 +1 @@
MANIFEST-000006

View File

View File

@ -0,0 +1,8 @@
2024/07/26-13:01:33.184951 7f70fa0006c0 Recovering log #4
2024/07/26-13:01:33.276590 7f70fa0006c0 Delete type=0 #4
2024/07/26-13:01:33.276711 7f70fa0006c0 Delete type=3 #2
2024/07/26-14:15:40.712242 7f70f3e006c0 Level-0 table #9: started
2024/07/26-14:15:40.712297 7f70f3e006c0 Level-0 table #9: 0 bytes OK
2024/07/26-14:15:40.750893 7f70f3e006c0 Delete type=0 #7
2024/07/26-14:15:40.806643 7f70f3e006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/07/26-14:15:40.863267 7f70f3e006c0 Manual compaction at level-1 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)

View File

@ -0,0 +1,5 @@
2024/07/26-09:38:09.968297 7f70fa0006c0 Delete type=3 #1
2024/07/26-09:40:38.576572 7f70f3e006c0 Level-0 table #5: started
2024/07/26-09:40:38.595934 7f70f3e006c0 Level-0 table #5: 24247 bytes OK
2024/07/26-09:40:38.633153 7f70f3e006c0 Delete type=0 #3
2024/07/26-09:40:38.675601 7f70f3e006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)

Binary file not shown.

539
rmss.css Normal file
View File

@ -0,0 +1,539 @@
.skillcat-grid-container {
display: grid;
grid-template-columns: [skill-category-name] 10% [applicable-stats] 10% [dev-cost] 8% [num-ranks] 8% [new-ranks] 8% [rank-bonus] 8% [stat-bonus] 8% [prof-bonus] 8% [special-bonus-1] 8% [special-bonus-2] 8% [total-bonus] 8% [controls] 8%;
}
.skillcat-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
justify-content: center;
}
.skillcat-grid-container > div:nth-child(24n+1),
.skillcat-grid-container > div:nth-child(24n+2),
.skillcat-grid-container > div:nth-child(24n+3),
.skillcat-grid-container > div:nth-child(24n+4),
.skillcat-grid-container > div:nth-child(24n+5),
.skillcat-grid-container > div:nth-child(24n+6),
.skillcat-grid-container > div:nth-child(24n+7),
.skillcat-grid-container > div:nth-child(24n+8),
.skillcat-grid-container > div:nth-child(24n+9),
.skillcat-grid-container > div:nth-child(24n+10),
.skillcat-grid-container > div:nth-child(24n+11),
.skillcat-grid-container > div:nth-child(24n+12) {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.skillcat-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.container {
display: flex;
}
.rm-heading {
font-size: 1em;
font-family: PragRoman;
border-bottom: 0px;
}
.actor-icon {
flex-shrink: 1;
}
.favorite-container {
padding: 5px;
}
.header-container {
flex-grow: 2;
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.header-text {
display: flex;
align-items: center;
padding: 1px;
}
.settings-button,
.playersheet-settings {
font-family: Signika, sans-serif;
font-size: 12px;
margin-right: 6px;
}
.resource-container {
display: flex;
flex-direction: row;
flex-grow: 3;
text-align: -webkit-center;
}
.resource-container > * {
flex: 1 1 0;
}
.resource-entry {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.resource-entry input {
width: 50px;
border: none;
}
.stat-container {
flex-direction: column;
flex-shrink: 1;
}
.stat-row {
align-items: center;
}
.equipment-container {
flex-direction: column;
flex-grow: 1;
}
.stat-block {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.stat-name,
.money-name {
width: 75px;
border: none;
font-family: Signika, sans-serif;
font-size: 12px;
}
.stat-name input {
border: none;
}
.stat-header {
font-family: Signika, sans-serif;
font-size: 12px;
}
.fixed-info-container {
flex-grow: 3;
flex-direction: row;
font-family: Signika, sans-serif;
font-size: 12px;
}
.fixed-info-section {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.armor-block {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.race-stat-fixed-info-block {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.role-traits-block {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.background-info-block {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.resistance-block {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
}
.red {
background-color: orangered;
}
.blue {
background-color: lightblue;
}
.grey {
background-color: lightgrey;
}
.green {
background-color: lightseagreen;
}
.skills-grid-container {
display: grid;
grid-template-columns: [favorite] 9% [skill-name] 11% [num-ranks] 9% [new-ranks] 9% [rank-bonus] 9% [category-bonus] 9% [item-bonus] 9% [special-bonus-1] 9% [special-bonus-2] 9% [total-bonus] 9% [controls] 8%;
}
.skills-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: column;
justify-content: center;
}
.skills-grid-container > div:nth-child(22n+1),
.skills-grid-container > div:nth-child(22n+2),
.skills-grid-container > div:nth-child(22n+3),
.skills-grid-container > div:nth-child(22n+4),
.skills-grid-container > div:nth-child(22n+5),
.skills-grid-container > div:nth-child(22n+6),
.skills-grid-container > div:nth-child(22n+7),
.skills-grid-container > div:nth-child(22n+8),
.skills-grid-container > div:nth-child(22n+9),
.skills-grid-container > div:nth-child(22n+10),
.skills-grid-container > div:nth-child(22n+11) {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: column;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.skills-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.money-column {
flex-direction: column;
}
.money-container {
flex-direction: column;
flex-shrink: 1;
padding-left: 10px;
}
.items-grid-container {
display: grid;
grid-template-columns: [worn] 10% [name] 30% [quantity] 15% [weight] 15% [cost] 15% [controls] 15%;
}
.items-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.items-grid-container > div:nth-child(12n+1),
.items-grid-container > div:nth-child(12n+2),
.items-grid-container > div:nth-child(12n+3),
.items-grid-container > div:nth-child(12n+4),
.items-grid-container > div:nth-child(12n+5),
.items-grid-container > div:nth-child(12n+6) {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.items-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.weapons-grid-container {
display: grid;
grid-template-columns: [name] 30% [equipped] 8% [breakage_range] 9% [fumble_range] 9% [strength] 9% [quantity] 9% [weight] 9% [cost] 9% [controls] 8%;
}
.weapons-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.weapons-grid-container > div:nth-child(18n+1),
.weapons-grid-container > div:nth-child(18n+2),
.weapons-grid-container > div:nth-child(18n+3),
.weapons-grid-container > div:nth-child(18n+4),
.weapons-grid-container > div:nth-child(18n+5),
.weapons-grid-container > div:nth-child(18n+6),
.weapons-grid-container > div:nth-child(18n+7),
.weapons-grid-container > div:nth-child(18n+8),
.weapons-grid-container > div:nth-child(18n+9) {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.weapons-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.armor-grid-container {
display: grid;
grid-template-columns: [name] 30% [equipped] 12% [at] 12% [quantity] 12% [weight] 12% [cost] 12% [controls] 10%;
}
.armor-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.armor-grid-container > div:nth-child(14n+1),
.armor-grid-container > div:nth-child(14n+2),
.armor-grid-container > div:nth-child(14n+3),
.armor-grid-container > div:nth-child(14n+4),
.armor-grid-container > div:nth-child(14n+5),
.armor-grid-container > div:nth-child(14n+6),
.armor-grid-container > div:nth-child(14n+7) {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.armor-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.herbs-grid-container {
display: grid;
grid-template-columns: [name] 30% [quantity] 11% [codes] 12% [af] 12% [weight] 12% [cost] 11% [controls] 12%;
}
.herbs-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.herbs-grid-container > div:nth-child(14n+1),
.herbs-grid-container > div:nth-child(14n+2),
.herbs-grid-container > div:nth-child(14n+3),
.herbs-grid-container > div:nth-child(14n+4),
.herbs-grid-container > div:nth-child(14n+5),
.herbs-grid-container > div:nth-child(14n+6),
.herbs-grid-container > div:nth-child(14n+7) {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.herbs-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.spell-grid-container {
display: grid;
grid-template-columns: [favorite] 9% [level] 8% [name] 30% [spell_list] 9% [area_of_effect] 9% [duration] 9% [range] 9% [type] 9% [controls] 8%;
}
.spell-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
}
.spell-grid-container > div:nth-child(18n+1),
.spell-grid-container > div:nth-child(18n+2),
.spell-grid-container > div:nth-child(18n+3),
.spell-grid-container > div:nth-child(18n+4),
.spell-grid-container > div:nth-child(18n+5),
.spell-grid-container > div:nth-child(18n+6),
.spell-grid-container > div:nth-child(18n+7),
.spell-grid-container > div:nth-child(18n+8),
.spell-grid-container > div:nth-child(18n+9) {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: center;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.spell-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.resistances-grid-container {
outline: 1px solid;
/* use instead of border */
margin-top: 1px;
margin-left: 1px;
padding: 5px;
display: grid;
grid-template-columns: [Name] 40% [Value] 20% [Race_Mod] 20% [Total] 20%;
}
.resistances-grid-heading {
font-weight: bold;
border-bottom: 1px solid;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
.resistance-input {
width: 50%;
}
.skillcat-name,
.skill-name,
.item-name,
.spell-name,
.equipable-name {
font-family: Signika, sans-serif;
font-size: 12px;
font-weight: bold;
text-align: center;
}
.skillcat-entry,
.skill-entry,
.item-entry,
.spell-entry,
.equipable-entry {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
}
.skillcat-headeritem,
.skill-headeritem,
.item-headeritem,
.spell-headeritem,
.equipable-headeritem {
text-align: center;
font-weight: bold;
}
.skillcat-controls,
.skill-controls,
.item-controls {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
}
.applicable-stats-grid-container {
display: grid;
grid-template-columns: [app-stat-1] 33% [app-stat-2] 33% [app-stat-3] 33%;
}
.applicable-stats-grid-container > div {
font-family: Signika, sans-serif;
font-size: 12px;
text-align: center;
border-bottom: 1px solid;
padding-top: 3px;
padding-bottom: 3px;
display: flex;
justify-content: flex-end;
flex-direction: column;
justify-content: center;
}
.dice-roller-options {
display: flex;
flex-direction: column;
}
.dice-roller-item {
display: flex;
align-items: center;
margin: 5px;
}
.dice-roller-item div {
flex: 1;
}
.roll-button-container {
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.sheet form {
display: flex;
flex-direction: column;
}
.sheet .sheet-content {
height: 100%;
display: flex;
flex-direction: column;
}
.sheet .sheet-content .editor {
height: 100%;
}

125
rmss.js Normal file
View File

@ -0,0 +1,125 @@
// Import Configuration Object
import { rmss } from "./module/config.js";
//import { registerGetSceneControlButtonsHook } from "./module/controls.js";
// Import document classes.
import { RMSSActor } from "./module/documents/actor.js";
import { RMSSItem } from "./module/documents/item.js";
// Import Sheets
import RMSSItemSheet from "./module/sheets/items/rmss_item_sheet.js";
import RMSSArmorSheet from "./module/sheets/items/rmss_armor_sheet.js";
import RMSSTransportSheet from "./module/sheets/items/rmss_transport_sheet.js";
import RMSSWeaponSheet from "./module/sheets/items/rmss_weapon_sheet.js";
import RMSSHerbOrPoisonSheet from "./module/sheets/items/rmss_herb_or_poison_sheet.js";
import RMSSSpellSheet from "./module/sheets/spells/rmss_spell_sheet.js";
import RMSSSkillCategorySheet from "./module/sheets/skills/rmss_skill_category_sheet.js";
import RMSSSkillSheet from "./module/sheets/skills/rmss_skill_sheet.js";
import RMSSPlayerSheet from "./module/sheets/actors/rmss_player_sheet.js";
import RMSSToolsSCImporter from "./module/sheets/apps/rmss_import_skill_categories.js";
import RMSSToolsDiceRoller from "./module/sheets/apps/rmss_dice_roller.js";
/** Preload handlebars templates for character sheets */
async function preloadHandlebarsTemplates() {
const templatePaths = [
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-stats.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-fixed-info.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-armor-info.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-resistance.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-race-stat-fixed-info.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-role-traits.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-background-info.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-skill-categories.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-skills.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-fav-skills.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-items.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-weapons.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-money.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-skill-categories.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-skills.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-armor.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-herbs.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-spells.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-fav-spells.html",
"systems/fvtt-rolemaster-frp/templates/sheets/actors/parts/actor-fav-items.html",
"systems/fvtt-rolemaster-frp/templates/sheets/apps/app_skill_category_importer.html"
];
return loadTemplates(templatePaths);
}
// Register Scene Controls
// registerGetSceneControlButtonsHook();
// Hook the init function and set up our system
Hooks.once("init", function() {
console.log("rmss | Initialising Rolemaster Standard System");
// Load our custom actor and item classes
console.log("rmss | Loading Rolemaster Actor and Item classes");
game.rmss = {
RMSSActor,
RMSSItem,
applications: {
RMSSToolsSCImporter,
RMSSToolsDiceRoller
}
};
// Define custom Document classes
CONFIG.Actor.documentClass = RMSSActor;
CONFIG.Item.documentClass = RMSSItem;
// Add PragRoman Font
CONFIG.fontDefinitions["PragRoman"] = {
editor: true,
fonts: [
{urls: ["systems/fvtt-rolemaster-frp/assets/fonts/PragRoman.woff2"]}
]
};
// Make Config Data Available
CONFIG.rmss = rmss;
// Unregister Default Sheets
console.log("rmss | Unregistering core sheets");
Items.unregisterSheet("core", ItemSheet);
Actors.unregisterSheet("core", ActorSheet);
// Register RMSS Sheets
console.log("rmss | Registering RMSS sheets");
// Items
Items.registerSheet("fvtt-rolemaster-frp", RMSSItemSheet, {makeDefault: true, label: "rmss.entity_sheet.item", types: ["item"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSArmorSheet, {makeDefault: true, label: "rmss.entity_sheet.armor", types: ["armor"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSTransportSheet, {makeDefault: true, label: "rmss.entity_sheet.transport", types: ["transport"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSWeaponSheet, {makeDefault: true, label: "rmss.entity_sheet.weapon", types: ["weapon"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSHerbOrPoisonSheet, {makeDefault: true, label: "rmss.entity_sheet.herb_or_poison", types: ["herb_or_poison"]});
// Spells
Items.registerSheet("fvtt-rolemaster-frp", RMSSSpellSheet, {makeDefault: true, label: "rmss.entity_sheet.spell", types: ["spell"]});
// Skills
Items.registerSheet("fvtt-rolemaster-frp", RMSSSkillCategorySheet, {makeDefault: true, label: "rmss.entity_sheet.skill_category", types: ["skill_category"]});
Items.registerSheet("fvtt-rolemaster-frp", RMSSSkillSheet, {makeDefault: true, label: "rmss.entity_sheet.skill", types: ["skill"]});
// Actors
Actors.registerSheet("fvtt-rolemaster-frp", RMSSPlayerSheet, {makeDefault: true, label: "rmss.entity_sheet.player_characrer", types: ["character"]});
// Preload Handlebars Templates
console.log("rmss | Preloading Handlebars Templates");
preloadHandlebarsTemplates();
// Handlebars Helpers
Handlebars.registerHelper("switch", function(value, options) {
this.switch_value = value;
return options.fn(this);
});
Handlebars.registerHelper("case", function(value, options) {
if (value === this.switch_value) {
return options.fn(this);
}
});
});

1
rmss/.gitignore vendored
View File

@ -1 +0,0 @@
node_modules/

View File

@ -1,14 +0,0 @@
// Less configuration
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Less Compile",
"type": "shell",
"command": "lessc less/rmss.less rmss.css",
"group": "build"
}
]
}

View File

@ -1,9 +0,0 @@
This tutorial is based on the video tutorials by Cédric Hauteville you can watch them here: https://www.youtube.com/playlist?list=PLFV9z59nkHDccUbRXVt623UdloPTclIrz parts of it were also lifted from the Foundry VTT Boilerplate system by XXX.
Icons have been sourced from https://game-icons.net
This system uses less for CSS you can see a good installation guide for VSCode at https://code.visualstudio.com/docs/languages/css#_transpiling-sass-and-less-into-css
User Notes
Skill Categories and Skills cannot be renamed if they are owned and you cannot drag a duplicate named skill to the sheet

View File

@ -1,22 +0,0 @@
Small
1. Add Relationship between skills and skill categories
2. Remove Tables and replace with CSS Grid
3. Fix unaligned CSS
4. Prevent Duplication on Drag and Drop for Skills and Skill Categories, possibly spells too.
DONE - Overriden _onDropItem on Player Sheet
DONE - Skill Categories cannot be renamed if they are owned.
Medium
4. Inventory sorted by types
i. Drag and drop should add an item if it already exists.
ii. Equipables
iii. Favorites
5. Creature Sheet
Large
6. Dice Roller
7. Initiative System

View File

@ -1,6 +0,0 @@
@import "./item-sheet.less";
@import "./actor-sheet.less";
@import "./skillcat-sheet.less";
@import "./money-sheet.less";
@import "./table.less";
@import "./grid.less";

View File

@ -1,53 +0,0 @@
export const rmss = {};
rmss.curreny_type = {
mp: "rmss.curreny_type.mp",
pp: "rmss.curreny_type.pp",
gp: "rmss.curreny_type.gp",
sp: "rmss.curreny_type.sp",
bp: "rmss.curreny_type.bp",
cp: "rmss.curreny_type.cp"
};
rmss.stats = {
agility: {
fullname: "Agility",
shortname: "Ag"
},
constitution: {
fullname: "Constitution",
shortname: "Co"
},
memory: {
fullname: "Memory",
shortname: "Me"
},
reasoning: {
fullname: "Reasoning",
shortname: "Re"
},
self_discipline: {
fullname: "Self Discipline",
shortname: "SD"
},
empathy: {
fullname: "Empathy",
shortname: "Em"
},
intuition: {
fullname: "Intuition",
shortname: "In"
},
presence: {
fullname: "Presence",
shortname: "Pr"
},
quickness: {
fullname: "Quickness",
shortname: "Qu"
},
strength: {
fullname: "Strength",
shortname: "St"
}
}

View File

@ -1,152 +0,0 @@
export class RMSSActor extends Actor {
/** @override */
prepareData() {
// Prepare data for the actor. Calling the super version of this executes
// the following, in order: data reset (to clear active effects),
// prepareBaseData(), prepareEmbeddedDocuments() (including active effects),
// prepareDerivedData().
super.prepareData();
}
prepareDerivedData() {
const actorData = this;
const systemData = actorData.system;
const flags = actorData.flags.rmss || {};
// Make separate methods for each Actor type (character, npc, etc.) to keep
// things organized.
this._prepareCharacterData(actorData);
this._prepareNpcData(actorData);
}
/**
* Prepare Character type specific data
*/
_prepareCharacterData(actorData) {
if (actorData.type !== 'character') return;
// Calculate Stat Bonuses for the Actor
this.prepareStatBonuses(actorData);
// Calculate Resistance Rolls for the Actor
this.prepareResistanceRolls(actorData);
// Iterate through and apply Stat bonuses for Skill Category Items
this.prepareSkillCategoryStatBonuses();
}
/**
* Prepare NPC type specific data.
*/
_prepareNpcData(actorData) {
if (actorData.type !== 'npc') return;
// Make modifications to data here. For example:
const data = actorData.data;
data.xp = (data.cr * data.cr) * 100;
}
// Tally each stat bonus and populate the total field.
prepareStatBonuses(actorData) {
const systemData = actorData.system;
actorData.system.stats.agility.stat_bonus = Number(systemData.stats.agility.racial_bonus)+Number(systemData.stats.agility.special_bonus)+Number(systemData.stats.agility.basic_bonus);
actorData.system.stats.constitution.stat_bonus = Number(systemData.stats.constitution.racial_bonus)+Number(systemData.stats.constitution.special_bonus)+Number(systemData.stats.constitution.basic_bonus);
actorData.system.stats.memory.stat_bonus = Number(systemData.stats.memory.racial_bonus)+Number(systemData.stats.memory.special_bonus)+Number(systemData.stats.memory.basic_bonus);
actorData.system.stats.reasoning.stat_bonus = Number(systemData.stats.reasoning.racial_bonus)+Number(systemData.stats.reasoning.special_bonus)+Number(systemData.stats.reasoning.basic_bonus);
actorData.system.stats.self_discipline.stat_bonus = Number(systemData.stats.self_discipline.racial_bonus)+Number(systemData.stats.self_discipline.special_bonus)+Number(systemData.stats.self_discipline.basic_bonus);
actorData.system.stats.empathy.stat_bonus = Number(systemData.stats.empathy.racial_bonus)+Number(systemData.stats.empathy.special_bonus)+Number(systemData.stats.empathy.basic_bonus);
actorData.system.stats.intuition.stat_bonus = Number(systemData.stats.intuition.racial_bonus)+Number(systemData.stats.intuition.special_bonus)+Number(systemData.stats.intuition.basic_bonus);
actorData.system.stats.presence.stat_bonus = Number(systemData.stats.presence.racial_bonus)+Number(systemData.stats.presence.special_bonus)+Number(systemData.stats.presence.basic_bonus);
actorData.system.stats.quickness.stat_bonus = Number(systemData.stats.quickness.racial_bonus)+Number(systemData.stats.quickness.special_bonus)+Number(systemData.stats.quickness.basic_bonus);
actorData.system.stats.strength.stat_bonus = Number(systemData.stats.strength.racial_bonus)+Number(systemData.stats.strength.special_bonus)+Number(systemData.stats.strength.basic_bonus);
}
// Calculate each Resistance Roll with the formula on the character sheet.
prepareResistanceRolls(actorData) { // TODO: Add Racial modifiers to resistance
const systemData = actorData.system;
actorData.system.resistance_rolls.essence = Number(systemData.stats.empathy.stat_bonus * 3);
actorData.system.resistance_rolls.channeling = Number(systemData.stats.intuition.stat_bonus * 3);
actorData.system.resistance_rolls.mentalism = Number(systemData.stats.presence.stat_bonus * 3);
actorData.system.resistance_rolls.fear = Number(systemData.stats.self_discipline.stat_bonus * 3);
actorData.system.resistance_rolls.poison_disease = Number(systemData.stats.constitution.stat_bonus * 3);
actorData.system.resistance_rolls.chann_ess = Number(systemData.stats.intuition.stat_bonus) + Number(systemData.stats.empathy.stat_bonus);
actorData.system.resistance_rolls.chann_ment = Number(systemData.stats.intuition.stat_bonus) + Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.ess_ment = Number(systemData.stats.empathy.stat_bonus) + Number(systemData.stats.presence.stat_bonus);
actorData.system.resistance_rolls.arcane = Number(systemData.stats.empathy.stat_bonus) + Number(systemData.stats.intuition.stat_bonus) + Number(systemData.stats.presence.stat_bonus);
}
/*prepareSkillCategoryBonuses() {
for (const item of this.items) {
if (item.type === "skill") {
}
}
}*/
// Tallys the bonus for each Stat that is applicable to the Skill Category and then updates the total
prepareSkillCategoryStatBonuses() {
for (const item of this.items) {
if (item.type === "skill_category") {
// Get all the applicable stats for this skill category
var app_stat_1 = item.system.app_stat_1;
var app_stat_2 = item.system.app_stat_2;
var app_stat_3 = item.system.app_stat_3;
// If the first one is None we don't need to do anything further
if (app_stat_1 === "None") {
continue;
}
else
{
var applicable_stat_bonus = 0;
var app_stat_1_found = false;
var app_stat_2_found = false;
var app_stat_3_found = false;
// Iterate through the applicable stats and find their full names
for (const stat in CONFIG.rmss.stats) {
// If the configured App Stat matches the one of the stats in config
if (app_stat_1 === CONFIG.rmss.stats[stat].shortname) {
app_stat_1_found = true;
// Get the Stat Bonus
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
}
if (app_stat_2 === CONFIG.rmss.stats[stat].shortname) {
app_stat_2_found = true;
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
}
if (app_stat_3 === CONFIG.rmss.stats[stat].shortname) {
app_stat_3_found = true;
applicable_stat_bonus = applicable_stat_bonus + this.system.stats[stat].stat_bonus;
}
}
//console.log("Applicable Stat Bonus: " + applicable_stat_bonus)
if (app_stat_1_found === true && app_stat_2_found === true && app_stat_3_found === true) {
// Apply the update if we found stat bonuses for every applicable stat
item.system.stat_bonus = applicable_stat_bonus;
// Update the total in the Item
item.calculateSkillCategoryTotalBonus(item);
}
}
}
}
}
// For each skill category return an object in this format.
// {{ _id: "skill category name"}}
// This is the format that the select helper on the skill sheet needs
getOwnedSkillCategories() {
var ownedSkillCategories = {None: "None"};
for (const item of this.items) {
if (item.type === "skill_category") {
ownedSkillCategories[item._id] = item.name;
}
}
return(ownedSkillCategories);
}
}

View File

@ -1,79 +0,0 @@
export class RMSSItem extends Item {
/** @override */
prepareData() {
// Prepare data for the item. Calling the super version of this executes
// the following, in order: data reset (to clear active effects),
// prepareBaseData(), prepareEmbeddedDocuments() (including active effects),
// prepareDerivedData().
super.prepareData();
}
// Set the icon images for newly created images.
async _preCreate(data, options, userId) {
await super._preCreate(data, options, userId);
// Do not set on copied items if they have a custom Icon.
if (!data.name.includes("(Copy)"))
{
if (this.type == "armor") {
await this.updateSource({img: "systems/rmss/assets/default/armor.svg"});
}
else if (this.type == "weapon") {
await this.updateSource({img: "systems/rmss/assets/default/weapon.svg"});
}
else if (this.type == "skill") {
await this.updateSource({img: "systems/rmss/assets/default/skill.svg"});
}
else if (this.type == "skill_category") {
await this.updateSource({img: "systems/rmss/assets/default/skill_category.svg"});
}
else if (this.type == "spell") {
await this.updateSource({img: "systems/rmss/assets/default/spell.svg"});
}
else if (this.type == "herb_or_poison") {
await this.updateSource({img: "systems/rmss/assets/default/herb_or_poison.svg"});
}
else if (this.type == "transport") {
await this.updateSource({img: "systems/rmss/assets/default/transport.svg"});
}
}
}
calculateSkillCategoryTotalBonus(itemData) {
if (this.type === "skill_category") {
const systemData = itemData.system;
itemData.system.total_bonus = Number(systemData.rank_bonus)+Number(systemData.stat_bonus)+Number(systemData.prof_bonus)+Number(systemData.special_bonus_1)+Number(systemData.special_bonus_2);
}
}
prepareDerivedData() {
const itemData = this;
const systemData = itemData.system;
const flags = itemData.flags.rmss || {};
// Make separate methods for each item type to keep things organized.
this._prepareSkillCategoryData(itemData);
this._prepareSkillData(itemData);
}
_prepareSkillCategoryData(itemData) {
if (itemData.type !== 'skill_category') return;
// Make modifications to data here. For example:
//const data = itemData.data;
// Calculate Stat Bonuses
this.calculateSkillCategoryTotalBonus(itemData);
}
_prepareSkillData(itemData) {
if (itemData.type !== 'skill') return;
// Make modifications to data here. For example:
const systemData = itemData.system;
// Calculate Stat Bonuses
itemData.system.total_bonus = Number(systemData.rank_bonus)+Number(systemData.category_bonus)+Number(systemData.item_bonus)+Number(systemData.special_bonus_1)+Number(systemData.special_bonus_2);
}
}

View File

@ -1,166 +0,0 @@
export default class RMSSPlayerSheet extends ActorSheet {
// Override Default Options, Set CSS Classes, Set Default Sheet, Set up Sheet Tabs
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
template: "systems/rmss/templates/sheets/actors/rmss-character-sheet.html",
classes: ["rmss", "sheet", "actor"],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "features" }]
});
}
// Make the data available to the sheet template
getData() {
const context = super.getData();
// Use a safe clone of the actor data for further operations.
const actorData = this.actor.toObject(false);
// Add the actor's data to context.data for easier access, as well as flags.
context.system = actorData.system;
context.flags = actorData.flags;
// Prepare character data and items.
if (actorData.type == 'character') {
this._prepareItems(context);
this._prepareCharacterData(context);
}
// Prepare NPC data and items.
if (actorData.type == 'npc') {
this._prepareItems(context);
}
return context;
}
//Override this method to check for duplicates when things are dragged to the sheet
// We don't want duplicate skills and skill categories.
async _onDropItem(event, data) {
// Reconstruct the item from the event
const newitem = await Item.implementation.fromDropData(data);
const itemData = newitem.toObject();
if (itemData.type === "skill_category" || itemData.type === "skill"){
// Get the already owned Items from the actor and push into an array
const owneditems = this.object.getOwnedSkillCategories();
console.log(owneditems);
var owneditemslist = Object.values(owneditems);
// Check if the dragged item is not in the array and not owned
if (!owneditemslist.includes(itemData.name)) {
console.log("Not Owned!");
super._onDropItem(event, data);
}
}
else {
super._onDropItem(event, data);
}
}
_prepareCharacterData(context) {
}
_prepareItems(context) {
// Initialize containers.
const gear = [];
const playerskill= [];
const skillcat = [];
// Iterate through items, allocating to containers
for (let i of context.items) {
i.img = i.img || DEFAULT_TOKEN;
// Append to gear.
if (i.type === 'item' || i.type === 'armor' || i.type === 'weapon' || i.type === 'herb_or_poison') {
gear.push(i);
}
// Append to skill categories.
else if (i.type === 'skill_category') {
skillcat.push(i);
}
// Append to playerskill
else if (i.type === 'skill') {
playerskill.push(i);
}
}
// Sort Skill/Skillcat Arrays
skillcat.sort(function (a, b){
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
playerskill.sort(function (a, b){
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
// Assign and return
context.gear = gear;
context.skillcat = skillcat;
context.playerskill = playerskill;
}
activateListeners(html) {
super.activateListeners(html);
// NOTE: Can you do skill/item favorites this way?
// Render the item sheet for viewing/editing prior to the editable check.
html.find('.item-edit').click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
//console.log(this);
item.sheet.render(true);
});
// -------------------------------------------------------------
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
// Add Item
html.find('.item-create').click(this._onItemCreate.bind(this));
// Delete Item
html.find('.item-delete').click(ev => {
const item = this.actor.items.get(ev.currentTarget.getAttribute("data-item-id"));
//console.log(ev.currentTarget.getAttribute("data-item-id"));
item.delete();
});
}
async _onItemCreate(event) {
event.preventDefault();
const header = event.currentTarget;
// Get the type of item to create.
const type = header.dataset.type;
// Grab any data associated with this control.
const data = duplicate(header.dataset);
// Initialize a default name.
const name = `New ${type.capitalize()}`;
// Prepare the item object.
const itemData = {
name: name,
type: type,
data: data
};
// Remove the type from the dataset since it's in the itemData.type prop.
//delete itemData.data["type"];
delete itemData.data.type;
// Finally, create the item!
return await Item.create(itemData, {parent: this.actor});
}
}

View File

@ -1,36 +0,0 @@
// Our Item Sheet extends the default
export default class RMSSArmorSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/rmss/templates/sheets/items/rmss-armor-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-armor-sheet.html`;
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,36 +0,0 @@
// Our Item Sheet extends the default
export default class RMSSHerbAndPoisonSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/rmss/templates/sheets/items/rmss-herb-or-poison-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-herb-or-poison-sheet.html`;
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,36 +0,0 @@
// Our Item Sheet extends the default
export default class RMSSItemSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/rmss/templates/sheets/items/rmss-item-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-item-sheet.html`;
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,36 +0,0 @@
// Our Item Sheet extends the default
export default class RMSSTransportSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/rmss/templates/sheets/items/rmss-transport-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-transport-sheet.html`;
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,36 +0,0 @@
// Our Item Sheet extends the default
export default class RMSSWeaponSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/rmss/templates/sheets/items/rmss-weapon-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/items/rmss-weapon-sheet.html`;
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
enrichedDescription: enrichedDescription
};
return sheetData;
}
}

View File

@ -1,111 +0,0 @@
// Our Item Sheet extends the default
export default class RMSSSkillCategorySheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/rmss/templates/sheets/skills/rmss-skill-category-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/skills/rmss-skill-category-sheet.html`;
}
// Make the data available to the sheet template
async getData() {
const context = await super.getData();
// Get a list of stats that can be used as applicable stats
var applicable_stat_list = this.prepareApplicableStatValues(CONFIG);
//Get the currently selected value for all three applicable stats
var applicable_stat_1_selected = this.prepareApplicableSelectedStat("app_stat_1");
var applicable_stat_2_selected = this.prepareApplicableSelectedStat("app_stat_2");
var applicable_stat_3_selected = this.prepareApplicableSelectedStat("app_stat_3");
// Build and apply the display string for Applicable Stats
var applicable_stat_text = this.buildApplicableStatsText(applicable_stat_1_selected, applicable_stat_2_selected, applicable_stat_3_selected);
//context.item.system['applicable_stats'] = applicable_stat_text;
context.item.system.applicable_stats = applicable_stat_text;
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
let sheetData = {
owner: this.item.isOwner,
editable :this.isEditable,
item: context.item,
system: context.item.system,
config: CONFIG.rmss,
applicable_stat_list: applicable_stat_list,
applicable_stat_1_selected: applicable_stat_1_selected,
applicable_stat_2_selected: applicable_stat_2_selected,
applicable_stat_3_selected: applicable_stat_3_selected,
enrichedDescription: enrichedDescription
};
return sheetData;
}
async _setApplicableStat(item, ev) {
// Build a JSON Object from the select tag value and select name (item data attribute key)
var update_key = ev.currentTarget.getAttribute("name");
var update_data = ev.target.value;
// Update Item Data
await item.update({[update_key]: update_data});
}
prepareApplicableStatValues(CONFIG) {
var applicable_stat_list = {None: "None"};
// Get a list of stat shortnames from the config
for (const item in CONFIG.rmss.stats) {
applicable_stat_list[CONFIG.rmss.stats[item].shortname] = CONFIG.rmss.stats[item].shortname;
}
return applicable_stat_list;
}
// Determine which Stat is selected for applicable stats
prepareApplicableSelectedStat(app_stat) {
var applicable_stat_selected = "";
applicable_stat_selected = this.item.system[app_stat];
return applicable_stat_selected;
}
// Build the text that is displayed in the Applicable Stats field
buildApplicableStatsText(app_stat_1, app_stat_2, app_stat_3) {
if (app_stat_1 === "None") {
return("None");
}
else if (app_stat_1 !== "None" && app_stat_2 === "None") {
return(app_stat_1);
}
else if (app_stat_1 !== "None" && app_stat_2 !== "None" && app_stat_3 === "None" ) {
return(app_stat_1 + "/" + app_stat_2 );
}
else if (app_stat_1 !== "None" && app_stat_2 !== "None" && app_stat_3 !== "None" ) {
return(app_stat_1 + "/" + app_stat_2 + "/" + app_stat_3 );
}
else {
return("None");
}
}
activateListeners(html) {
super.activateListeners(html);
// -------------------------------------------------------------
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
// Update Applicable Stats for Skill Categories
html.find('.stat-selector').change(ev => {
this._setApplicableStat(this.item, ev);
});
}
}

View File

@ -1,90 +0,0 @@
// Our Item Sheet extends the default
export default class RMSSSkillSheet extends ItemSheet {
// Set the height and width
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 530,
height: 440,
template: "systems/rmss/templates/sheets/skills/rmss-skill-sheet.html",
classes: ["rmss", "sheet", "item"]
});
}
// If our sheet is called here it is.
get template() {
return `systems/rmss/templates/sheets/skills/rmss-skill-sheet.html`;
}
// Make the data available to the sheet template
async getData() {
const baseData = await super.getData();
var enrichedDescription = await TextEditor.enrichHTML(this.item.system.description, {async: true});
// Get a list of the parent item's skill categories for the dropdown
var owned_skillcats = this.prepareSkillCategoryValues();
// Figure out if a valid Skill Category is already selected
var selected_skillcat = this.prepareSelectedSkillCategory(owned_skillcats, this.object.system.category);
this.prepareSelectedSkillCategoryBonus(selected_skillcat);
let sheetData = {
owner: this.item.isOwner,
editable :this.isEditable,
item: baseData.item,
system: baseData.item.system,
config: CONFIG.rmss,
owned_skillcats: owned_skillcats,
enrichedDescription: enrichedDescription,
selected_skillcat: selected_skillcat
};
return sheetData;
}
prepareSkillCategoryValues() {
// If there is no player owning this Skill then we cannot assign a category.
var skillcat_list = {None: "Skill Has No Owner", };
if (this.item.isEmbedded === null) {
return(skillcat_list);
}
else
{
const skillcats = this.item.parent.getOwnedSkillCategories();
return(skillcats);
}
}
// Determine which Stat is selected and test that it is in the current list of categories.
prepareSelectedSkillCategory(ownedskillcats, selected_category) {
// Start By setting the owned category to None, if nothing happens this will be the default
var default_selected_category = "None";
// Get a list of keys from the currently owned skill categories and compare to the current value
if (Object.keys(ownedskillcats).includes(selected_category)) {
return(selected_category);
} else {
return(default_selected_category);
}
}
prepareSelectedSkillCategoryBonus(selected_skillcat) {
if (this.item.isEmbedded === null) {
console.log("Skill has no owner");
}
else
{
const items = this.object.parent.items;
for (const item of items) {
if (item.type === "skill_category" && item._id === selected_skillcat) {
this.object.system.category_bonus = item.system.total_bonus;
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More