update CDMG sheets to add randomization for easier character creation

This commit is contained in:
Patrick Schroeder
2021-07-17 21:45:52 -05:00
parent 67a40d62e3
commit 402ebaf3b9
2 changed files with 801 additions and 91 deletions
+126 -40
View File
@@ -1,24 +1,42 @@
@import url('https://fonts.googleapis.com/css?family=Passion+One:wght@300&display=swap');
button[type=roll].sheet-stat-roll::before {
background-image: none;
font-family: dicefontd6;
content: "l";
color: #3f0f12;
}
.sheet-collateral-damage {
.collateral-damage {
font-family: Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
font-size: 14px;
font-weight: bold;
min-width: 500px; /* TODO: Figure out if there is a better value for this */
}
.sheet-collateral-damage .sheet-row-padding {
.collateral-damage button[type=roll].stat-roll::before {
background-image: none;
font-family: dicefontd6;
content: "F";
color: #3f0f12;
}
.collateral-damage .row-padding {
padding-top:5px;
}
.sheet-collateral-damage .sheet-section-act-heading {
.collateral-damage select {
width: 100%;
font-family: 'Passion One', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
text-transform: uppercase;
margin-bottom: 0px;
}
.collateral-damage .section {
padding: 5px;
}
.collateral-damage .randomize-button {
font-family: 'Passion One', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
font-size: 13px;
font-weight: normal;
line-height: 18px;
}
.collateral-damage .section-act-heading {
font-family: 'Passion One', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
text-transform: uppercase;
font-weight: 300;
@@ -30,18 +48,7 @@ button[type=roll].sheet-stat-roll::before {
border-width: 2px;
}
.sheet-collateral-damage .sheet-stat-content {
display: inline-block;
vertical-align: middle;
text-align: center;
width: 45px;
}
.sheet-collateral-damage .sheet-section {
padding: 5px;
}
.sheet-collateral-damage .sheet-section-heading {
.collateral-damage .section-heading {
font-family: 'Passion One', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
text-transform: uppercase;
font-weight: 300;
@@ -51,14 +58,21 @@ button[type=roll].sheet-stat-roll::before {
background-color: #eeb8bb;
}
.sheet-collateral-damage .sheet-section-content {
.collateral-damage .section-content {
border-left: solid #3f0f12;
border-top: solid #3f0f12;
border-width: 2px;
padding: 5px;
}
.sheet-collateral-damage .sheet-input-label-header {
.collateral-damage .stat-content {
display: inline-block;
vertical-align: middle;
text-align: center;
width: 45px;
}
.collateral-damage .input-label-header {
font-family: 'Passion One', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
text-transform: uppercase;
font-weight: 300;
@@ -69,7 +83,7 @@ button[type=roll].sheet-stat-roll::before {
text-align: left;
}
.sheet-collateral-damage .sheet-input-label {
.collateral-damage .input-label {
color: #3f0f12;
border-top: solid #3f0f12;
border-width: 1px;
@@ -77,19 +91,19 @@ button[type=roll].sheet-stat-roll::before {
text-align: left;
}
.sheet-collateral-damage .sheet-center-text {
.collateral-damage .center-text {
text-align: center;
}
/* Customizes the inputs to use bold font */
.sheet-collateral-damage input[type=text] {
.collateral-damage input[type=text] {
width: 100%;
font-size: 14px;
font-family: 'Passion One', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
text-transform: uppercase;
font-weight: 300;
}
.sheet-collateral-damage textarea {
.collateral-damage textarea {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
@@ -103,20 +117,22 @@ button[type=roll].sheet-stat-roll::before {
}
/* Used to build out + or - in stat table */
.sheet-collateral-damage .sheet-stat-content label {
.collateral-damage .stat-content label {
text-align: center;
}
.sheet-collateral-damage .sheet-stat-content label span:before {
.collateral-damage .stat-content label span:before {
content: "+";
font-size: 25px;
cursor: pointer;
}
.sheet-collateral-damage .sheet-stat-content label input[type=checkbox]:checked + span:before {
.collateral-damage .stat-content label input[type=checkbox]:checked + span:before {
content: "-";
font-size: 25px;
cursor: pointer;
}
/* Used to build the stat dice table */
.sheet-collateral-damage .sheet-stats-dice-header {
.collateral-damage .stats-dice-header {
font-family: 'Passion One', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
text-transform: uppercase;
font-weight: 300;
@@ -125,35 +141,105 @@ button[type=roll].sheet-stat-roll::before {
text-align: center;
color: white;
}
.sheet-collateral-damage table {
.collateral-damage table {
width: 100%;
}
.sheet-collateral-damage td {
.collateral-damage td {
text-align: center;
border: 1px solid #3f0f12;
}
/* Used to build out the wound heart toggles */
.sheet-collateral-damage input[type=checkbox] {
.collateral-damage input[type=checkbox] {
display: none;
}
.sheet-collateral-damage label span:before {
.collateral-damage label span:before {
content: url("https://raw.githubusercontent.com/patschroed/roll20-character-sheets/master/CDMG/heart.png");
cursor: pointer;
}
.sheet-collateral-damage label input[type=checkbox]:checked + span:before {
.collateral-damage label input[type=checkbox]:checked + span:before {
content: url("https://raw.githubusercontent.com/patschroed/roll20-character-sheets/master/CDMG/heart-slash.png");
cursor: pointer;
}
.sheet-collateral-damage ul {
.collateral-damage ul {
list-style-type: none;
margin-bottom: 0px;
margin-left: 13px;
}
.sheet-collateral-damage li {
.collateral-damage li {
display: inline-block;
}
.sheet-collateral-damage li label {
.collateral-damage li label {
padding: 0px;
display: inline-block;
}
/* Used to dynamically switch between the different class selections */
.fantasy-class-selector,
.horror-class-selector,
.western-class-selector,
.superhero-class-selector,
.scifi-class-selector {
display: none;
}
.class-toggle[value="fantasy"] ~ div.fantasy-class-selector,
.class-toggle[value="horror"] ~ div.horror-class-selector,
.class-toggle[value="western"] ~ div.western-class-selector,
.class-toggle[value="superhero"] ~ div.superhero-class-selector,
.class-toggle[value="scifi"] ~ div.scifi-class-selector {
display: block;
}
/* Popup content */
.overlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
margin: 70px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
width: 55%;
position: relative;
transition: all 5s ease-in-out;
font-family: 'Passion One', Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif;
font-weight: 300;
font-size: 16px;
}
.popup h2 {
margin-top: 0;
color: rgb(0, 0, 0);
}
.popup .close {
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: rgb(0, 0, 0);
}
.popup .content {
max-height: 30%;
}
/* Using this to pre-load the heart-slash to avoid the flicker */
.collateral-damage::after{
position:absolute; width:0; height:0; overflow:hidden; z-index:-1;
content:url("https://raw.githubusercontent.com/patschroed/roll20-character-sheets/master/CDMG/heart-slash.png")
}
+675 -51
View File
@@ -1,10 +1,10 @@
<div class="collateral-damage">
<!--Logo / Player Name / Movie Title -->
<div class="2colrow">
<div class="col">
<div class="sheet-2colrow">
<div class="sheet-col">
<img src="https://github.com/patschroed/roll20-character-sheets/blob/master/CDMG/cdmg-logo.png?raw=true" />
</div>
<div class="col">
<div class="sheet-col">
<div>
<input type="text" name="attr_name" />
<div class="input-label-header">PLAYER NAME</div>
@@ -13,44 +13,193 @@
<input type="text" name="attr_movie_title" />
<div class="input-label-header">MOVIE TITLE</div>
</div>
<div>
<select name="attr_setting">
<option value="fantasy" selected>fantasy</option>
<option value="horror">horror</option>
<option value="western">western</option>
<option value="superhero">superhero</option>
<option value="scifi">sci-fi</option>
</select>
<div class="input-label-header">MOVIE SETTING</div>
</div>
</div>
</div>
<!--Act summaries-->
<div class="3colrow row-padding">
<div class="col">
<div class="section-act-heading">Act 1 <br> Objectives</div>
<div class="sheet-3colrow row-padding">
<div class="sheet-col">
<div class="section-act-heading">
<div>Act 1 Objectives</div>
<button type="action" class="randomize-button" name="act-random-act1-objective">Randomize</button>
</div>
<textarea name="attr_act_1_objective"></textarea>
</div>
<div class="col">
<div class="section-act-heading">Act 2 <br> Objectives</div>
<div class="sheet-col">
<div class="section-act-heading">
<div>Act 2 Objectives</div>
<button type="action" class="randomize-button" name="act-random-act2-objective">Randomize</button>
</div>
<textarea name="attr_act_2_objective"></textarea>
</div>
<div class="col">
<div class="section-act-heading">Act 3 <br> Objectives</div>
<div class="sheet-col">
<div class="section-act-heading">
<div>Act 3 Objectives</div>
<button type="action" class="randomize-button" name="act-random-act3-objective">Randomize</button>
</div>
<textarea name="attr_act_3_objective"></textarea>
</div>
</div>
<!--Player Info / Stats / Wounds / Relationships -->
<div class="2colrow row-padding">
<div class="col">
<div class="sheet-2colrow row-padding">
<div class="sheet-col">
<div class="section-heading">
PLAYER INFO
<button type="action" class="randomize-button" name="act-randomize-player-info">Randomize</button>
</div>
<div class="section-content">
<!-- Character Name Selection -->
<input type="text" name="attr_character_name" />
<div class="input-label">CHARACTER NAME</div>
<input type="text" name="attr_class" />
<div class="input-label">CLASS</div>
<input type="text" name="attr_mentality" />
<div class="input-label">MENTALITY</div>
<input type="text" name="attr_flaw" />
<div class="input-label">FLAW</div>
<!-- Class Selection -->
<section>
<input type="hidden" class="class-toggle" name="attr_setting" value="fantasy" />
<div class="fantasy-class-selector">
<select name="attr_class">
<option value="shopkeep">Shop Keep</option>
<option value="tavernworker">Tavern Worker</option>
<option value="hireling">Hireling</option>
<option value="streeturchin">Street Urchin</option>
<option value="wizardapprentice">Wizard Apprentice</option>
<option value="doomsayer">doomsayer</option>
<option value="minion">Minion</option>
<option value="monsterousbeast">Monsterous Beast</option>
<option value="nobleperson">Noble Person</option>
</select>
</div>
<div class="horror-class-selector">
<select name="attr_class">
<option value="gasattendant">Gas Attendant</option>
<option value="gothkid">Goth Kid</option>
<option value="localdeputy">Local Deputy</option>
<option value="campcounselor">Camp Counselor</option>
<option value="babysitter">Babysitter</option>
<option value="localhistorian">Local Historian</option>
<option value="firstvictimsparent">First Victim's Parent</option>
<option value="paranormalfanatic">Paranormal Fanatic</option>
<option value="firstvictimsbff">First Victim's BFF</option>
</select>
</div>
<div class="western-class-selector">
<select name="attr_class">
<option value="bartender">Bartender</option>
<option value="pianoplayer">Piano Player</option>
<option value="paintedlady">Painted Lady</option>
<option value="deputy">Deputy</option>
<option value="farmer">Farmer</option>
<option value="pastor">Pastor</option>
<option value="bandit">Bandit</option>
<option value="swindler">Swindler</option>
<option value="townmayor">Town Mayor</option>
</select>
</div>
<div class="superhero-class-selector">
<select name="attr_class">
<option value="newsreporter">News reporter</option>
<option value="streetfoodvendor">Street Food Vender</option>
<option value="beatcop">Beat Cop</option>
<option value="bikemessenger">Bike Messenger</option>
<option value="businessmastermind">Business Mastermind</option>
<option value="henchman">Henchman</option>
<option value="sidekick">Side Kick</option>
<option value="robotminion">Robot Minion</option>
<option value="antimutantactivist">Anti-Mutant Activist</option>
</select>
</div>
<div class="scifi-class-selector">
<select name="attr_class">
<option value="attractivesmuggler">Attractive Smuggler</option>
<option value="helperdroid">Helper Droid</option>
<option value="firstofficer">First Officer</option>
<option value="chiefengineer">Chief Engineer</option>
<option value="redshirt">Red Shirt</option>
<option value="alienriffraff">Alien Riff-Raff</option>
<option value="shipspilot">Ship's Pilor</option>
<option value="sentientplantlife">Sentient Plant Life</option>
<option value="bountyhunter">Bounty Hunter</option>
</select>
</div>
<div class="input-label">CLASS</div>
</section>
<!-- Mentality -->
<section>
<input type="text" name="attr_mentality" />
<div class="input-label">MENTALITY <a href="#mentalityhelppopup">?</a></div>
<div id="mentalityhelppopup" class="overlay">
<div class="popup">
<h2 class="center-text">CHARACTER MENTALITY CHART</h2>
<a class="close" href="#">×</a>
<div class="content">
<table>
<tr>
<td>CHILDISH</td>
<td>Literally, you have the mind of a small child.</td>
</tr>
<tr>
<td>DELUSIONAL</td>
<td>You think youre way cooler/better than you really are.</td>
</tr>
<tr>
<td>CHAOTIC</td>
<td>Chaos and destruction are always on your mind.</td>
</tr>
<tr>
<td>BIZARRE</td>
<td>Your unusual appearance and unexpected outbursts keep many around you on edge.</td>
</tr>
<tr>
<td>FLASHY / FLAMBOYANT</td>
<td>Your presence must always be known. You love attention!</td>
</tr>
<tr>
<td>GREEDY</td>
<td>You want everything for yourself. Sharing is not in your vocabulary.</td>
</tr>
<tr>
<td>ENVIOUS</td>
<td>You want everything everyone else has, and you believe you deserve it.</td>
</tr>
<tr>
<td>PETTY</td>
<td>Every little thing bothers you, and its everyone elses fault!</td>
</tr>
<tr>
<td>AMBITIOUS</td>
<td>You are determined! You will be the best at any and everything you do.</td>
</tr>
<tr>
<td>STUBBORN</td>
<td>Its your way or nothing.</td>
</tr>
</table>
</div>
</div>
</div>
</section>
<!-- Flaw -->
<section>
<input type="text" name="attr_flaw" />
<div class="input-label">FLAW</div>
</section>
</div>
<div class="section-heading">
STATS
<button type="action" class="randomize-button" name="act-randomize-player-stats">Randomize</button>
</div>
<div class="section-content">
<div>
@@ -73,8 +222,7 @@
</div>
<div class="stat-content"> = </div>
<div class="stat-content">
<input type="hidden" name="attr_luck_total_hidden" />
<input class="center-text" type="text" name="attr_luck_total" value="@{luck_total_hidden}" disabled/>
<input class="center-text" type="text" name="attr_luck_total" />
<div class="input-label center-text">TOTAL</div>
</div>
<div class="stat-content">
@@ -107,8 +255,7 @@
</div>
<div class="stat-content"> = </div>
<div class="stat-content">
<input type="hidden" name="attr_vul_total_hidden" />
<input class="center-text" type="text" name="attr_vul_total" value="@{vul_total_hidden}" disabled/>
<input class="center-text" type="text" name="attr_vul_total" />
<div class="input-label center-text">TOTAL</div>
</div>
<div class="stat-content">
@@ -130,7 +277,7 @@
</div>
<div class="stat-content">
<label>
<input name="attr_res_modifier" type="checkbox" value="1"/>
<input name="attr_res_modifier" type="checkbox" value="1" />
<span></span>
</label>
</div>
@@ -140,8 +287,7 @@
</div>
<div class="stat-content"> = </div>
<div class="stat-content">
<input type="hidden" name="attr_res_total_hidden" />
<input class="center-text" type="text" name="attr_res_total" value="@{res_total_hidden}" disabled/>
<input class="center-text" type="text" name="attr_res_total" />
<div class="input-label center-text">TOTAL</div>
</div>
<div class="stat-content">
@@ -174,7 +320,7 @@
</table>
</div>
</div>
<div class="col">
<div class="sheet-col">
<div class="section-heading">
WOUNDS
</div>
@@ -223,7 +369,7 @@
LEFT:
</div>
<div>
<label>YOUR ROLL:</label>
<label>YOUR ROLL: <button type="action" class="randomize-button" name="act-randomize-left-relationship">Randomize</button></label>
<textarea name="attr_left_your"></textarea>
<label>THEIR ROLL:</label>
<textarea name="attr_left_their"></textarea>
@@ -234,7 +380,7 @@
RIGHT:
</div>
<div>
<label>YOUR ROLL:</label>
<label>YOUR ROLL: <button type="action" class="randomize-button" name="act-randomize-right-relationship">Randomize</button></label>
<textarea name="attr_right_your"></textarea>
<label>THEIR ROLL:</label>
<textarea name="attr_right_their"></textarea>
@@ -248,30 +394,508 @@
<!-- Sheetworker scripts -->
<script type="text/worker">
const stats = ["luck", "vul", "res"];
stats.forEach(stat => {
on(`change:${stat}_base change:${stat}_modifier change:${stat}_bonus`, () => {
getAttrs([`${stat}_base`, `${stat}_modifier`, `${stat}_bonus`], values => {
const base = parseInt(values[`${stat}_base`]) || 0;
const mod = parseInt(values[`${stat}_modifier`]) || 0;
const bonus = parseInt(values[`${stat}_bonus`]) || 0;
//Calculate the total
let total;
if(mod) total = base - bonus;
else total = base + bonus;
//Calculate the dice bonus
let dice;
if(total < 5) dice = 1;
else if(total >= 5 && total < 9) dice = 2;
else dice = 3;
setAttrs({
[`${stat}_total_hidden`]: total,
[`${stat}_dice_hidden`]: dice
const SETTING_ATTR = 'setting';
const STATS = ["luck", "vul", "res"];
const PLAYER_INFO_STATS = {
fantasy: [{
class: 'shopkeep',
stats: {
luck: 2,
vul: -1,
res: 0,
}
}, {
class: 'tavernworker',
stats: {
luck: -2,
vul: 0,
res: 2,
}
}, {
class: 'hireling',
stats: {
luck: -2,
vul: 2,
res: 2,
}
}, {
class: 'streeturchin',
stats: {
luck: 0,
vul: 0,
res: 0,
}
}, {
class: 'wizardapprentice',
stats: {
luck: 0,
vul: 2,
res: 0,
}
}, {
class: 'doomsayer',
stats: {
luck: 1,
vul: -1,
res: -1,
}
}, {
class: 'minion',
stats: {
luck: -1,
vul: -1,
res: 1,
}
}, {
class: 'monsterousbeast',
stats: {
luck: 0,
vul: 3,
res: 0,
}
}, {
class: 'nobleperson',
stats: {
luck: 2,
vul: 2,
res: 0,
}
}],
horror: [{
class: 'gasattendant',
stats: {
luck: 0,
vul: 1,
res: -2,
}
}, {
class: 'gothkid',
stats: {
luck: -1,
vul: -2,
res: 0,
}
}, {
class: 'localdeputy',
stats: {
luck: -1,
vul: 2,
res: 2,
}
}, {
class: 'campcounselor',
stats: {
luck: 0,
vul: 0,
res: 3,
}
}, {
class: 'babysitter',
stats: {
luck: 0,
vul: 0,
res: 0,
}
}, {
class: 'localhistorian',
stats: {
luck: 2,
vul: 0,
res: 2,
}
}, {
class: 'firstvictimsparent',
stats: {
luck: 0,
vul: 2,
res: 0,
}
}, {
class: 'paranormalfanatic',
stats: {
luck: -2,
vul: 2,
res: 0,
}
}, {
class: 'firstvictimsbff',
stats: {
luck: -2,
vul: 2,
res: 0,
}
}],
western: [{
class: 'bartender',
stats: {
luck: 2,
vul: -1,
res: 0,
}
}, {
class: 'pianoplayer',
stats: {
luck: 2,
vul: 0,
res: 0,
}
}, {
class: 'paintedlady',
stats: {
luck: 0,
vul: 1,
res: 2,
}
}, {
class: 'deputy',
stats: {
luck: -2,
vul: 0,
res: 0,
}
}, {
class: 'farmer',
stats: {
luck: 0,
vul: -1,
res: 1,
}
}, {
class: 'pastor',
stats: {
luck: 1,
vul: -1,
res: 0,
}
}, {
class: 'bandit',
stats: {
luck: -1,
vul: -1,
res: -1,
}
}, {
class: 'swindler',
stats: {
luck: -2,
vul: 0,
res: 1,
}
}, {
class: 'townmayor',
stats: {
luck: 2,
vul: 2,
res: 0,
}
}],
superhero: [{
class: 'newsreporter',
stats: {
luck: -2,
vul: 2,
res: 0,
}
}, {
class: 'streetfoodvendor',
stats: {
luck: 0,
vul: 2,
res: 0,
}
}, {
class: 'beatcop',
stats: {
luck: -3,
vul: 1,
res: 1,
}
}, {
class: 'bikemessenger',
stats: {
luck: -2,
vul: 0,
res: 1,
}
}, {
class: 'businessmastermind',
stats: {
luck: -2,
vul: 0,
res: 0,
}
}, {
class: 'henchman',
stats: {
luck: -2,
vul: 0,
res: 2,
}
}, {
class: 'sidekick',
stats: {
luck: 0,
vul: 0,
res: 2,
}
}, {
class: 'robotminion',
stats: {
luck: 0,
vul: 3,
res: 1,
}
}, {
class: 'antimutantactivist',
stats: {
luck: 0,
vul: 1,
res: 1,
}
}],
scifi: [{
class: 'attractivesmuggler',
stats: {
luck: 2,
vul: -1,
res: 0,
}
}, {
class: 'helperdroid',
stats: {
luck: -2,
vul: 0,
res: 2,
}
}, {
class: 'firstofficer',
stats: {
luck: -1,
vul: -2,
res: 0,
}
}, {
class: 'chiefengineer',
stats: {
luck: 2,
vul: 0,
res: 0,
}
}, {
class: 'redshirt',
stats: {
luck: -2,
vul: 2,
res: -2,
}
}, {
class: 'alienriffraff',
stats: {
luck: 2,
vul: -2,
res: 0,
}
}, {
class: 'shipspilot',
stats: {
luck: 0,
vul: 0,
res: 2,
}
}, {
class: 'sentientplantlife',
stats: {
luck: 0,
vul: 2,
res: 2,
}
}, {
class: 'bountyhunter',
stats: {
luck: 2,
vul: 0,
res: 2,
}
}],
}
const MENTALITIES = [
'childish',
'delusional',
'chaotic',
'bizarre',
'flashy/flamboyant',
'greedy',
'petty',
'ambitious',
'stubborn',
];
const ACT_OBJECTIVES = [
[
'Get outta there',
'Save another player',
'Don\'t be seen',
'Be on time',
'Put yourself in harm\'s way (without getting hurt)',
'Get to work',
'Don\'t forget to pick up dinner',
'Pick up the kids from school',
'Meet up with an old friend',
'Don\'t take any damage'
],
[
'Disarm/Plant a trap',
'Escape',
'Ruin another player\'s change of completing their Objective',
'Find the bright side of the situation',
'Protect a family/friend/person',
'Gain employment',
'Put yourself in harm\'s way (without getting hurt)',
'Aid the elderly',
'Gain any amount of income',
'Don\'t take more than one point of damage'
],
[
'Ruin another player\'s change of completing their Objective',
'Save the day',
'Have a profitable/positive ending',
'Discover a deep dark secret',
'Put yourself and others in danger',
'Join a side',
'Save your business',
'Be Heroic',
'Sacrifice youself for someone else',
'Take two points of damage (with or without dying)'
],
]
const RELATIONSHIPS_RIGHT = [
'Your PC and this PC are members of a secret organization. Prompt: What is the name of this organization, and what is its purpose?',
'Your PC and this PC are related by blood. Prompt: How are you related?',
'Your PC and this PC used to work together. Prompt: What was the job?',
'Your PC lent something to this PC over a year ago and they have yet to return it. Prompt: What is the item? Why did you lend it to them? How much do you want it back?',
'This PC used to pick on you when you both were younger. Prompt: What did they do to you in school? How badly do you want revenge?',
'Your PC and this PC see each other almost every day, but have never spoken. Prompt: Where do you keep seeing each other, and why haven\'t you talked to each other yet?',
'This PC knows a dark secret about your PC. Prompt: What is the secret? Do you know that they know?',
'This player is your best friend. Prompt: How long have you known each other? Where did you meet?',
'Your PC and this PC were once in a very long and serious romantic relationship. Prompt: Why didn\'t it work out? Do you want them back?',
'Your PC and this PC once got drunk together and had a heart-to-heart. Prompt: What happened? How well do you remember it?'
];
const RELATIONSHIPS_LEFT = [
'Your PC is in love with this PC but has never told them. Prompt: What is it about them that you love?',
'Your PC and this PC openly hate one another. Prompt: Where does your hatred come from?',
'This PC doesnt know who your character is, but your character has a huge crush on them. Prompt: What is it about this character that has your PC so smitten?',
'Your PC and this PC are neighbors! Prompt: What was the feud that soured your neighborly good will toward each other?',
'This PC is clueless to the fact that your character longs for their demise. Prompt: Why do you want their PC to die?',
'When your PC and this PC talk, its like pulling teeth. You just have nothing in common. Prompt: Tell us about the most awkward interaction the two of you have had.',
'Your PC is incredibly envious of this PC, for one reason or another. Prompt: What makes you so jealous?',
'Your PC feels that this PCs character flaw has deeply impacted their life. Prompt: How did they impact your life?',
'Your PC feels that this PC is incredibly annoying, yet you still hang out with them. Prompt: What is it about them that annoys you so much?',
'Your PC is angry with this PC about something. Prompt: Why are you mad? What would cause you to forgive them?'
];
const setRandomActObjective = (act) => {
setAttrs({
[`act_${act+1}_objective`]: ACT_OBJECTIVES[act][Math.floor(Math.random() * ACT_OBJECTIVES[act].length)]
});
};
const rollD6 = () => {
return Math.floor(Math.random() * 6) + 1;
}
STATS.forEach(stat => {
on(`change:${stat}_base change:${stat}_modifier change:${stat}_bonus`, () => {
getAttrs([`${stat}_base`, `${stat}_modifier`, `${stat}_bonus`], values => {
const base = parseInt(values[`${stat}_base`]) || 0;
const mod = parseInt(values[`${stat}_modifier`]) || 0;
const bonus = parseInt(values[`${stat}_bonus`]) || 0;
//Calculate the total
let total;
if(mod) total = base - bonus;
else total = base + bonus;
setAttrs({
[`${stat}_total`]: total,
});
});
});
});
});
STATS.forEach(stat => {
on(`change:${stat}_total`, () => {
getAttrs([`${stat}_total`], values => {
const total = parseInt(values[`${stat}_total`]) || 0;
//Calculate the dice bonus
let dice;
if(total < 5) dice = 1;
else if(total >= 5 && total < 9) dice = 2;
else dice = 3;
setAttrs({
[`${stat}_dice_hidden`]: dice
});
});
});
});
on(`change:class`, (event) => {
getAttrs([SETTING_ATTR], values => {
const setting = values[SETTING_ATTR];
const selectedClass = PLAYER_INFO_STATS[setting].find(settingClass => settingClass.class === event.newValue);
STATS.forEach(stat => {
const statValue = selectedClass.stats[stat]
const negative = statValue < 0;
const modifier = negative ? 1 : 0;
setAttrs({
[`${stat}_bonus`]: negative ? statValue * -1 : statValue,
[`${stat}_modifier`]: modifier,
});
});
});
});
on("clicked:randomize-player-info", () => {
getAttrs([SETTING_ATTR], values => {
const setting = values[SETTING_ATTR];
const selectedClass = PLAYER_INFO_STATS[setting][Math.floor(Math.random() * PLAYER_INFO_STATS[setting].length)];
setAttrs({
['class']: selectedClass.class,
['mentality']: MENTALITIES[Math.floor(Math.random() * 9)],
});
});
});
on("clicked:randomize-player-stats", () => {
STATS.forEach(stat => {
const value = rollD6() + rollD6() + rollD6();
setAttrs({
[`${stat}_base`]: value,
});
});
});
on("clicked:random-act1-objective", () => {
setRandomActObjective(0)
});
on("clicked:random-act2-objective", () => {
setRandomActObjective(1)
});
on("clicked:random-act3-objective", () => {
setRandomActObjective(2)
});
on("clicked:randomize-right-relationship", () => {
setAttrs({
['right_your']: RELATIONSHIPS_RIGHT[Math.floor(Math.random() * RELATIONSHIPS_RIGHT.length)]
});
});
on("clicked:randomize-left-relationship", () => {
setAttrs({
['left_your']: RELATIONSHIPS_LEFT[Math.floor(Math.random() * RELATIONSHIPS_RIGHT.length)]
});
});
</script>