Created Tails of Equestria sheet.

This commit is contained in:
Cazra
2017-05-07 23:10:18 -04:00
parent ccfefdfb61
commit a5a8f5ea93
17 changed files with 1707 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
node_modules
+48
View File
@@ -0,0 +1,48 @@
module.exports = function(grunt) {
grunt.initConfig({
less: {
default: {
files: {
'sheet.css': 'less/index.less'
}
}
},
pug: {
default: {
files: {
'sheet.html': 'pug/index.pug'
},
options: {
pretty: true
}
}
},
'string-replace': {
default: {
files: {
'sheet.css': 'sheet.css'
},
options: {
replacements: [
{
pattern: /,\n/g,
replacement: ', '
},
{
pattern: /\.((?!charsheet)[^ .\n]+)(?=.+\{)/g,
replacement: function(match, p1) {
return '.sheet-' + p1;
}
}
]
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-pug');
grunt.loadNpmTasks('grunt-string-replace');
grunt.registerTask('default', ['less', 'pug', 'string-replace']);
};
+4
View File
@@ -0,0 +1,4 @@
# Tails of Equestria
This character sheet is for Tails of Equestria, the officially licensed
My Little Pony: Friendship is Magic roleplaying game.
+101
View File
@@ -0,0 +1,101 @@
/**
* Forces an update on a list of numerical fields, also making sure that
* any undefined fields are set to 0.
* @param {string[]} attrs
* @param {function} cb
*/
function forceUpdate(attrs, cb) {
parseAttrs(attrs, values => {
let tempValues = {};
_.each(attrs, attr => {
tempValues[attr] = -9999;
});
setAttrs(tempValues);
setAttrs(values);
});
}
function onChange(attrs, cb) {
attrs = _.map(attrs, attr => {
return 'change:' + attr;
}).join(' ');
on(attrs, cb);
}
function onChangeParse(attrs, cb) {
onChange(attrs, () => {
parseAttrs(attrs, cb);
});
}
/**
* Gets the specified attributes and parses them as an integer or 0.
*/
function parseAttrs(attrs, cb) {
getAttrs(attrs, function(values) {
_.each(attrs, function(attr) {
if(_.isUndefined(values[attr]))
values[attr] = 0;
else if(!isNaN(values[attr]))
values[attr] = parseInt(values[attr]);
});
cb(values);
});
}
function updateCutieMarkTalent() {
var prefix = 'talent_cutieMark';
_updateTalents(prefix);
}
function updateTalents() {
updateCutieMarkTalent();
getSectionIDs('repeating_talents', ids => {
_.each(ids, id => {
var prefix = 'repeating_talents_' + id;
_updateTalents(prefix);
});
});
}
function _updateTalents(prefix) {
parseAttrs([prefix + '_dice', prefix + '_trait', 'body', 'mind', 'charm'], values => {
var talentDice = values[prefix + '_dice'];
var trait = values[prefix + '_trait'];
var traitDice = values[trait];
if(talentDice === 'null' || !traitDice)
setAttrs({
[prefix + '_equation']: 0
});
else {
var traitDice = values[trait];
setAttrs({
[prefix + '_equation']: talentDice + ' + ' + traitDice
});
}
});
}
// Change events
on('change:repeating_talents', evt => {
updateTalents();
});
onChange(['talent_cutieMark_dice', 'talent_cutieMark_trait'], () => {
updateCutieMarkTalent();
});
onChange(['body', 'mind', 'charm'], () => {
updateTalents();
});
on('sheet:opened', () => {
setAttrs({
character_sheet: 'TailsOfEquestria v1.0.0'
});
updateTalents();
});
+5
View File
@@ -0,0 +1,5 @@
@fontColor: #5e3dba;
@twilightColor: #DECFE1;
@pinkieColor: #F9B6DD;
@dashieColor: #B3E7EF;
@flutterColor: #FAD1E4;
+163
View File
@@ -0,0 +1,163 @@
@import "colors.less";
input {
border: none;
box-shadow: none;
&[type=number]::-webkit-inner-spin-button, &[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
}
label {
color: @fontColor;
}
select {
box-shadow: none;
height: auto;
line-height: 18px;
margin-bottom: 0;
-moz-appearance: none;
-webkit-appearance: none;
}
textarea {
background: linear-gradient(to bottom, transparent, transparent 17px, @fontColor);
background-attachment: local;
background-size: 1px 18px;
border: none;
box-shadow: none;
color: @fontColor;
padding: 0;
resize: none;
}
.labelledAbove {
display: inline-block;
label {
font-size: 0.8em;
margin-bottom: 0;
padding-top: 0.5em;
}
}
.labelledBoxH {
background: #aaa;
display: inline-block;
overflow: hidden;
& > label {
display: inline;
font-weight: bold;
padding: 0 0.25em;
vertical-align: middle;
}
& > .inner {
display: inline-block;
float: right;
vertical-align: middle;
& > * {
vertical-align: middle;
}
.fraction {
display: inline-block;
input {
border: none;
display: inline;
}
}
}
}
.labelledBoxV {
background: #aaa;
display: inline-block;
overflow: hidden;
& > label {
display: inline-block;
font-weight: bold;
margin: 0;
padding: 0;
text-align: center;
}
& > .inner {
text-align: center;
width: 100%;
input {
text-align: center;
width: 100%;
}
.fraction {
display: inline-block;
input {
border: none;
display: inline;
}
}
}
}
.labelledUnderlined {
display: inline-block;
margin-bottom: 1em;
min-width: 0.45in;
position: relative;
label {
position: absolute;
font-size: 0.75em;
line-height: 0.75em;
top: 110%;
}
.inner {
border-bottom: dotted 1px @fontColor;
width: 100%;
input {
border: none;
border-radius: 0;
padding-bottom: 0;
width: 100%;
}
select {
border: none;
border-radius: 0;
padding-bottom: 0;
width: 100%;
}
.readOnlyBox {
padding: 0;
padding-top: initial;
width: 100%;
}
}
}
.mathOperator {
display:inline-block;
margin-bottom: 0.5em;
padding-left: 0.25em;
padding-right: 0.25em;
}
.readOnlyBox {
background: #ddd;
display: inline-block;
padding: 4px;
width: 3.5em;
}
+51
View File
@@ -0,0 +1,51 @@
@import "colors.less";
@import "rolltemplate.less";
.charsheet {
background: #fff;
color: @fontColor;
width: 8in;
@import "fields.less";
@import "main.less";
h1 {
color: @fontColor;
}
.centeredH {
text-align: center;
}
.centeredV > * {
vertical-align: middle;
}
.floatLeft {
float: left;
}
.floatRight {
float: right;
}
.inlineBlock {
display: inline-block;
}
.top {
height: 2.6in;
overflow: hidden;
position: relative;
width: 8in;
.mask {
height: 1in;
left: 0;
position: absolute;
top: 1.65in;
width: 100%;
background: linear-gradient(fade(#fff, 0%), #fff);
}
}
}
+290
View File
@@ -0,0 +1,290 @@
@import "colors.less";
.main-container {
border: solid 5px #ea60e1;
border-radius: 0.25in;
padding: 1em;
position: relative;
& > div {
margin-bottom: 0.2in;
}
.bio {
background: @twilightColor;
border-radius: 0.1in;
display: inline-block;
padding: 1em;
width: 5in;
.labelledUnderlined {
display: block;
font-size: 2em;
margin-bottom: 0.5em;
width: 100%;
label {
display: inline-block;
line-height: 1em;
margin: 0;
position: relative;
text-align: right;
width: 1.5in;
}
.inner {
display: inline-block;
width: auto;
input, select {
background: transparent;
color: @fontColor;
font-size: 0.7em;
padding: 0;
width: 3in;
}
}
}
}
.friendshipTokens {
background: #f226e4;
border-radius: 0.75in;
display: inline-block;
height: 1.5in;
position: absolute;
right: 1em;
top: 1em;
width: 1.5in;
h1 {
color: #fff;
font-size: 1.75em;
span {
height: 100%;
position: absolute;
text-align: center;
transform-origin: center;
width: 100%;
&:nth-of-type(1) {
transform: rotate(-63deg);
}
&:nth-of-type(2) {
transform: rotate(-49deg);
}
&:nth-of-type(3) {
transform: rotate(-35deg);
}
&:nth-of-type(4) {
transform: rotate(-21deg);
}
&:nth-of-type(5) {
transform: rotate(-7deg);
}
&:nth-of-type(6) {
transform: rotate(7deg);
}
&:nth-of-type(7) {
transform: rotate(21deg);
}
&:nth-of-type(8) {
transform: rotate(35deg);
}
&:nth-of-type(9) {
transform: rotate(49deg);
}
&:nth-of-type(10) {
transform: rotate(63deg);
}
}
}
input {
background: transparent;
color: #fff;
font-size: 5em;
left: 50%;
position: absolute;
text-align: center;
top: 50%;
transform: translate(-50%, -50%);
}
}
.quirks {
background: @twilightColor;
border-radius: 0.1in;
padding: 1em;
h1 {
color: @fontColor;
font-size: 2em;
}
.quirk {
& > label {
display: inline-block;
margin-bottom: 0;
margin-top: 0.25em;
vertical-align: middle;
width: 0.3in;
}
input {
background: transparent;
}
.labelledUnderlined:nth-of-type(2) {
width: 4.5in;
}
}
}
.stamina {
background: @pinkieColor;
border-radius: 0.1in;
display: inline-block;
padding: 1em;
vertical-align: middle;
h1 {
color: @fontColor;
display: inline-block;
font-size: 2em;
vertical-align: middle;
}
.fraction {
display: inline-block;
input {
background: transparent;
border-bottom: dotted 1px @fontColor;
color: @fontColor;
font-size: 2em;
padding: 0;
text-align: center;
width: 2em;
}
}
}
.talents {
background: @dashieColor;
border-radius: 0.1in;
padding: 1em;
h1 {
color: @fontColor;
font-size: 2em;
}
.talent {
background: @dashieColor;
border-radius: 0.1in;
padding: 0.25em;
position: relative;
transition: background 0.5s;
width: 7in;
&:hover {
background: darken(@dashieColor, 20%);
}
& > label {
display: inline-block;
margin-bottom: 0;
margin-top: 0.5em;
vertical-align: middle;
width: 0.3in;
}
button {
background: darken(@dashieColor, 20%);
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
input, select {
background: transparent;
color: @fontColor;
}
.labelledUnderlined:nth-of-type(4) {
width: 3.5in;
}
}
}
.traits {
display: inline-block;
vertical-align: middle;
.trait {
background: #aaa;
border-radius: 0.1in;
display: inline-block;
height: 0.6in;
padding: 1em;
position: relative;
transition: background 0.5s;
width: 0.8in;
button {
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
label {
font-size: 2em;
text-align: center;
}
select {
background: transparent;
border: none;
color: @fontColor;
font-size: 1.75em;
left: 50%;
position: absolute;
top: 50%;
transform: translateX(-50%);
width: 0.75in;
}
&.body {
background: @dashieColor;
&:hover {
background: darken(@dashieColor, 10%);
}
}
&.mind {
background: @twilightColor;
&:hover {
background: darken(@twilightColor, 10%);
}
}
&.charm {
background: @flutterColor;
&:hover {
background: darken(@flutterColor, 10%);
}
}
}
}
}
+31
View File
@@ -0,0 +1,31 @@
@tplBorderColor: #7e3fc1;
.rolltemplate-toe {
table {
background: #fff;
border: solid 2px @tplBorderColor;
border-collapse: separate;
border-radius: 1em;
overflow: hidden;
width: 100%;
thead th {
background: @tplBorderColor;
color: #fff;
padding: 0.5em 1em;
}
tbody {
text-align: center;
td {
padding: 0.5em 0;
}
.notes {
font-size: 0.8em;
font-style: italic;
}
}
}
}
+9
View File
@@ -0,0 +1,9 @@
{
"name": "TailsOfEquestria",
"devDependencies": {
"grunt": "^1.0.1",
"grunt-contrib-less": "^1.4.0",
"grunt-contrib-pug": "^1.0.0",
"grunt-string-replace": "^1.3.0"
}
}
+74
View File
@@ -0,0 +1,74 @@
mixin fraction(name)
.fraction
input(type='number', name='attr_' + name)
span /
input(type='number', name='attr_' + name + '_max')
mixin input(type, name)
input(type=type, name='attr_' + name, placeholder=attributes.placeholder, style=attributes.style, value=attributes.value)
mixin labelledAbove(label)
.labelledAbove(style=attributes.style)
label= label
.inner: block
mixin labelledBoxH(label)
.labelledBoxH(class=attributes.class, style=attributes.style)
label= label
.inner: block
mixin labelledBoxV(label)
.labelledBoxV(class=attributes.class, style=attributes.style)
label= label
.inner: block
mixin labelledUnderlined(label)
.labelledUnderlined(style=attributes.style)
label= label
.inner: block
mixin option(view, value, isSelected)
-
if(!value)
value = view;
option(value=value, selected=isSelected)= view
mixin readOnlyBox(name)
.readOnlyBox(style=attributes.style): span(name='attr_' + name)
input(type='hidden', name='attr_' + name)
mixin repeating(name)
fieldset(class='repeating_' + name)
block
mixin rollButton(attr, notes)
-
var tpl = '&{template:toe} {{charName=@{character_name}}} {{attr=' + attr + '}} {{result=[[@{' + attr + '}]]}}';
if(notes)
tpl += '{{notes=@{' + notes + '}}}';
button(type='roll', value=tpl)
mixin select(name)
select(name='attr_' + name, style=attributes.style)
block
mixin selectDice(name)
+select(name)(style=attributes.style)
+option('none', 'null', true)
+option('d4')
+option('d6')
+option('d8')
+option('d10')
+option('d12')
+option('d20')
mixin selectTrait(name)
+select(name)(style=attributes.style)
+option('none', 'null', true)
+option('body')
+option('mind')
+option('charm')
mixin textarea(name)
textarea(name='attr_' + name, style=attributes.style, placeholder=attributes.placeholder)
+104
View File
@@ -0,0 +1,104 @@
include fields.pug
+input('hidden', 'character_sheet')(value='TailsOfEquestria', style='display: none;')
.top
img(src='http://ninjadivision.com/wp-content/uploads/2017/02/MLP-Website-Header-900x325.jpg')
.mask
.main-container
div
.bio
+labelledUnderlined('Pony Name:'): +input('text', 'character_name')
+labelledUnderlined('Player Name:'): +input('text', 'player_name')
+labelledUnderlined('Pony Type:'): +input('text', 'race')
+labelledUnderlined('Level:'): +input('number', 'level')
+labelledUnderlined('Element of Harmony:'): +select('elementOfHarmony')
+option('generosity')
+option('honesty')
+option('kindness')
+option('laughter')
+option('loyalty')
+option('magic')
+option('other')
.friendshipTokens
h1
span F
span R
span I
span E
span N
span D
span S
span H
span I
span P
+input('number', 'friendshipTokens')(value='0')
div
.stamina
h1 Stamina:
+fraction('stamina')
.traits
.trait.body
label Body
+rollButton('body')
+selectDice('body')
.trait.mind
label Mind
+rollButton('mind')
+selectDice('mind')
.trait.charm
label Charm
+rollButton('charm')
+selectDice('charm')
div
.talents
mixin talent(isCutieMark)
- var prefix = isCutieMark ? 'talent_cutieMark_' : '';
.talent(class=isCutieMark ? 'talentCutieMark' : '')
if(isCutieMark)
label CM:
else
label T:
+rollButton(prefix + 'equation', prefix + 'notes')
+labelledUnderlined(''): +input('text', prefix + 'name')
+labelledUnderlined('Dice:'): +selectDice(prefix + 'dice')
+labelledUnderlined('Trait'): +selectTrait(prefix + 'trait')
+labelledUnderlined('Notes:'): +input('text', prefix + 'notes')
+input('hidden', prefix + 'equation')
h1 Talents:
+talent(true)
+repeating('talents')
+talent(false)
div
.quirks
mixin quirk(isMain)
-var prefix = isMain ? 'quirk_main_' : '';
.quirk(class=isMain ? 'quirkMain' : '')
if(isMain)
label Main:
else
label Q:
+labelledUnderlined(''): +input('text', prefix + 'name')
+labelledUnderlined('Notes'): +input('text', prefix + 'notes')
h1 Quirks:
+quirk(true)
+repeating('quirks')
+quirk(false)
div
.inlineBlock(style='margin-right: 1em; vertical-align: top; width: 48%;')
h1 Equipment:
+textarea('equipment')(style='height: 4in;')
.inlineBlock(style='width: 48%;')
h1 Appearance/Cutie Mark:
+textarea('appearance')
h1 Campaign Notes:
+textarea('campaignNotes')
script(type='text/worker')
include ../js/worker.js
include rolltemplate.pug
+10
View File
@@ -0,0 +1,10 @@
rolltemplate.sheet-rolltemplate-toe
table
thead: tr: th {{charName}} ⇒ {{attr}}
tbody
tr: td Result {{result}}
| {{#notes}}
tr: td.notes
div Notes:
div {{notes}}
| {{/notes}}
+442
View File
@@ -0,0 +1,442 @@
.sheet-rolltemplate-toe table {
background: #fff;
border: solid 2px #7e3fc1;
border-collapse: separate;
border-radius: 1em;
overflow: hidden;
width: 100%;
}
.sheet-rolltemplate-toe table thead th {
background: #7e3fc1;
color: #fff;
padding: 0.5em 1em;
}
.sheet-rolltemplate-toe table tbody {
text-align: center;
}
.sheet-rolltemplate-toe table tbody td {
padding: 0.5em 0;
}
.sheet-rolltemplate-toe table tbody .sheet-notes {
font-size: 0.8em;
font-style: italic;
}
.charsheet {
background: #fff;
color: #5e3dba;
width: 8in;
}
.charsheet input {
border: none;
box-shadow: none;
}
.charsheet input[type=number]::-webkit-inner-spin-button, .charsheet input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
.charsheet label {
color: #5e3dba;
}
.charsheet select {
box-shadow: none;
height: auto;
line-height: 18px;
margin-bottom: 0;
-moz-appearance: none;
-webkit-appearance: none;
}
.charsheet textarea {
background: linear-gradient(to bottom, transparent, transparent 17px, #5e3dba);
background-attachment: local;
background-size: 1px 18px;
border: none;
box-shadow: none;
color: #5e3dba;
padding: 0;
resize: none;
}
.charsheet .sheet-labelledAbove {
display: inline-block;
}
.charsheet .sheet-labelledAbove label {
font-size: 0.8em;
margin-bottom: 0;
padding-top: 0.5em;
}
.charsheet .sheet-labelledBoxH {
background: #aaa;
display: inline-block;
overflow: hidden;
}
.charsheet .sheet-labelledBoxH > label {
display: inline;
font-weight: bold;
padding: 0 0.25em;
vertical-align: middle;
}
.charsheet .sheet-labelledBoxH > .sheet-inner {
display: inline-block;
float: right;
vertical-align: middle;
}
.charsheet .sheet-labelledBoxH > .sheet-inner > * {
vertical-align: middle;
}
.charsheet .sheet-labelledBoxH > .sheet-inner .sheet-fraction {
display: inline-block;
}
.charsheet .sheet-labelledBoxH > .sheet-inner .sheet-fraction input {
border: none;
display: inline;
}
.charsheet .sheet-labelledBoxV {
background: #aaa;
display: inline-block;
overflow: hidden;
}
.charsheet .sheet-labelledBoxV > label {
display: inline-block;
font-weight: bold;
margin: 0;
padding: 0;
text-align: center;
}
.charsheet .sheet-labelledBoxV > .sheet-inner {
text-align: center;
width: 100%;
}
.charsheet .sheet-labelledBoxV > .sheet-inner input {
text-align: center;
width: 100%;
}
.charsheet .sheet-labelledBoxV > .sheet-inner .sheet-fraction {
display: inline-block;
}
.charsheet .sheet-labelledBoxV > .sheet-inner .sheet-fraction input {
border: none;
display: inline;
}
.charsheet .sheet-labelledUnderlined {
display: inline-block;
margin-bottom: 1em;
min-width: 0.45in;
position: relative;
}
.charsheet .sheet-labelledUnderlined label {
position: absolute;
font-size: 0.75em;
line-height: 0.75em;
top: 110%;
}
.charsheet .sheet-labelledUnderlined .sheet-inner {
border-bottom: dotted 1px #5e3dba;
width: 100%;
}
.charsheet .sheet-labelledUnderlined .sheet-inner input {
border: none;
border-radius: 0;
padding-bottom: 0;
width: 100%;
}
.charsheet .sheet-labelledUnderlined .sheet-inner select {
border: none;
border-radius: 0;
padding-bottom: 0;
width: 100%;
}
.charsheet .sheet-labelledUnderlined .sheet-inner .sheet-readOnlyBox {
padding: 0;
padding-top: initial;
width: 100%;
}
.charsheet .sheet-mathOperator {
display: inline-block;
margin-bottom: 0.5em;
padding-left: 0.25em;
padding-right: 0.25em;
}
.charsheet .sheet-readOnlyBox {
background: #ddd;
display: inline-block;
padding: 4px;
width: 3.5em;
}
.charsheet .sheet-main-container {
border: solid 5px #ea60e1;
border-radius: 0.25in;
padding: 1em;
position: relative;
}
.charsheet .sheet-main-container > div {
margin-bottom: 0.2in;
}
.charsheet .sheet-main-container .sheet-bio {
background: #DECFE1;
border-radius: 0.1in;
display: inline-block;
padding: 1em;
width: 5in;
}
.charsheet .sheet-main-container .sheet-bio .sheet-labelledUnderlined {
display: block;
font-size: 2em;
margin-bottom: 0.5em;
width: 100%;
}
.charsheet .sheet-main-container .sheet-bio .sheet-labelledUnderlined label {
display: inline-block;
line-height: 1em;
margin: 0;
position: relative;
text-align: right;
width: 1.5in;
}
.charsheet .sheet-main-container .sheet-bio .sheet-labelledUnderlined .sheet-inner {
display: inline-block;
width: auto;
}
.charsheet .sheet-main-container .sheet-bio .sheet-labelledUnderlined .sheet-inner input, .charsheet .sheet-main-container .sheet-bio .sheet-labelledUnderlined .sheet-inner select {
background: transparent;
color: #5e3dba;
font-size: 0.7em;
padding: 0;
width: 3in;
}
.charsheet .sheet-main-container .sheet-friendshipTokens {
background: #f226e4;
border-radius: 0.75in;
display: inline-block;
height: 1.5in;
position: absolute;
right: 1em;
top: 1em;
width: 1.5in;
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 {
color: #fff;
font-size: 1.75em;
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span {
height: 100%;
position: absolute;
text-align: center;
transform-origin: center;
width: 100%;
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(1) {
transform: rotate(-63deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(2) {
transform: rotate(-49deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(3) {
transform: rotate(-35deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(4) {
transform: rotate(-21deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(5) {
transform: rotate(-7deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(6) {
transform: rotate(7deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(7) {
transform: rotate(21deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(8) {
transform: rotate(35deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(9) {
transform: rotate(49deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens h1 span:nth-of-type(10) {
transform: rotate(63deg);
}
.charsheet .sheet-main-container .sheet-friendshipTokens input {
background: transparent;
color: #fff;
font-size: 5em;
left: 50%;
position: absolute;
text-align: center;
top: 50%;
transform: translate(-50%, -50%);
}
.charsheet .sheet-main-container .sheet-quirks {
background: #DECFE1;
border-radius: 0.1in;
padding: 1em;
}
.charsheet .sheet-main-container .sheet-quirks h1 {
color: #5e3dba;
font-size: 2em;
}
.charsheet .sheet-main-container .sheet-quirks .sheet-quirk > label {
display: inline-block;
margin-bottom: 0;
margin-top: 0.25em;
vertical-align: middle;
width: 0.3in;
}
.charsheet .sheet-main-container .sheet-quirks .sheet-quirk input {
background: transparent;
}
.charsheet .sheet-main-container .sheet-quirks .sheet-quirk .sheet-labelledUnderlined:nth-of-type(2) {
width: 4.5in;
}
.charsheet .sheet-main-container .sheet-stamina {
background: #F9B6DD;
border-radius: 0.1in;
display: inline-block;
padding: 1em;
vertical-align: middle;
}
.charsheet .sheet-main-container .sheet-stamina h1 {
color: #5e3dba;
display: inline-block;
font-size: 2em;
vertical-align: middle;
}
.charsheet .sheet-main-container .sheet-stamina .sheet-fraction {
display: inline-block;
}
.charsheet .sheet-main-container .sheet-stamina .sheet-fraction input {
background: transparent;
border-bottom: dotted 1px #5e3dba;
color: #5e3dba;
font-size: 2em;
padding: 0;
text-align: center;
width: 2em;
}
.charsheet .sheet-main-container .sheet-talents {
background: #B3E7EF;
border-radius: 0.1in;
padding: 1em;
}
.charsheet .sheet-main-container .sheet-talents h1 {
color: #5e3dba;
font-size: 2em;
}
.charsheet .sheet-main-container .sheet-talents .sheet-talent {
background: #B3E7EF;
border-radius: 0.1in;
padding: 0.25em;
position: relative;
transition: background 0.5s;
width: 7in;
}
.charsheet .sheet-main-container .sheet-talents .sheet-talent:hover {
background: #5fccdd;
}
.charsheet .sheet-main-container .sheet-talents .sheet-talent > label {
display: inline-block;
margin-bottom: 0;
margin-top: 0.5em;
vertical-align: middle;
width: 0.3in;
}
.charsheet .sheet-main-container .sheet-talents .sheet-talent button {
background: #5fccdd;
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
.charsheet .sheet-main-container .sheet-talents .sheet-talent input, .charsheet .sheet-main-container .sheet-talents .sheet-talent select {
background: transparent;
color: #5e3dba;
}
.charsheet .sheet-main-container .sheet-talents .sheet-talent .sheet-labelledUnderlined:nth-of-type(4) {
width: 3.5in;
}
.charsheet .sheet-main-container .sheet-traits {
display: inline-block;
vertical-align: middle;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait {
background: #aaa;
border-radius: 0.1in;
display: inline-block;
height: 0.6in;
padding: 1em;
position: relative;
transition: background 0.5s;
width: 0.8in;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait button {
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait label {
font-size: 2em;
text-align: center;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait select {
background: transparent;
border: none;
color: #5e3dba;
font-size: 1.75em;
left: 50%;
position: absolute;
top: 50%;
transform: translateX(-50%);
width: 0.75in;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait.sheet-body {
background: #B3E7EF;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait.sheet-body:hover {
background: #89dae6;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait.sheet-mind {
background: #DECFE1;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait.sheet-mind:hover {
background: #c8b0cd;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait.sheet-charm {
background: #FAD1E4;
}
.charsheet .sheet-main-container .sheet-traits .sheet-trait.sheet-charm:hover {
background: #f5a3c9;
}
.charsheet h1 {
color: #5e3dba;
}
.charsheet .sheet-centeredH {
text-align: center;
}
.charsheet .sheet-centeredV > * {
vertical-align: middle;
}
.charsheet .sheet-floatLeft {
float: left;
}
.charsheet .sheet-floatRight {
float: right;
}
.charsheet .sheet-inlineBlock {
display: inline-block;
}
.charsheet .sheet-top {
height: 2.6in;
overflow: hidden;
position: relative;
width: 8in;
}
.charsheet .sheet-top .sheet-mask {
height: 1in;
left: 0;
position: absolute;
top: 1.65in;
width: 100%;
background: linear-gradient(rgba(255, 255, 255, 0), #fff);
}
+366
View File
@@ -0,0 +1,366 @@
<input type="hidden" name="attr_character_sheet" style="display: none;" value="TailsOfEquestria"/>
<div class="top"><img src="http://ninjadivision.com/wp-content/uploads/2017/02/MLP-Website-Header-900x325.jpg"/>
<div class="mask"></div>
</div>
<div class="main-container">
<div>
<div class="bio">
<div class="labelledUnderlined">
<label>Pony Name:</label>
<div class="inner">
<input type="text" name="attr_character_name"/>
</div>
</div>
<div class="labelledUnderlined">
<label>Player Name:</label>
<div class="inner">
<input type="text" name="attr_player_name"/>
</div>
</div>
<div class="labelledUnderlined">
<label>Pony Type:</label>
<div class="inner">
<input type="text" name="attr_race"/>
</div>
</div>
<div class="labelledUnderlined">
<label>Level:</label>
<div class="inner">
<input type="number" name="attr_level"/>
</div>
</div>
<div class="labelledUnderlined">
<label>Element of Harmony:</label>
<div class="inner">
<select name="attr_elementOfHarmony">
<option value="generosity">generosity</option>
<option value="honesty">honesty</option>
<option value="kindness">kindness</option>
<option value="laughter">laughter</option>
<option value="loyalty">loyalty</option>
<option value="magic">magic</option>
<option value="other">other</option>
</select>
</div>
</div>
</div>
<div class="friendshipTokens">
<h1><span>F</span><span>R</span><span>I</span><span>E</span><span>N</span><span>D</span><span>S</span><span>H</span><span>I</span><span>P</span></h1>
<input type="number" name="attr_friendshipTokens" value="0"/>
</div>
</div>
<div>
<div class="stamina">
<h1>Stamina:</h1>
<div class="fraction">
<input type="number" name="attr_stamina"/><span>/</span>
<input type="number" name="attr_stamina_max"/>
</div>
</div>
<div class="traits">
<div class="trait body">
<label>Body</label>
<button type="roll" value="&amp;{template:toe} {{charName=@{character_name}}} {{attr=body}} {{result=[[@{body}]]}}"></button>
<select name="attr_body">
<option value="null" selected="selected">none</option>
<option value="d4">d4</option>
<option value="d6">d6</option>
<option value="d8">d8</option>
<option value="d10">d10</option>
<option value="d12">d12</option>
<option value="d20">d20</option>
</select>
</div>
<div class="trait mind">
<label>Mind</label>
<button type="roll" value="&amp;{template:toe} {{charName=@{character_name}}} {{attr=mind}} {{result=[[@{mind}]]}}"></button>
<select name="attr_mind">
<option value="null" selected="selected">none</option>
<option value="d4">d4</option>
<option value="d6">d6</option>
<option value="d8">d8</option>
<option value="d10">d10</option>
<option value="d12">d12</option>
<option value="d20">d20</option>
</select>
</div>
<div class="trait charm">
<label>Charm</label>
<button type="roll" value="&amp;{template:toe} {{charName=@{character_name}}} {{attr=charm}} {{result=[[@{charm}]]}}"></button>
<select name="attr_charm">
<option value="null" selected="selected">none</option>
<option value="d4">d4</option>
<option value="d6">d6</option>
<option value="d8">d8</option>
<option value="d10">d10</option>
<option value="d12">d12</option>
<option value="d20">d20</option>
</select>
</div>
</div>
</div>
<div>
<div class="talents">
<h1>Talents:</h1>
<div class="talent talentCutieMark">
<label>CM:</label>
<button type="roll" value="&amp;{template:toe} {{charName=@{character_name}}} {{attr=talent_cutieMark_equation}} {{result=[[@{talent_cutieMark_equation}]]}}{{notes=@{talent_cutieMark_notes}}}"></button>
<div class="labelledUnderlined">
<label></label>
<div class="inner">
<input type="text" name="attr_talent_cutieMark_name"/>
</div>
</div>
<div class="labelledUnderlined">
<label>Dice:</label>
<div class="inner">
<select name="attr_talent_cutieMark_dice">
<option value="null" selected="selected">none</option>
<option value="d4">d4</option>
<option value="d6">d6</option>
<option value="d8">d8</option>
<option value="d10">d10</option>
<option value="d12">d12</option>
<option value="d20">d20</option>
</select>
</div>
</div>
<div class="labelledUnderlined">
<label>Trait</label>
<div class="inner">
<select name="attr_talent_cutieMark_trait">
<option value="null" selected="selected">none</option>
<option value="body">body</option>
<option value="mind">mind</option>
<option value="charm">charm</option>
</select>
</div>
</div>
<div class="labelledUnderlined">
<label>Notes:</label>
<div class="inner">
<input type="text" name="attr_talent_cutieMark_notes"/>
</div>
</div>
<input type="hidden" name="attr_talent_cutieMark_equation"/>
</div>
<fieldset class="repeating_talents">
<div class="talent">
<label>T:</label>
<button type="roll" value="&amp;{template:toe} {{charName=@{character_name}}} {{attr=equation}} {{result=[[@{equation}]]}}{{notes=@{notes}}}"></button>
<div class="labelledUnderlined">
<label></label>
<div class="inner">
<input type="text" name="attr_name"/>
</div>
</div>
<div class="labelledUnderlined">
<label>Dice:</label>
<div class="inner">
<select name="attr_dice">
<option value="null" selected="selected">none</option>
<option value="d4">d4</option>
<option value="d6">d6</option>
<option value="d8">d8</option>
<option value="d10">d10</option>
<option value="d12">d12</option>
<option value="d20">d20</option>
</select>
</div>
</div>
<div class="labelledUnderlined">
<label>Trait</label>
<div class="inner">
<select name="attr_trait">
<option value="null" selected="selected">none</option>
<option value="body">body</option>
<option value="mind">mind</option>
<option value="charm">charm</option>
</select>
</div>
</div>
<div class="labelledUnderlined">
<label>Notes:</label>
<div class="inner">
<input type="text" name="attr_notes"/>
</div>
</div>
<input type="hidden" name="attr_equation"/>
</div>
</fieldset>
</div>
</div>
<div>
<div class="quirks">
<h1>Quirks:</h1>
<div class="quirk quirkMain">
<label>Main:</label>
<div class="labelledUnderlined">
<label></label>
<div class="inner">
<input type="text" name="attr_quirk_main_name"/>
</div>
</div>
<div class="labelledUnderlined">
<label>Notes</label>
<div class="inner">
<input type="text" name="attr_quirk_main_notes"/>
</div>
</div>
</div>
<fieldset class="repeating_quirks">
<div class="quirk">
<label>Q:</label>
<div class="labelledUnderlined">
<label></label>
<div class="inner">
<input type="text" name="attr_name"/>
</div>
</div>
<div class="labelledUnderlined">
<label>Notes</label>
<div class="inner">
<input type="text" name="attr_notes"/>
</div>
</div>
</div>
</fieldset>
</div>
</div>
<div>
<div class="inlineBlock" style="margin-right: 1em; vertical-align: top; width: 48%;">
<h1>Equipment:</h1>
<textarea name="attr_equipment" style="height: 4in;"></textarea>
</div>
<div class="inlineBlock" style="width: 48%;">
<h1>Appearance/Cutie Mark:</h1>
<textarea name="attr_appearance"></textarea>
<h1>Campaign Notes:</h1>
<textarea name="attr_campaignNotes"></textarea>
</div>
</div>
</div>
<script type="text/worker">/**
* Forces an update on a list of numerical fields, also making sure that
* any undefined fields are set to 0.
* @param {string[]} attrs
* @param {function} cb
*/
function forceUpdate(attrs, cb) {
parseAttrs(attrs, values => {
let tempValues = {};
_.each(attrs, attr => {
tempValues[attr] = -9999;
});
setAttrs(tempValues);
setAttrs(values);
});
}
function onChange(attrs, cb) {
attrs = _.map(attrs, attr => {
return 'change:' + attr;
}).join(' ');
on(attrs, cb);
}
function onChangeParse(attrs, cb) {
onChange(attrs, () => {
parseAttrs(attrs, cb);
});
}
/**
* Gets the specified attributes and parses them as an integer or 0.
*/
function parseAttrs(attrs, cb) {
getAttrs(attrs, function(values) {
_.each(attrs, function(attr) {
if(_.isUndefined(values[attr]))
values[attr] = 0;
else if(!isNaN(values[attr]))
values[attr] = parseInt(values[attr]);
});
cb(values);
});
}
function updateCutieMarkTalent() {
var prefix = 'talent_cutieMark';
_updateTalents(prefix);
}
function updateTalents() {
updateCutieMarkTalent();
getSectionIDs('repeating_talents', ids => {
_.each(ids, id => {
var prefix = 'repeating_talents_' + id;
_updateTalents(prefix);
});
});
}
function _updateTalents(prefix) {
parseAttrs([prefix + '_dice', prefix + '_trait', 'body', 'mind', 'charm'], values => {
var talentDice = values[prefix + '_dice'];
var trait = values[prefix + '_trait'];
var traitDice = values[trait];
if(talentDice === 'null' || !traitDice)
setAttrs({
[prefix + '_equation']: 0
});
else {
var traitDice = values[trait];
setAttrs({
[prefix + '_equation']: talentDice + ' + ' + traitDice
});
}
});
}
// Change events
on('change:repeating_talents', evt => {
updateTalents();
});
onChange(['talent_cutieMark_dice', 'talent_cutieMark_trait'], () => {
updateCutieMarkTalent();
});
onChange(['body', 'mind', 'charm'], () => {
updateTalents();
});
on('sheet:opened', () => {
setAttrs({
character_sheet: 'TailsOfEquestria v1.0.0'
});
updateTalents();
});
</script>
<rolltemplate class="sheet-rolltemplate-toe">
<table>
<thead>
<tr>
<th>{{charName}} &#x21D2; {{attr}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>Result {{result}}</td>
</tr>{{#notes}}
<tr>
<td class="notes">
<div>Notes:</div>
<div>{{notes}}</div>
</td>
</tr>{{/notes}}
</tbody>
</table>
</rolltemplate>
+8
View File
@@ -0,0 +1,8 @@
{
"html": "sheet.html",
"css": "sheet.css",
"authors": "Stephen Lindberg",
"preview": "sheet.png",
"roll20userid": "46544",
"instructions": "This character sheet is for Tails of Equestria, the officially licensed My Little Pony: Friendship is Magic roleplaying game."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB