Skip to content

Instantly share code, notes, and snippets.

@aardrian
Last active October 28, 2017 01:31
Show Gist options
  • Save aardrian/c6709d25470d2011af0d33d06bedd039 to your computer and use it in GitHub Desktop.
Save aardrian/c6709d25470d2011af0d33d06bedd039 to your computer and use it in GitHub Desktop.
Vehicle/Drone Sheet JSON
<header>
<h1>Shadowrun&trade; Demo Sheet (JSON-powered)</h1>
</header>
<main>
<div id="Core">
<p>
The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
</p>
</div>
<div id="Magic">
<p>
The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
</p>
</div>
<div id="Cyber">
<p>
The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
</p>
</div>
<div id="VehicleDrone">
<p>
The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
</p>
</div>
<div id="Notes">
<p>
The JSON is probably invalid or the script that parses it is broken. Either way, my fault.
</p>
</div>
</main>
<footer>
<ul>
<li><a href="https://s.codepen.io/aardrian/pen/aLRwBV" target="_top">Static version</a> of this experiment.</li>
<li><a href="https://jsonformatter.curiousconcept.com/">JSON Formatter &amp; Validator</a></li>
<li><a href="https://www.danstools.com/javascript-minify/">JavaScript Minifier</a></li>
</ul>
</footer>
// Verify the JSON is JSON
// https://jsonformatter.curiousconcept.com/
// Minify the JSON for use below
// https://www.cleancss.com/json-minify/
// Minify the HTML node
// https://www.willpeavy.com/minifier/
// Escape the HTML for the JSON
// https://www.freeformatter.com/json-escape.html
var stuff =
'{"title":"Shadowrun","items":[{"card":"Core","type":"","name":"Personal Data","attributes":{"Name / Primary Alias":"Fender / Benjamin Toma","Metatype":"Human","Ethnicity":"Caucasian / Japanese","Age":"24","Sex":"Male","Height":"5&#8242;6&#8243;","Weight":"120# / 54kg","Street Cred":"9","Notoriety":"1","Public Awareness":"1","Karma":"0","Total Karma":"84"}},{"card":"Core","type":"","name":"Attributes","attributes":{"Body":"3","Agility":"3","Reaction":"5","Strength":"3","Willpower":"4","Logic":"3","Intuition":"4","Charisma":"2","Edge":"3","Magic":"4","Essence":"4.04","Initiative":"9+1D6","Matrix Initiative":"9+3D6/4D6","Astral Initiative":"8+2D6","Composure":"6","Judge Intentions":"6","Memory":"7","Lift/Carry":"45kg/30kg","Movement":"Walk 6; Run 12","Physical Limit":"5(6)","Mental Limit":"5","Social Limit":"4"}},{"card":"Core","type":"","name":"Condition Monitor","attributes":{"Overflow":"3"},"Notes":"For every 3 boxes of damage on any one damage track, the character takes a -1 Dice Pool modifier on tests; these modifiers are cumulative within and across damage tracks. See <em>Wound Modifiers<\/em> p.169.","table":"Condition Monitor","row":[{"Track":"Physical","&minus;⅓":"&#9711;","&minus;‌⅔":"&#9711;","&minus;1":"&#9711;","&minus;1⅓":"&#9711;","&minus;‌1⅔":"&#9711;","&minus;2":"&#9711;","&minus;2⅓":"&#9711;","&minus;‌2⅔":"&#9711;","&minus;3":"&#9711;","&minus;3⅓":"&#9711;"},{"Track":"Mental","&minus;⅓":"&#9711;","&minus;‌⅔":"&#9711;","&minus;1":"&#9711;","&minus;1⅓":"&#9711;","&minus;‌1⅔":"&#9711;","&minus;2":"&#9711;","&minus;2⅓":"&#9711;","&minus;‌2⅔":"&#9711;","&minus;3":"&#9711;","&minus;3⅓":"&#9711;"}]},{"card":"Core","type":"","name":"Skills","table":"Skills","row":[{"Name":"Spellcasting","Attribute":"Magic","Rating":"4","Type":"A"},{"Name":"Counterspelling","Attribute":"Magic","Rating":"4","Type":"A"},{"Name":"Pilot Aircraft","Attribute":"Reaction","Rating":"4+2","Type":"A"},{"Name":"Pilot Ground Craft","Attribute":"Reaction","Rating":"4","Type":"A"},{"Name":"Automotive Mechanic","Attribute":"Logic","Rating":"2","Type":"A"},{"Name":"Aeronautics Mechanic","Attribute":"Logic","Rating":"2","Type":"A"},{"Name":"Gunnery","Attribute":"Agility","Rating":"3","Type":"A"},{"Name":"Hardware","Attribute":"Logic","Rating":"3","Type":"A"},{"Name":"Computer","Attribute":"Logic","Rating":"2","Type":"A"},{"Name":"Electronic Warfare","Attribute":"Logic","Rating":"2","Type":"A"},{"Name":"Cybercombat","Attribute":"Logic","Rating":"1","Type":"A"},{"Name":"Perception","Attribute":"Intuition","Rating":"2","Type":"A"},{"Name":"Automatics","Attribute":"Agility","Rating":"2","Type":"A"},{"Name":"Sneaking","Attribute":"Agility","Rating":"1","Type":"A"},{"Name":"Pilot Watercraft","Attribute":"Reaction","Rating":"2","Type":"A"},{"Name":"Etiquette","Attribute":"Charisma","Rating":"1","Type":"A"},{"Name":"Assensing","Attribute":"Intuition","Rating":"1","Type":"A"},{"Name":"Demolitions","Attribute":"Logic","Rating":"1","Type":"A"},{"Name":"Drone Designs (Academic)","Attribute":"Logic","Rating":"4","Type":"K"},{"Name":"Law Enforcement Tactics (Street)","Attribute":"Intuition","Rating":"1","Type":"K"},{"Name":"Runner Hangouts (Street)","Attribute":"Intuition","Rating":"1","Type":"K"},{"Name":"Gang Identication (Street)","Attribute":"Intuition","Rating":"1","Type":"K"},{"Name":"Mechanics (Street)","Attribute":"Intuition","Rating":"3","Type":"K"},{"Name":"Smuggling Routes (Street)","Attribute":"Intuition","Rating":"2","Type":"K"},{"Name":"Local Knowledge (Street)","Attribute":"Intuition","Rating":"1","Type":"K"},{"Name":"Vehicle Identification (Academic)","Attribute":"Logic","Rating":"1","Type":"K"},{"Name":"Korean","Attribute":"","Rating":"1","Type":"K"},{"Name":"Spanish","Attribute":"","Rating":"1","Type":"K"},{"Name":"Japanese","Attribute":"","Rating":"3","Type":"K"},{"Name":"English","Attribute":"","Rating":"N","Type":"K"}]},{"card":"Core","type":"","name":"ID / Lifestyle / Currency","attributes":{"Primary Lifestyle":"Middle, 7 months pre-paid.","Nuyen":"139,050.66 ¥","Licenses":"Gun ×3, Magic ×3, Drive ×6"},"HTML":"<ul><li>Ben Toma: SIN 4, SMG License 4, Magic License 4, Drivers 4, Drone 4<\/li><li>James Itoh: SIN 4, SMG License 4, Magic License 4, Drivers 4, Drone 4, SAG<\/li><li>Harold Kanagawa: SIN 4, SMG License 4, Magic License 4, Drivers 4, Drone 4<\/li><li>Jon Hikaru: SIN 6, SMG License 6, Magic License 6, Drivers 6, Drone 6<\/ul>"},{"card":"Core","type":"","name":"Armor","table":"Armor","row":[{"Armor":"Armor Jacket: Fire 6, Chemical 4","Rating":"12","Notes":"Shock Frills, p.438"},{"Armor":"Armor Clothing: Non-conductive 6","Rating":"6","Notes":""},{"Armor":"Formfitting: Non-conductive 6","Rating":"8","Notes":""},{"Armor":"Helmet","Rating":"+2","Notes":""}]},{"card":"Core","type":"","name":"Ranged Weapons","table":"Ranged Weapons","row":[{"Weapon":"Ingram Smartgun X","Dam":"8P","Acc":"4(6)","AP":"—","Mode":"BF/FA","RC":"2","Ammo":"32(c)"}]},{"card":"Core","type":"","name":"Melee Weapons","table":"Melee Weapons","row":[{"Weapon":"Survival Knife","Reach":"—","Dam":"(Str+2)P","Acc":"5","AP":"-1"}]},{"card":"Core","type":"","name":"Qualities","table":"Qualities","row":[{"Quality":"Burnout’s Way","Notes":"Treat augmentation as Alphaware for Essence drain. SG.177","Type":"P"},{"Quality":"Focused Concentration","Notes":"Rating 3: Sustain a Force 3 spell without a -2 penalty. p.74","Type":"P"},{"Quality":"Allergy: Mild: Seafood","Notes":"-2 to physical tests while affected. p.78","Type":"N"},{"Quality":"Insomnia","Notes":"Int + Will (4) to recover Stun at normal rate, otherwise at 2× rate. p.81","Type":"N"},{"Quality":"Spirit Bane: Fire","Notes":"May not obey a party member; will attack me first. p.85","Type":"N"}]},{"card":"Core","type":"","name":"Contacts","table":"Contacts","row":[{"Type":"Fixer","Name":"‘Rerun’ Gibson (LA)","Loyalty":"1","Connection":"3","Favor":""},{"Type":"Smuggler","Name":"Addonis, The (LA)","Loyalty":"1","Connection":"3","Favor":""},{"Type":"Mechanic","Name":"Cathy ‘Crybaby’ Monroe (LA)","Loyalty":"3","Connection":"2","Favor":""},{"Type":"Fixer","Name":"Ganeff (LA)","Loyalty":"2","Connection":"4","Favor":""},{"Type":"Smuggler","Name":"DC (Double-Clutch) (Seattle)","Loyalty":"1","Connection":"3","Favor":""},{"Type":"Madame","Name":"June (LA)","Loyalty":"0","Connection":"","Favor":"2,000¥ credit"},{"Type":"Rigger","Name":"Wheels (LA?)","Loyalty":"1","Connection":"1","Favor":""},{"Type":"Fixer","Name":"Kaz (LA)","Loyalty":"5","Connection":"4","Favor":""}]},{"card":"Core","type":"","name":"Gear","HTML":"<ul><li>Commlink: Transys Avalon 6: biometric reader, sub-vocal mic. Rating 6<\/li><li>Glasses: low-light, vision mag, image link, SmartLink Rating 4<\/li><li>Ear buds: audio enhancement 3 Rating 3<\/li><li>Jammer, area Rating 4<\/li><li>Jammer, directional Rating 6<\/li><li>White noise generator Rating 6<\/li><li>Repair shop Rating 3<\/li><li>Respirator Rating 6<\/li><li>Spell Focus: Spellcasting: Manipulation. p.320 Rating 2<\/li><li>Medkit Rating 6<\/li><li>Qi focus: 1951 Nash \u201CCountry Club\u201D 2-door hardtop, chest, licensed (\u00D72) Rating 2<\/li><li>MagLock Passkey Rating 4<\/li><li>Sequencer Rating 6<\/li><li>Flashlight, Toolkit<\/li><li>Tag Eraser<\/li><li>Metal Restraints<\/li><li>Rope (50m), Survival Kit (van)<\/li><li>Rubber bullets (2 boxes, 200 rounds)<\/li><li>Cheap suit<\/li><li>Scuba gear + belt of 4 tanks<\/li><li>200 rounds regular ammo for Ingram Smartgun X<\/li><\/ul>"},{"card":"Magic","type":"","name":"Spells","Notes":"Hermetic: Logic + Willpower to resist Drain.","table":"Spells","row":[{"Spell":"Stunbolt (Combat, p.284): Stun damage.","Type":"M","Range":"LoS","Duration":"I","Drain":"F-3"},{"Spell":"Levitate (Manip, p.293): Target # = Mass/200kg.","Type":"P","Range":"LoS","Duration":"S","Drain":"F-2"},{"Spell":"Deflection (Manip, SG.115): Bonus to dice pool.","Type":"P","Range":"LoS","Duration":"S","Drain":"F-1"},{"Spell":"Fix (Manip, SG.116): Force × Hits in Kg.","Type":"P","Range":"T","Duration":"P","Drain":"F"},{"Spell":"Physical Barrier (Manip, p.294): Armor/Structure=hits.","Type":"P","Range":"LoS","Duration":"S","Drain":"F-1"},{"Spell":"Mana Barrier (Manip, p.294): Barrier rating = hits.","Type":"M","Range":"LoS","Duration":"S","Drain":"F-2"},{"Spell":"Influence (Manip, p.293): 1 command, minutes=hits.","Type":"P","Range":"LoS","Duration":"P","Drain":"F-1"},{"Spell":"Improved Invisibility (Illusion, p.291): Affects tech.","Type":"P","Range":"LoS","Duration":"S","Drain":"F-1"}]},{"card":"Magic","type":"","name":"Adept Powers","table":"Adept Powers","row":[{"Name":"Metabolic Control","Notes":"Takes 3 hrs instead of 1 for fatigue / sleep deprivation damage. SG.172","Rating":"—"},{"Name":"Hang Time","Notes":"+2 to climb; stick to wall for 10 minutes. SG.171","Rating":"2"},{"Name":"Astral Perception","Notes":"Dual-natured when used. p.309","Rating":"—"},{"Name":"Spell Resistance","Notes":"+2 to resistance tests. p.311","Rating":"2"},{"Name":"Improved Ability","Notes":"Pilot Aircraft: +2 to skill. p.309","Rating":"2"},{"Name":"Improved Potential","Notes":"Raise physical limit by 1 (Qi focus ×2, 1951 Nash ‘Country Club’ 2-door hardtop, chest, licensed)","Rating":"2"}]},{"card":"Cyber","type":"","name":"Augmentation","table":"Augmentation","row":[{"Augmentation":"Control Rig","Rating":"2","Notes":"Add rating to vehicle tests, Speed, Handling, reduce threshold for tests, built-in sim, p.452","Essence":"1.6"},{"Augmentation":"Damage Compensator","Rating":"2","Notes":"Ignore 2 boxes of damage for modifiers, p.460","Essence":"0.16"},{"Augmentation":"Hand","Rating":"","Notes":"Capacity 4, obvious","Essence":"0.2"},{"Augmentation":"• Commlink","Rating":"","Notes":"Takes up 2 in hand","Essence":"—"},{"Augmentation":"• Fingertip Compartment ×2","Rating":"","Notes":"Takes up 1 in hand each, 1 holds microdrone","Essence":""}]},{"card":"Cyber","type":"Deck","name":"Proteus Poseidon RCC","attributes":{"Rating":"5","Processing":"5","Firewall":"6","Noise Reduc":"4*","Sharing":"1*"},"Boxes":11,"Notes":"Matrix Condition Monitor: 8 + (Device Rating / 2) = 11 (p.228). Resist with Device Rating + Firewall = 11. p.267. RCC can handle up to 15 slaved drones (Device Rating × 3) (p.267). *Noise Reduction & Sharing combined cannot exceed device Device Rating (p.267). ","table":"Condition Monitor","HTML":"<ul><li>Mapsofts: LA (6), Las Vegas (6), Hong Kong (6)<\/li><li>Common: Encryption (+1 to Firewall)<\/li><li>Common: Signal Scrub (Noise Reduction 2)<\/li><li>Hacking: Armor (+2 to resist damage)<\/li><li>Hacking: Guard (reduce damage 1DV/Mark)<\/li><li>Hacking: Shell (+1 resist damage, stacks)<\/li><li>Hacking: Sneak (+2 resist Trace User)<\/li><li>Hacking: Wrapper (override Matrix icons)<\/li><\/ul>"},{"card":"VehicleDrone","type":"Vehicle (in LA)","name":"GMC Bulldog","attributes":{"Handling":"3/3","Acceleration":"2","Speed":"3","Pilot":"1","Body":"16","Armor":"15","Sensor":"4","Anti-theft":"3","ECM":"4","Seats":"9"},"Boxes":20,"Notes":"Condition Monitor: 12 + (Bod/2) = 20. p.463. Rigger control, tinted windows, medkit (5), toolkit, smuggling compartment, chameleon skin, concealed turret, Gridlink override, drone racks: micro, medium ×3 (1 landing).","table":"Armament","row":[{"Weapon":"AK-97","Dam":"10P","Acc":"5","AP":"−2","Mode":"SA/BF/FA","RC":"—","Ammo":"38(c)"}],"HTML":"<ul> <li>Morphing license plates, complex action to change, R5.152<\/li><li>Spoof chip, R5.152<\/li><li>Run-flat tires, continue to work if punctured, R5.153<\/li><li>Power-train (14 slots remain) <ul> <li>Acceleration Enhancement 1 (4 slots), R5.154<\/li><li>Rigger cocoon (2 slots), Armor 12, Structure 8, +6 resist, R5.156<\/li><\/ul> <\/li><li>Protection (4 slots remain) <ul> <li>Anti-theft system 3 (4 slots), Lockdown, Shock 9S(e), R5.159<\/li><li>Armor, concealed 3 (12 slots), Perception (4) to notice, R5.159<\/li><\/ul> <\/li><li>Weapons (1 slot remains) <ul> <li>Drone rack: micro, landing (2 slots), holds 10 minidrones, R5.160<\/li><li>Drone rack: medium, x2 (6 slots), total of two medium, R5.160<\/li><li>Drone rack: medium, landing (8 slots), 1 medium, complex action, R5.160<\/li><li>Mount: standard, concealed, turret, remote (+4 slots), R5.163<\/li><li>Gun ports: x3 (3 slots), 4 point recoil compensation harness, R5.160<\/li><\/ul> <\/li><li>Body (13 slots remain) <ul> <li>Chameleon coating (2 slots), simple action to change, R5.163<\/li><li>Smuggling compartment (3 slots), 10-20% vehicle size, R5.165<\/li><li>Increased seating (1 slot), R5.164<\/li><li>Fridge (1 slot), as Special Equipment for 500\u00A5, R5.165<\/li><\/ul> <\/li><li>Electronics (5 slots remain) <ul> <li>ECM 4 (2 slots), as Area Jammer, R5.166<\/li><li>GridLink override (1 slot), presents as normal to GridLink, R5.167<\/li><li>Sensor Upgrade 4 (12 slots), R5.168<\/li><\/ul> <\/li><\/ul>"},{"card":"VehicleDrone","type":"Drone (in LA)","name":"GM-Nissan Doberman","attributes":{"Handling":"5","Acceleration":"1","Speed":"3","Pilot":"1","Body":"4","Armor":"4","Sensor":"3"},"Boxes":8,"Notes":"Condition Monitor: 6 + (Bod/2) = 8. p.466, Medium drone. External flexible weapon mount. Clearsight (from RCC) 3, Doberman Stealth 3, Doberman Maneuvering 3, AK-97 Targeting 3, Recoil comp = Body (4).","table":"Armament","row":[{"Weapon":"AK-97","Dam":"10P","Acc":"5","AP":"−2","Mode":"SA/BF/FA","RC":"—","Ammo":"38(c)"}]},{"card":"VehicleDrone","type":"Drone","name":"MCT-Nissan Roto-drone","attributes":{"Handling":"4","Acceleration":"4","Speed":"3","Pilot":"3","Body":"4","Armor":"4","Sensor":"3"},"Boxes":8,"Notes":"Condition Monitor: 6 + (Bod/2) = 8. p.466, Medium roto-drone ×2. Light fixed external weapon mount. Clearsight (from RCC) 3, Roto-Drone Stealth 3, RD Maneuvering 3, Ingram Smartgun Targeting 3, Recoil comp = Body (4).","table":"Armament","row":[{"Weapon":"Ingram Smartgun X","Dam":"8P","Acc":"4(6)","AP":"—","Mode":"BF/FA","RC":"2","Ammo":"32(c)"}]},{"card":"VehicleDrone","type":"Drone","name":"MCT Fly-spy","attributes":{"Handling":"4","Acceleration":"2","Speed":"3","Pilot":"3","Body":"1","Armor":"0","Sensor":"3"},"Boxes":7,"Notes":"Condition Monitor: 6 + (Bod/2) = 7. p.466, Minidrone. Two of these, same configuration. Clearsight 3, Fly-Spy Stealth 3, Fly-Spy Manuevering 3, Fly-Spy Evasion 3."},{"card":"VehicleDrone","type":"Drone","name":"Horizon “Noizquito”","attributes":{"Handling":"4","Acceleration":"2","Speed":"3R","Pilot":"3","Body":"1","Armor":"0","Sensor":"3"},"Boxes":7,"Notes":"Condition Monitor: 6 + (Bod/2) = 7. R5.128, Microdrone. Can produce audio at 160db, strobe patterns. Strobes impose −2 looking in direction of drone, −1 with compensation. Speakers impose −2 for those in earshot, −1 if sound dampener."},{"card":"VehicleDrone","type":"Drone","name":"Sony Nightingale","attributes":{"Handling":"4","Acceleration":"1","Speed":"2R","Pilot":"2","Body":"1(1)","Armor":"0","Sensor":"2"},"Boxes":7,"Notes":"Condition Monitor: 6 + (Bod/2) = 7. R5.129, Minidrone. Realistic features (1). Clearsight (from RCC) 3, Nightingale Stealth 3, Nightingale Maneuvering 3, requires Pilot Exotic Vehicle skill (default to Reaction)."},{"card":"VehicleDrone","type":"Drone","name":"MCT Seven “Swims”","attributes":{"Handling":"3","Acceleration":"1","Speed":"2W","Pilot":"1","Body":"1(3)","Armor":"0","Sensor":"1"},"Boxes":7,"Notes":"Condition Monitor: 6 + (Bod/2) = 7. R5.134, Small water drone."},{"card":"Notes","type":"","name":"Rigging Pools","HTML":"<ul><li>Maneuver (rigged): Skill + Int + 2 [Handling]<ul><li>Van: 4 + 4 + 2 [3 + 2]<\/li><li>MCT: 5 + 4 + 2 [4 + 2]<\/li><li>Fly spy: 6 + 4 + 2 [4 + 2]<\/li><li>Bird: 6 + 4 + 2 [4 + 2]<\/li><\/ul><\/li><li>Dog Brain Maneuver: Pilot + Maneuvering [Handling]<ul><li>Van: 1 [3]<\/li><li>MCT: 3 + 3 [4]<\/li><li>Dob: 3 + 3 [5]<\/li><li>Fly spy: 3 + 3 [4]<\/li><li>Bird: 2 + 3 [4]<\/li><li>Noiz: 3 [4]<\/li><\/ul><\/li><li>Perception (rigged): Perception + Int [Sensor]<ul><li>Van: 2 + 4 + 2 [4 + 2]<\/li><li>MCT: 2 + 4 + 2 [3 + 2]<\/li><li>Fly spy: 2 + 4 + 2 [3 + 2]<\/li><li>Bird: 2 + 4 + 2 [2 + 2]<\/li><\/ul><\/li><li>Dog Brain Perception: Pilot + Clearsight [Sensor]<ul><li>Van: 1 + 3 [4]<\/li><li>MCT: 3 + 3 [3]<\/li><li>Dob: 3 + 3 [3]<\/li><li>Fly spy: 3 + 3 [3]<\/li><li>Bird: 2 + 3 [2]<\/li><li>Noiz: 3 [3]<\/li><\/ul><\/li><li>Attack (rigged): Gunner + Logic [Accuracy]<ul><li>Van\/Dob: 3 + 3 + 2 [5 + 2]<\/li><li>MCT: 3 + 3 + 2 [6 + 2]<\/li><\/ul><\/li><li>Dog Brain Attack: Pilot + Targeting [Accuracy]<ul><li>Van: 1 + 3 [5]<\/li><li>MCT: 3 + 3 [6]<\/li><li>Dob: 3 + 3 [5]<\/li><\/ul><\/li><\/ul>"},{"card":"Notes","type":"","name":"Background","HTML":"<p>A skinny half-Japanese kid who grew up in Koreatown in LA, Ben always enjoyed tinkering and playing with RC toys. He did assorted technical jobs for local mechanic shops where he met a smuggler who eventually took him along on some small runs, mentoring him for a future career in the trade.<\/p><p>As Ben learned more and earned more, he saved up for a Control Rig and was introduced to some street docs through his smuggling mentor. Ben never realized he had magical ability until after the surgery. The doctors who performed the surgery did not tell him either \u2014 they just wanted to get paid and keep a relationship with the smuggling world.<\/p><p>Frustrated and disenchanted with the smugglers and doctors, Ben turned to learning about his magical abilities. As he grew in spellcasting and channeling adept powers he worked to combine these with his passion and skill for vehicles and drones.<\/p><p>Ben makes a good living by doing odd jobs, from simple mechanic work to the occasional driver. He maintains a good relationship with his former mentor, though it was not without its problems. Some of Ben\u2019s mentor\u2019s loyalty comes from a sense of responsibility for the street doc fiasco, even as Ben has turned it into an asset.<\/p>"}]}';
function ParseJSON(data, elmID, nodeType) {
try {
var JSONdata = JSON.parse(data);
var divContainer = document.getElementById(elmID);
divContainer.innerHTML = "";
var filteredNodes = JSONdata.items;
for (var a = 0; a < filteredNodes.length; a++) {
var json = filteredNodes[a];
if (json.card === nodeType) {
// I have to find a way to filter
var article = document.createElement("article");
article.className = json.type
.split(" ")
.join("-")
.toLowerCase();
article.setAttribute('id', removeSpecialChars(json.name));
// heading
var h2 = document.createElement("h2");
var span = document.createElement("span");
h2.appendChild(span);
span.innerHTML = json.name;
if (json.type !== undefined && json.type != "") {
span.innerHTML = json.type + ": " + span.innerHTML;
}
var span2 = document.createElement("span");
h2.appendChild(span2);
// attributes
if (json.attributes !== undefined) {
var attrs = Object.keys(json.attributes);
var attrVals = Object.values(json.attributes);
var dl = document.createElement("dl");
for (var i = 0; i < attrs.length; i++) {
var dt = document.createElement("dt");
dt.innerHTML = attrs[i];
dl.appendChild(dt);
var dd = document.createElement("dd");
dd.innerHTML = attrVals[i];
dl.appendChild(dd);
}
}
// boxes
if (json.Boxes !== undefined) {
var pB = document.createElement("p");
pB.className = "boxes";
var boxen = "";
for (var i = 0; i < json.Boxes; i++) {
boxen = "<span>&nbsp;</span> " + boxen;
}
pB.innerHTML = "<strong>Condition Monitor:</strong> " + boxen;
}
// notes
if (json.Notes !== undefined) {
var p = document.createElement("p");
p.innerHTML = "<strong>Notes:</strong> " + json.Notes;
}
// data grid
if (json.table !== undefined && json.row !== undefined) {
var table = document.createElement("table");
var caption = document.createElement("caption");
caption.innerHTML = json.table;
table.appendChild(caption);
var tableHead = Object.keys(json.row[0]);
var tableRows = Object.values(json.row);
var tr = table.insertRow(-1);
for (var i = 0; i < tableHead.length; i++) {
var th = document.createElement("th");
th.innerHTML = tableHead[i];
tr.appendChild(th);
}
for (var j = 0; j < tableRows.length; j++) {
var tableCells = Object.values(json.row[j]);
var tr = table.insertRow(-1);
for (var k = 0; k < tableCells.length; k++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = tableCells[k];
}
}
}
// raw HTML
if (json.HTML !== undefined) {
var div = document.createElement("div");
div.innerHTML = json.HTML;
}
// build it
divContainer.appendChild(article);
article.appendChild(h2);
if (json.attributes !== undefined) {
article.appendChild(dl);
}
if (json.Boxes !== undefined) {
article.appendChild(pB);
}
if (json.Notes !== undefined) {
article.appendChild(p);
}
if (json.table !== undefined && json.row !== undefined) {
article.appendChild(table);
}
if (json.HTML !== undefined) {
article.appendChild(div);
}
}
}
} catch (e) {
console.log("ParseJSON(): " + e);
}
}
// Need a simpler one
function removeSpecialChars(str) {
return str.replace(/(?!\w|\s)./g, '')
.replace(/\s+/g, ' ')
.replace(/^(\s*)([\W\w]*)(\b\s*$)/g, '$2')
.replace(" ","")
.replace(" ","");
}
ParseJSON(stuff, "Core", "Core");
ParseJSON(stuff, "Magic", "Magic");
ParseJSON(stuff, "Cyber", "Cyber");
ParseJSON(stuff, "VehicleDrone", "VehicleDrone");
ParseJSON(stuff, "Notes", "Notes");
body {
padding: .25em;
margin: 0;
font-family: "Open Sans", Arial, sans-serif;
line-height: 1.4;
background-color: #fff;
}
h1 {
font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
font-weight: bold;
font-size: 200%;
margin: 0;
line-height: 1.0;
}
article {
margin: 2em 0;
}
@media print {
body, main {
margin: 0;
padding: 0;
}
article {
page-break-inside: avoid;
}
footer {
display: none;
}
}
@media screen and (min-width: 68em), print and (min-width: 6in) {
main > div {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 1em 2em;
}
}
@media screen and (min-width: 80em), print and (min-width: 7in) {
main > div {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-gap: 1em 2em;
}
}
@media print and (min-width: 6in) {
main > div {
grid-gap: 0.25in 0.25in;
margin: 0.25in 0;
}
}
h2 {
font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
font-weight: bold;
font-size: 150%;
line-height: 1.0;
/* padding: 0.2em 1.5em 0.2em 0.4em; */
/* background: linear-gradient(
-135deg,
transparent 0,
transparent 1.5em,
#5a0a0d 1.5em,
#5a0a0d 100%
); */
margin: 0 0 0.5em 0;
border-bottom: .1rem solid #5a0a0d;
display: flex;
}
h2 span:first-child {
padding: 0.2em 0 0.2em 0.4em;
color: #fff;
background-color: #5a0a0d;
}
h2 span:last-child {
background: linear-gradient(
-135deg,
transparent 0,
transparent calc(100% - 1em),
#5a0a0d calc(100% - 1em),
#5a0a0d 100%
);
flex-grow: 1;
}
@media print {
body {
font-size: 6pt;
color: #000;
background-color: #fff;
margin: 0;
padding: 0;
}
}
@media all and (min-width: 30em) {
body {
padding: 1vw;
}
article {
border-left: 0.1rem solid #5a0a0d;
}
article > *:not(h2) {
margin-left: .5em;
margin-right: .5em;
}
h2 {
margin: 0 0 0.5em 0;
}
}
@media print {
h2 {
background: transparent;
color: #000;
border-bottom: 0.1em solid #000;
}
h2 span:first-child {
background-color: #999;
}
h2 span:last-child {
background: linear-gradient(
-135deg,
transparent 0,
transparent calc(100% - 1em),
#999 calc(100% - 1em),
#999 100%
);
}
article {
border-left: none;
margin: 0;
}
}
p > strong:first-child {
font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
font-weight: bold;
}
p.boxes {
display: flex;
flex-wrap: wrap;
}
p.boxes strong {
flex-basis: 100%;
}
p.boxes span {
flex: 0 0 auto;
border: .1em solid #000;
height: auto;
width: 1em;
margin: 0 .1em .2em .1em;
}
dl {
display: grid;
grid-template-columns: auto auto auto auto auto auto;
/* Disabled until anything other than WebKit supports it */
/* grid-template-columns: repeat(auto-fill, minmax(4em, 1fr)); */
grid-gap: 0.1em 0;
}
/* All these media queries can go away when other browsers support the minmax bits below. */
@media all and (min-width: 28em) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto;
}
dt::after {
content: ":";
}
}
@media all and (min-width: 34em) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
}
}
@media all and (min-width: 40em) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto auto auto
auto auto;
}
}
@media all and (min-width: 46em) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto auto auto
auto auto auto auto;
}
}
@media all and (min-width: 52em) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto auto auto
auto auto auto auto auto auto;
}
}
@media all and (min-width: 58em) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto auto auto
auto auto auto auto auto auto auto auto;
}
}
@media all and (min-width: 64em) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto auto auto
auto auto auto auto auto auto auto auto auto auto;
}
}
@media screen and (min-width: 68em), print and (min-width: 7in) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto auto auto
auto auto auto auto;
}
}
@media screen and (min-width: 70em), print and (min-width: 8in) {
dl {
grid-template-columns: auto auto auto auto auto auto auto auto auto auto
auto auto auto auto auto auto;
}
}
@supports (grid-template-columns: repeat(auto-fill, minmax(4em, 1fr) minmax(4em, 1fr))) {
dl {
grid-template-columns: repeat(auto-fill, minmax(3.75em, 1fr) minmax(3.75em, 1fr));
}
}
dt {
font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
font-weight: bold;
}
dd {
margin: 0;
padding: 0 0.5em 0 0.25em;
}
table {
border-collapse: collapse;
width: calc(100% - 1em);
max-width: 100%;
}
table caption {
color: #f00;
position: absolute;
top: auto;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE 6/7 */
clip: rect(1px, 1px, 1px, 1px);
width: 1px;
height: 1px;
white-space: nowrap;
}
th,
td {
text-align: center;
padding: 0.2em 0.4em;
border-bottom: 0.02em solid #ccc;
}
th {
font-family: "Saira Extra Condensed", "Arial Narrow", sans-serif;
font-weight: bold;
vertical-align: bottom;
}
td {
vertical-align: top;
}
th:first-child,
td:first-child {
text-align: left;
}
ul {
padding-left: 1em;
}
@media all and (min-width: 40em) {
article div > ul {
column-count: 2;
column-gap: 2em;
}
}
@media all and (min-width: 80em), print and (min-width: 9in) {
article div > ul {
column-count: 3;
column-gap: 2em;
}
}
/* Layout that must be customized for every set of blocks */
@media screen and (min-width: 68em), print and (min-width: 6in) {
#Core {
grid-template-areas:
"C1 C3"
"C2 C5"
"C6 C9"
"C7 C9"
"C8 C9"
"C10 C4"
"C11 C4";
}
#Magic {
grid-template-areas:
"M1 M2";
}
#Cyber {
grid-template-areas:
"A1 A2";
}
#VehicleDrone {
grid-template-areas:
"V6 V4"
"V3 V2"
"V1 V1"
"V5 V7";
}
#Notes {
grid-template-areas:
"N2 N1";
}
}
@media screen and (min-width: 80em), print and (min-width: 7in) {
#Core {
grid-template-areas:
"C1 C1 C1 C1 C1 C1 C3 C3 C3 C3 C3 C3"
"C2 C2 C2 C2 C6 C6 C6 C6 C4 C4 C4 C4"
"C2 C2 C2 C2 C6 C6 C6 C6 C4 C4 C4 C4"
"C7 C7 C7 C7 C8 C8 C8 C8 C4 C4 C4 C4"
"C11 C11 C11 C11 C11 C11 C11 C11 C4 C4 C4 C4"
"C5 C5 C5 C5 C5 C10 C10 C10 C10 C10 C10 C10"
"C9 C9 C9 C9 C9 C9 C9 C9 C9 C9 C9 C9";
}
#Magic {
grid-template-areas:
"M1 M1 M1 M1 M1 M1 M2 M2 M2 M2 M2 M2";
}
#Cyber {
grid-template-areas:
"A1 A1 A1 A1 A2 A2 A2 A2 A2 A2 A2 A2";
}
#VehicleDrone {
grid-template-areas:
"V1 V1 V1 V1 V1 V1 V4 V4 V4 V4 V4 V4"
"V1 V1 V1 V1 V1 V1 V5 V5 V5 V5 V5 V5"
"V1 V1 V1 V1 V1 V1 V6 V6 V6 V6 V6 V6"
"V1 V1 V1 V1 V1 V1 V7 V7 V7 V7 V7 V7"
"V2 V2 V2 V2 V2 V2 V3 V3 V3 V3 V3 V3";
}
#Notes {
grid-template-areas:
"N2 N2 N2 N2 N2 N2 N1 N1 N1 N1 N1 N1";
}
}
#PersonalData {
grid-area: C1;
}
#Attributes {
grid-area: C2;
}
#ConditionMonitor {
grid-area: C3;
}
#Skills {
grid-area: C4;
}
#IDLifestyleCurrency {
grid-area: C5;
}
#Armor {
grid-area: C6;
}
#RangedWeapons {
grid-area: C7;
}
#MeleeWeapons {
grid-area: C8;
}
#Qualities {
grid-area: C9;
}
#Contacts {
grid-area: C10;
}
#Gear {
grid-area: C11;
}
#Spells {
grid-area: M1;
}
#AdeptPowers {
grid-area: M2;
}
#Augmentation {
grid-area: A1;
}
#ProteusPoseidonRCC {
grid-area: A2;
}
#GMCBulldog {
grid-area: V1;
}
#GMNissanDoberman {
grid-area: V2;
}
#MCTNissanRotodrone {
grid-area: V3;
}
#MCTFlyspy {
grid-area: V4;
}
#HorizonNoizquito {
grid-area: V5;
}
#SonyNightingale {
grid-area: V6;
}
#MCTSevenSwims {
grid-area: V7;
}
#RiggingPools {
grid-area: N1;
}
#Background {
grid-area: N2;
}
#Augmentation table th:nth-child(3), #Augmentation table td:nth-child(3), #Armor table th:nth-child(3), #Armor table td:nth-child(3), #Qualities table th:nth-child(2), #Qualities table td:nth-child(2), #AdeptPowers table th:nth-child(2), #AdeptPowers table td:nth-child(2), #Contacts table th:nth-child(2), #Contacts table td:nth-child(2), #Contacts table th:nth-child(5), #Contacts table td:nth-child(5), #Skills table th:nth-child(2), #Skills table td:nth-child(2) {
text-align: left;
}
#Augmentation table th:nth-child(4), #Augmentation table td:nth-child(4) {
text-align: right;
}
#ProteusPoseidonRCC th {
border: 1px solid #ccc;
text-align: center;
}
#ProteusPoseidonRCC th:last-child {
border: none;
}
#ProteusPoseidonRCC td {
border-bottom: none;
}
#ConditionMonitor th:nth-child(2), #ConditionMonitor th:nth-child(3), #ConditionMonitor th:nth-child(5), #ConditionMonitor th:nth-child(6), #ConditionMonitor th:nth-child(8), #ConditionMonitor th:nth-child(9), #ConditionMonitor th:nth-child(11), #ConditionMonitor th:nth-child(12) {
color: transparent;
font-size: 70%;
}
#ConditionMonitor td:nth-child(4), #ConditionMonitor td:nth-child(7), #ConditionMonitor td:nth-child(10), #ConditionMonitor td:nth-child(13) {
background-color: #eee;
font-weight: bold;
}
#PersonalData dl, #IDLifestyleCurrency dl {
grid-template-columns: auto auto auto auto;
}
#Attributes dl {
grid-template-columns: auto auto auto auto;
}
#Attributes dd:nth-child(-n+20) {
font-size: 150%;
align-self: end;
}
#Attributes dt:nth-child(-n+20) {
align-self: end;
}
#Attributes *:nth-child(21), #Attributes *:nth-child(22), #Attributes *:nth-child(23), #Attributes *:nth-child(24) {
margin-top: 1em;
}
#VehicleDrone {
page-break-before: always;
}

Vehicle/Drone Sheet JSON

Playing with different CSS layout techniques to create a Shadowrun vehicle/drone sheet. Ideally for on-screen display and printing, with data coming from JSON.

A Pen by Adrian Roselli on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment