Compare commits
22 Commits
f1c16da7e4
...
acf4b4dcdb
| Author | SHA1 | Date | |
|---|---|---|---|
| acf4b4dcdb | |||
| 0b020decc1 | |||
| 5294b19a13 | |||
| 97b2d61e5f | |||
| 0ac27e32e2 | |||
| e3df7bdfe9 | |||
| d229a65d02 | |||
| 04bd0e35e9 | |||
| 3c8fb03d5d | |||
| d613867eef | |||
| 7608e24300 | |||
| 195e343d30 | |||
| bce5ff10e6 | |||
| 3e3deda9dc | |||
| bb7fb1dc83 | |||
| 41c5437ec4 | |||
| e9c163ea2a | |||
| 4b9f145df6 | |||
| cf12833c0d | |||
| af40e4500a | |||
| 48c070f024 | |||
| 1ed213c9fa |
37
TODO.md
@ -102,26 +102,44 @@
|
|||||||
- Kandidaten
|
- Kandidaten
|
||||||
- gelb: gold, yellow, orange
|
- gelb: gold, yellow, orange
|
||||||
- grün: lawngreen, lime, greenyellow
|
- grün: lawngreen, lime, greenyellow
|
||||||
|
- x nach dem Laden passiert es manchmal, dass nach dem Einfügen von testCombatant das add Modal gleich wieder aufgeht
|
||||||
|
- schien die gleiche Sache zu sein wie mit dem hidden.bs.modal event
|
||||||
|
- jetzt kommt es aber trotzdem manchmal wieder
|
||||||
|
- vllt. ein timeout-Problem?
|
||||||
|
- x custom validation not triggering error message nor visible styles
|
||||||
|
- x außerdem bleiben nichtvalid. Werte stehen, wenn man das modal mit ESC schließt und dann mit edit wieder öffnet
|
||||||
|
- x warum sind im dist/-Folder immer zwei Versionen der gleichen Datei? -> lag an parcel-reporter-static-file-copy
|
||||||
|
|
||||||
|
- x revamp Act-icon
|
||||||
|
- alternative to "-10"?
|
||||||
|
- at least recreate Electrolize characters in SVG (with fontforge)
|
||||||
|
- x on KO/Dead soll nur der act-button disabled werden, nicht take damage oder more actions
|
||||||
|
- muss die property disabled richtig verwenden
|
||||||
|
- x action-buttons nicht vertically centered
|
||||||
|
- x color scheme beim Favicon anpassen
|
||||||
|
- https://realfavicongenerator.net/
|
||||||
|
- see also here: https://github.com/audreyfeldroy/favicon-cheat-sheet
|
||||||
|
|
||||||
|
|
||||||
### open
|
### open
|
||||||
|
|
||||||
- color scheme beim Favicon anpassen
|
- favicon checken: https://realfavicongenerator.net/favicon_checker
|
||||||
|
- Mauszeiger soll Finger werden, wenn er über combatant-name/ini/dice-and-rea hovert
|
||||||
|
- actions-menu erscheint nicht direkt unter dem Button
|
||||||
|
- Deployment: use minified libraries (aug-ui, bs, jq)
|
||||||
|
- focus-related stuff
|
||||||
|
- after pressing damage button, focus moves to first table row act button
|
||||||
|
- it's probably b/c I resort the table
|
||||||
|
- wenn ein damage monitor offen ist und ich auf add combatant clicke, springt der Fokus nicht zuverlässig ins erste input feld
|
||||||
- im FP3T Tor Browser kann ich rauszoomen, bis ich die ganzen damage monitors und action menus sehe -> verhindern!
|
- im FP3T Tor Browser kann ich rauszoomen, bis ich die ganzen damage monitors und action menus sehe -> verhindern!
|
||||||
- action-menu und damage-monitor sliden jetzt nicht mehr rein, sondern bleiben an Ort und Stelle
|
- action-menu und damage-monitor sliden jetzt nicht mehr rein, sondern bleiben an Ort und Stelle
|
||||||
- das sollte die Sache verhindern
|
- das sollte die Sache verhindern
|
||||||
- warum fkt. das Ganze nicht als Webapp?
|
- warum fkt. das Ganze nicht als Webapp?
|
||||||
- Firefox (android) sieht die Seite nicht als installable an
|
- Firefox (android) sieht die Seite nicht als installable an
|
||||||
- Webmanifest ist aber da und scheint auch in Ordnung zu sein (sagt Firefox on Linux)
|
- Webmanifest ist aber da und scheint auch in Ordnung zu sein (sagt Firefox on Linux)
|
||||||
- nach dem Laden passiert es manchmal, dass nach dem Einfügen von testCombatant das add Modal gleich wieder aufgeht
|
- comments with general info in source files?
|
||||||
- schien die gleiche Sache zu sein wie mit dem hidden.bs.modal event
|
- nice to have: focus trapping im modal fkt. nur rückwärts (shift-tab), aber nicht vorwärts
|
||||||
- jetzt kommt es aber trotzdem manchmal wieder
|
- zumindest im Chrome; FF ungetestet
|
||||||
- vllt. ein timeout-Problem?
|
|
||||||
- wenn ein damage monitor offen ist und ich auf add combatant clicke, springt der Fokus nicht zuverlässig ins erste input feld
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Feature Requests
|
## Feature Requests
|
||||||
@ -130,7 +148,6 @@
|
|||||||
- mal sehen …
|
- mal sehen …
|
||||||
- Animationen? Transitions?
|
- Animationen? Transitions?
|
||||||
- deployment: dist/* soll direkt auf hermes hochgeladen werden
|
- deployment: dist/* soll direkt auf hermes hochgeladen werden
|
||||||
- x warum sind im dist/-Folder immer zwei Versionen der gleichen Datei? -> lag an parcel-reporter-static-file-copy
|
|
||||||
- HTML soll nicht in eine Zeile umgedingst werden, das sieht doch nicht aus
|
- HTML soll nicht in eine Zeile umgedingst werden, das sieht doch nicht aus
|
||||||
- bootstrap, jquery, font auch lokal vorhalten
|
- bootstrap, jquery, font auch lokal vorhalten
|
||||||
- x font
|
- x font
|
||||||
|
|||||||
@ -1,16 +1,27 @@
|
|||||||
const s = require("../src/js/sr2ini.js");
|
const sr2ini = require("../src/js/sr2ini.js");
|
||||||
|
|
||||||
describe ("test function rollForInitiative()", () => {
|
describe ("test function rollForInitiative()", () => {
|
||||||
test("function should accept numbes as integers as well as strings", () => {
|
test("function should accept integers and strings as parameters", () => {
|
||||||
expect(typeof s.rollForInitiative("1", "5")).toBe("number");
|
expect(typeof sr2ini.rollForInitiative("1", "5")).toBe("number");
|
||||||
expect(typeof s.rollForInitiative(1, 5)).toBe("number");
|
expect(typeof sr2ini.rollForInitiative(1, 5)).toBe("number");
|
||||||
|
expect(typeof sr2ini.rollForInitiative(1, "5")).toBe("number");
|
||||||
|
expect(typeof sr2ini.rollForInitiative("1", 5)).toBe("number");
|
||||||
});
|
});
|
||||||
|
test("return value should be zero for bad parameters", () => {
|
||||||
test("result should be greater than zero", () => {
|
// one or zero parameters
|
||||||
expect(s.rollForInitiative("1", "5")).toBeGreaterThan(0);
|
expect(sr2ini.rollForInitiative(1)).toBe(0);
|
||||||
|
expect(sr2ini.rollForInitiative()).toBe(0);
|
||||||
|
// non-number strings
|
||||||
|
expect(sr2ini.rollForInitiative("qwerty", 12)).toBe(0);
|
||||||
|
expect(sr2ini.rollForInitiative(1, "six")).toBe(0);
|
||||||
|
// parameters as an array
|
||||||
|
expect(sr2ini.rollForInitiative(new Array(1, 2))).toBe(0);
|
||||||
|
expect(sr2ini.rollForInitiative(new Array("1", "2"))).toBe(0);
|
||||||
});
|
});
|
||||||
|
test("should return a value within the possible range of dice rolls", () => {
|
||||||
test("should return zero for bad parameters", () => {
|
expect(sr2ini.rollForInitiative(1, 0)).toBeGreaterThanOrEqual(1);
|
||||||
expect(s.rollForInitiative("a", 2)).toBe(0);
|
expect(sr2ini.rollForInitiative(1, 0)).toBeLessThanOrEqual(6);
|
||||||
|
expect(sr2ini.rollForInitiative(5, 20)).toBeGreaterThanOrEqual(25);
|
||||||
|
expect(sr2ini.rollForInitiative(5, 20)).toBeLessThanOrEqual(50);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
21
icons/README.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Your Favicon Package
|
||||||
|
|
||||||
|
This package was generated with [RealFaviconGenerator](https://realfavicongenerator.net/) [v0.16](https://realfavicongenerator.net/change_log#v0.16)
|
||||||
|
|
||||||
|
## Install instructions
|
||||||
|
|
||||||
|
To install this package:
|
||||||
|
|
||||||
|
Extract this package in the root of your web site. If your site is <code>http://www.example.com</code>, you should be able to access a file named <code>http://www.example.com/favicon.ico</code>.
|
||||||
|
|
||||||
|
Insert the following code in the `head` section of your pages:
|
||||||
|
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
|
<link rel="manifest" href="/site.webmanifest">
|
||||||
|
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#004aa5">
|
||||||
|
<meta name="msapplication-TileColor" content="#2b5797">
|
||||||
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
|
||||||
|
*Optional* - Check your favicon with the [favicon checker](https://realfavicongenerator.net/favicon_checker)
|
||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 24 KiB |
@ -2,7 +2,7 @@
|
|||||||
<browserconfig>
|
<browserconfig>
|
||||||
<msapplication>
|
<msapplication>
|
||||||
<tile>
|
<tile>
|
||||||
<square150x150logo src="/icons/mstile-150x150.png"/>
|
<square150x150logo src="/mstile-150x150.png"/>
|
||||||
<TileColor>#004aa5</TileColor>
|
<TileColor>#004aa5</TileColor>
|
||||||
</tile>
|
</tile>
|
||||||
</msapplication>
|
</msapplication>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 7.2 KiB |
7
icons/html_code.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
|
<link rel="manifest" href="/site.webmanifest">
|
||||||
|
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#004aa5">
|
||||||
|
<meta name="msapplication-TileColor" content="#2b5797">
|
||||||
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 7.5 KiB |
13
icons/safari-pinned-tab.svg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="740.000000pt" height="740.000000pt" viewBox="0 0 740.000000 740.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<metadata>
|
||||||
|
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||||
|
</metadata>
|
||||||
|
<g transform="translate(0.000000,740.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 521 B |
@ -1,9 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Shadowrun 2e Ini Tracker",
|
"name": "",
|
||||||
"short_name": "sr2ini",
|
"short_name": "",
|
||||||
"start_url": "/",
|
|
||||||
"description": "A simple Initiative tracker for Shadowrun 2e",
|
|
||||||
"orientation": "portrait",
|
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/icons/android-chrome-192x192.png",
|
"src": "/icons/android-chrome-192x192.png",
|
||||||
@ -16,7 +13,7 @@
|
|||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"theme_color": "deeppink",
|
"theme_color": "gold",
|
||||||
"background_color": "#004aa5",
|
"background_color": "#004aa5",
|
||||||
"display": "standalone"
|
"display": "standalone"
|
||||||
}
|
}
|
||||||
@ -48,6 +48,7 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fontsource/electrolize": "^5.0.12",
|
||||||
"augmented-ui": "^2.0.0",
|
"augmented-ui": "^2.0.0",
|
||||||
"bootstrap": "^5.2.3",
|
"bootstrap": "^5.2.3",
|
||||||
"jquery": "^3.6.3"
|
"jquery": "^3.6.3"
|
||||||
|
|||||||
@ -1,30 +1,39 @@
|
|||||||
|
/* *************************
|
||||||
|
* Import font (Electrolize)
|
||||||
|
*************************** */
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Electrolize";
|
||||||
|
src: local("Electrolize"), url("../../node_modules/@fontsource/electrolize/files/electrolize-latin-400-normal.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ***********************
|
/* ***********************
|
||||||
* Non-bootstrap variables
|
* Non-bootstrap variables
|
||||||
************************* */
|
************************* */
|
||||||
|
|
||||||
|
// foreground colors
|
||||||
$fg: gold;
|
$fg: gold;
|
||||||
$fg-bright: yellow;
|
$fg-bright: yellow;
|
||||||
$fg-dark: orange;
|
$fg-dark: orange;
|
||||||
// old fg-colors: deeppink, lightpink, #b3005f;
|
// old fg-colors: deeppink, lightpink, #b3005f;
|
||||||
|
|
||||||
|
// background colors
|
||||||
$bg: cyan; // #00ffff
|
$bg: cyan; // #00ffff
|
||||||
$bg-bright: lightcyan; // #e0ffff
|
$bg-bright: lightcyan; // #e0ffff
|
||||||
$bg-dark: darkcyan; // #008b8b
|
$bg-dark: darkcyan; // #008b8b
|
||||||
|
|
||||||
|
// base font size
|
||||||
$html-font-size: 14px;
|
$html-font-size: 14px;
|
||||||
|
|
||||||
|
|
||||||
/* ******************************
|
/* ******************************
|
||||||
* Overriding Bootstrap variables
|
* Override Bootstrap variables
|
||||||
******************************** */
|
******************************** */
|
||||||
|
|
||||||
@import "../../node_modules/bootstrap/scss/functions";
|
@import "../../node_modules/bootstrap/scss/functions";
|
||||||
|
|
||||||
// fonts
|
// font
|
||||||
@font-face {
|
|
||||||
font-family: "Electrolize";
|
|
||||||
src: local("Electrolize"), url("../img/Electrolize-Regular.ttf") format("truetype"), url("https://fonts.googleapis.com/css2?family=Electrolize&display=swap");
|
|
||||||
}
|
|
||||||
$font-family-base: "Electrolize";
|
$font-family-base: "Electrolize";
|
||||||
|
|
||||||
// colors
|
// colors
|
||||||
@ -59,7 +68,7 @@ $form-feedback-icon-valid: none;
|
|||||||
$form-feedback-icon-invalid: none;
|
$form-feedback-icon-invalid: none;
|
||||||
|
|
||||||
// more bootstrap stylesheets
|
// more bootstrap stylesheets
|
||||||
//@import "../../node_modules/bootstrap/scss/bootstrap";
|
//@import "../../node_modules/bootstrap/scss/bootstrap"; // everything
|
||||||
@import "../../node_modules/bootstrap/scss/variables";
|
@import "../../node_modules/bootstrap/scss/variables";
|
||||||
@import "../../node_modules/bootstrap/scss/variables-dark";
|
@import "../../node_modules/bootstrap/scss/variables-dark";
|
||||||
@import "../../node_modules/bootstrap/scss/maps";
|
@import "../../node_modules/bootstrap/scss/maps";
|
||||||
@ -75,9 +84,9 @@ $form-feedback-icon-invalid: none;
|
|||||||
@import "../../node_modules/bootstrap/scss/reboot";
|
@import "../../node_modules/bootstrap/scss/reboot";
|
||||||
|
|
||||||
|
|
||||||
/* ******
|
/* *************
|
||||||
* Mixins
|
* Custom mixins
|
||||||
******** */
|
*************** */
|
||||||
|
|
||||||
@mixin aug() {
|
@mixin aug() {
|
||||||
--aug-b: 5px;
|
--aug-b: 5px;
|
||||||
@ -102,14 +111,12 @@ $form-feedback-icon-invalid: none;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *******************
|
/* **************
|
||||||
* Responsive styles
|
* Responsiveness
|
||||||
********************* */
|
**************** */
|
||||||
|
|
||||||
@media (width <= 500px) {
|
@media (width <= 500px) {
|
||||||
html {
|
html { font-size: $html-font-size; }
|
||||||
font-size: $html-font-size;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
min-width: 100vw;
|
min-width: 100vw;
|
||||||
@ -120,9 +127,7 @@ $form-feedback-icon-invalid: none;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (500px < width < 1000px) {
|
@media (500px < width < 1000px) {
|
||||||
html {
|
html { font-size: calc(100vw / (500px / $html-font-size)); }
|
||||||
font-size: calc(100vw / (500px / $html-font-size));
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
$calc-width: calc(100vw / 2 + 250px);
|
$calc-width: calc(100vw / 2 + 250px);
|
||||||
@ -132,9 +137,7 @@ $form-feedback-icon-invalid: none;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (1000px <= width) {
|
@media (1000px <= width) {
|
||||||
html {
|
html { font-size: calc($html-font-size * 2); }
|
||||||
font-size: calc($html-font-size * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
min-width: 75vw;
|
min-width: 75vw;
|
||||||
@ -143,7 +146,6 @@ $form-feedback-icon-invalid: none;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************
|
/* *****************
|
||||||
* Basic styles
|
* Basic styles
|
||||||
******************* */
|
******************* */
|
||||||
@ -165,18 +167,13 @@ body {
|
|||||||
margin: .2rem;
|
margin: .2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//button { font-family: Electrolize; }
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
padding: .2rem;
|
padding: .2rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
button { font-family: Electrolize; }
|
|
||||||
|
|
||||||
button:focus {
|
|
||||||
filter: brightness(150%) !important;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sr2-button {
|
.sr2-button {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: .07rem solid $bg;
|
border: .07rem solid $bg;
|
||||||
@ -198,6 +195,8 @@ button:focus {
|
|||||||
&:focus {
|
&:focus {
|
||||||
border: .1rem solid $bg !important;
|
border: .1rem solid $bg !important;
|
||||||
box-shadow: 0 0 .3rem $bg-bright, 0 0 .6rem $bg, 0 0 1.2rem $bg-dark !important;
|
box-shadow: 0 0 .3rem $bg-bright, 0 0 .6rem $bg, 0 0 1.2rem $bg-dark !important;
|
||||||
|
filter: brightness(150%) !important;
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
@ -211,7 +210,6 @@ button:focus {
|
|||||||
.display-none { display: none; }
|
.display-none { display: none; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************
|
/* *****************
|
||||||
* Header styles
|
* Header styles
|
||||||
******************* */
|
******************* */
|
||||||
@ -246,7 +244,6 @@ header.navbar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************
|
/* *****************
|
||||||
* Table styles
|
* Table styles
|
||||||
******************* */
|
******************* */
|
||||||
@ -310,6 +307,7 @@ header.navbar {
|
|||||||
color: $fg;
|
color: $fg;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
.sr2-button {
|
.sr2-button {
|
||||||
height: 1.3rem;
|
height: 1.3rem;
|
||||||
@ -333,7 +331,13 @@ header.navbar {
|
|||||||
.combatant-actions {
|
.combatant-actions {
|
||||||
--aug-border-right: 2px;
|
--aug-border-right: 2px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
min-height: 2rem;
|
||||||
min-width: 5rem;
|
min-width: 5rem;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-menu {
|
.actions-menu {
|
||||||
@ -348,22 +352,14 @@ header.navbar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.max-ini td {
|
.max-ini td { text-shadow: 0 0 .15rem $fg; }
|
||||||
text-shadow: 0 0 .15rem $fg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.zero-ini td {
|
.zero-ini td { color: $fg-dark; }
|
||||||
color: $fg-dark;
|
|
||||||
|
|
||||||
svg { fill: $fg-dark; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.ko-or-dead td {
|
.ko-or-dead td {
|
||||||
background-color: rgba(0, 0, 0, .5);
|
background-color: rgba(0, 0, 0, .5);
|
||||||
color: $fg-dark;
|
color: $fg-dark;
|
||||||
text-decoration: line-through .1rem $fg;
|
text-decoration: line-through .1rem $fg;
|
||||||
|
|
||||||
.sr2-button svg { fill: $fg-dark; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge.bg-warning {
|
.badge.bg-warning {
|
||||||
@ -382,12 +378,6 @@ header.navbar {
|
|||||||
top: .3rem;
|
top: .3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.damage-dropdown,
|
|
||||||
.actions-dropdown {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative; // required in order to center dropdowns vertically
|
|
||||||
}
|
|
||||||
|
|
||||||
.damage-monitor,
|
.damage-monitor,
|
||||||
.actions-menu {
|
.actions-menu {
|
||||||
@include aug;
|
@include aug;
|
||||||
@ -395,7 +385,7 @@ header.navbar {
|
|||||||
|
|
||||||
--aug-inlay-bg: rgba(0, 0, 0, .5);
|
--aug-inlay-bg: rgba(0, 0, 0, .5);
|
||||||
--aug-border-opacity: .75;
|
--aug-border-opacity: .75;
|
||||||
padding-top: .7remx;
|
padding-top: .7rem;
|
||||||
padding-bottom: .7rem;
|
padding-bottom: .7rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
@ -418,6 +408,8 @@ header.navbar {
|
|||||||
.damage-monitor {
|
.damage-monitor {
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
|
|
||||||
|
td { padding: .1rem; }
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
@ -432,6 +424,19 @@ header.navbar {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
animation: .6s alternate infinite pulse;
|
||||||
|
animation-delay: -.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
from { filter: brightness(.85) }
|
||||||
|
50% { filter: brightness(1); }
|
||||||
|
to { filter: brightness(1.15); }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.damage-stun {
|
.damage-stun {
|
||||||
@ -459,7 +464,6 @@ header.navbar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************
|
/* *****************
|
||||||
* Modal styles
|
* Modal styles
|
||||||
******************* */
|
******************* */
|
||||||
@ -530,9 +534,14 @@ header.navbar {
|
|||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
&[type="number"]::-webkit-inner-spin-button,
|
&[type="number"] {
|
||||||
&[type="number"]::-webkit-outer-spin-button {
|
-moz-appearance: textfield;
|
||||||
appearance: none;
|
|
||||||
|
&::-webkit-inner-spin-button,
|
||||||
|
&::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus:invalid { box-shadow: 0 0 .25rem $fg-bright, 0 0 .5rem $fg, 0 0 1rem $fg-dark !important; }
|
&:focus:invalid { box-shadow: 0 0 .25rem $fg-bright, 0 0 .5rem $fg, 0 0 1rem $fg-dark !important; }
|
||||||
@ -613,4 +622,3 @@ footer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,11 +8,7 @@
|
|||||||
<title>Shadowrun 2e Ini Tracker</title>
|
<title>Shadowrun 2e Ini Tracker</title>
|
||||||
<meta name="description" content="A simple Initiative tracker for Shadowrun 2e" />
|
<meta name="description" content="A simple Initiative tracker for Shadowrun 2e" />
|
||||||
<meta name="author" content="Eclipse729" />
|
<meta name="author" content="Eclipse729" />
|
||||||
<!-- <meta name="theme-color" content="" />-->
|
|
||||||
|
|
||||||
<link rel="manifest" href="/icons/sr2ini.webmanifest">
|
|
||||||
|
|
||||||
<!-- <link type="text/css" rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css" > -->
|
|
||||||
<link type="text/css" rel="stylesheet" href="../node_modules/augmented-ui/augmented-ui.css">
|
<link type="text/css" rel="stylesheet" href="../node_modules/augmented-ui/augmented-ui.css">
|
||||||
<link type="text/css" rel="stylesheet" href="css/sr2ini.scss">
|
<link type="text/css" rel="stylesheet" href="css/sr2ini.scss">
|
||||||
|
|
||||||
@ -21,11 +17,11 @@
|
|||||||
<link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png">
|
||||||
<link rel="manifest" href="/icons/sr2ini.webmanifest">
|
<link rel="manifest" href="/icons/sr2ini.iconmanifest">
|
||||||
<link rel="shortcut icon" href="/icons/favicon.ico">
|
<link rel="shortcut icon" href="/icons/favicon.ico">
|
||||||
<meta name="msapplication-TileColor" content="#004aa5">
|
<meta name="msapplication-TileColor" content="#004aa5">
|
||||||
<meta name="msapplication-config" content="/icons/browserconfig.xml">
|
<meta name="msapplication-config" content="/icons/browserconfig.xml">
|
||||||
<!-- <meta name="theme-color" content="#004aa5">-->
|
<meta name="theme-color" content="gold">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@ -148,9 +144,9 @@
|
|||||||
</symbol>
|
</symbol>
|
||||||
<!-- act (-10) -->
|
<!-- act (-10) -->
|
||||||
<symbol id="act" >
|
<symbol id="act" >
|
||||||
<rect x="0" y="272" height="64" width="96" />
|
<path d="M 96 228 q 6 2 8 8 v 40 q -2 6 -8 8 h -88 q -6 -2 -8 -8 v -40 q 2 -6 8 -8 z" />
|
||||||
<path d="M 160 64 h 64 v 384 h -64 v -296 l -64 64 l -40 -40 Z" />
|
<path d="M 84 178 q -5.5 4.5 -11 0 l -24 -24 q -4.5 -5.5 0 -11 l 76 -76 q 9 -3 12 -4 h 68 q 6 2 8 8 v 368 q -2 6 -8 8 h -44 q -6 -2 -8 -8 v -324 q -0 -8 -5.5 -2.5 z" />
|
||||||
<path d="M 352 64 h 96 l 64 64 v 256 l -64 64 h -96 l -64 -64 v -256 l 64 -64 l 32 64 h 32 l 32 32 v 192 l -32 32 h -32 l -32 -32 v -192 l 32 -32" fill-rule="evenodd" />
|
<path d="M 295 444 h 174 q 11 0 21 -11 l 11 -11 q 11 -11 11 -27 v -285 q 0 -16 -11 -27 l -11 -11 q -11 -11 -21 -11 h -174 q -11 0 -21 11 l -11 11 q -11 11 -11 27 v 285 q 0 16 11 27 l 11 11 q 11 11 21 11 z M 452 144 v 216 q 0 8 -1 11 t -5 6 t -6 5 t -10 1 h -96 q -8 0 -10 -1 t -6 -5 t -5 -6 t -1 -11 v -216 q 0 -8 1 -11 t 5 -6 t 6 -5 t 10 -1 h 96 q 8 0 10 1 t 6 5 t 5 6 t 1 11 z" />
|
||||||
</symbol>
|
</symbol>
|
||||||
<!-- take damage -->
|
<!-- take damage -->
|
||||||
<symbol id="take-damage" >
|
<symbol id="take-damage" >
|
||||||
@ -193,8 +189,8 @@
|
|||||||
<!-- footer -->
|
<!-- footer -->
|
||||||
<div class="footer-container container">
|
<div class="footer-container container">
|
||||||
<footer data-augmented-ui="tl-clip br-clip both">
|
<footer data-augmented-ui="tl-clip br-clip both">
|
||||||
<p>code & design by <a href="#" tabindex="-1" title="Eclipse">Eclipse</a> | background by <a href="https://www.deviantart.com/xxaries1970xx" tabindex="-1" title="xxAries1970xx on DeviantArt">xxAries1970xx</a></p>
|
<p><a href="https://git.unterdemradar.de/tobias/sr2ini" tabindex="-1" title="sr2ini">sr2ini</a> | Copyright (C) 2023 by Eclipse | background by <a href="https://www.deviantart.com/xxaries1970xx" tabindex="-1" title="xxAries1970xx on DeviantArt">xxAries1970xx</a></p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -36,7 +36,9 @@ const COMBATANT_TABLE_ROW = [
|
|||||||
'<td class="combatant-ini" title="Effective initiative (w/ wound penalties)" data-bs-toggle="modal" data-bs-target="#combatant-modal" data-augmented-ui="both"></td>\n',
|
'<td class="combatant-ini" title="Effective initiative (w/ wound penalties)" data-bs-toggle="modal" data-bs-target="#combatant-modal" data-augmented-ui="both"></td>\n',
|
||||||
'<td class="combatant-dice-and-rea" title="Iniative dice and reaction" data-bs-toggle="modal" data-bs-target="#combatant-modal" data-augmented-ui="both"><span class="combatant-dice"></span>D+<span class="combatant-rea"></span></td>\n',
|
'<td class="combatant-dice-and-rea" title="Iniative dice and reaction" data-bs-toggle="modal" data-bs-target="#combatant-modal" data-augmented-ui="both"><span class="combatant-dice"></span>D+<span class="combatant-rea"></span></td>\n',
|
||||||
'<td class="combatant-actions" data-augmented-ui="both">\n',
|
'<td class="combatant-actions" data-augmented-ui="both">\n',
|
||||||
'<button type="button" class="sr2-button act-button" title="Act and reduce ini by 10"><svg viewbox="0 0 512 512"><use href="#act" /></svg></button>\n',
|
'<div>\n',
|
||||||
|
'<button type="button" class="sr2-button act-button" title="Act and reduce ini by 10"><svg viewbox="0 0 512 512"><use href="#act" /></svg></button>\n',
|
||||||
|
'</div>\n',
|
||||||
'<div class="damage-dropdown">\n',
|
'<div class="damage-dropdown">\n',
|
||||||
'<button type="button" class="sr2-button damage-button" title="Take damage"><svg viewbox="0 0 512 512"><use href="#take-damage" /></svg></button>\n',
|
'<button type="button" class="sr2-button damage-button" title="Take damage"><svg viewbox="0 0 512 512"><use href="#take-damage" /></svg></button>\n',
|
||||||
'</div>\n',
|
'</div>\n',
|
||||||
@ -55,14 +57,14 @@ const DAMAGE_MONITOR_HTML = [
|
|||||||
'<div class="damage-monitor" data-augmented-ui="tl-scoop bl-clip-y tr-clip-y br-scoop both">\n',
|
'<div class="damage-monitor" data-augmented-ui="tl-scoop bl-clip-y tr-clip-y br-scoop both">\n',
|
||||||
'<table>\n',
|
'<table>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" title="Light stun damage" tabindex="-1">L</button></td><td><button type="button" class="damage-physical active" title="Light physical damage" tabindex="-1">L</button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" title="Light stun damage" tabindex="-1">L</button></td><td><button type="button" class="damage-physical active" title="Light physical damage" tabindex="-1">L</button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"></button></td><td><button type="button" class="damage-physical active" tabindex="-1"></button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"> </button></td><td><button type="button" class="damage-physical active" tabindex="-1"> </button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" title="Medium stun damage" tabindex="-1">M</button></td><td><button type="button" class="damage-physical active" title="Medium physical damage" tabindex="-1">M</button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" title="Medium stun damage" tabindex="-1">M</button></td><td><button type="button" class="damage-physical active" title="Medium physical damage" tabindex="-1">M</button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"></button></td><td><button type="button" class="damage-physical active" tabindex="-1"></button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"> </button></td><td><button type="button" class="damage-physical active" tabindex="-1"> </button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"></button></td><td><button type="button" class="damage-physical active" tabindex="-1"></button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"> </button></td><td><button type="button" class="damage-physical active" tabindex="-1"> </button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" title="Severe stun damage" tabindex="-1">S</button></td><td><button type="button" class="damage-physical active" title="Severe physical damage" tabindex="-1">S</button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" title="Severe stun damage" tabindex="-1">S</button></td><td><button type="button" class="damage-physical active" title="Severe physical damage" tabindex="-1">S</button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"></button></td><td><button type="button" class="damage-physical active" tabindex="-1"></button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"> </button></td><td><button type="button" class="damage-physical active" tabindex="-1"> </button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"></button></td><td><button type="button" class="damage-physical active" tabindex="-1"></button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"> </button></td><td><button type="button" class="damage-physical active" tabindex="-1"> </button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"></button></td><td><button type="button" class="damage-physical active" tabindex="-1"></button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" tabindex="-1"> </button></td><td><button type="button" class="damage-physical active" tabindex="-1"> </button></td></tr>\n',
|
||||||
'<tr><td><button type="button" class="damage-stun active" title="K.O." tabindex="-1"><svg viewbox="0 0 512 512"><use href="#ko" /></svg></button></td><td><button type="button" class="damage-physical active" title="Dead" tabindex="-1"><svg viewbox="0 0 512 512"><use href="#dead" /></svg></button></td></tr>\n',
|
'<tr><td><button type="button" class="damage-stun active" title="K.O." tabindex="-1"><svg viewbox="0 0 512 512"><use href="#ko" /></svg></button></td><td><button type="button" class="damage-physical active" title="Dead" tabindex="-1"><svg viewbox="0 0 512 512"><use href="#dead" /></svg></button></td></tr>\n',
|
||||||
'</table>\n',
|
'</table>\n',
|
||||||
'</div>'].join("");
|
'</div>'].join("");
|
||||||
@ -120,7 +122,7 @@ function getEffectiveIni(tr) {
|
|||||||
// add test combatant for testing purposes (duh)
|
// add test combatant for testing purposes (duh)
|
||||||
function addTestCombatant() {
|
function addTestCombatant() {
|
||||||
// Eclipse
|
// Eclipse
|
||||||
$("#add-combatant-button").click();
|
// $("#add-combatant-button").click();
|
||||||
$("#combatant-modal-name").val("Eclipse");
|
$("#combatant-modal-name").val("Eclipse");
|
||||||
$("#combatant-modal-dice").val(3);
|
$("#combatant-modal-dice").val(3);
|
||||||
$("#combatant-modal-rea").val(6);
|
$("#combatant-modal-rea").val(6);
|
||||||
@ -236,7 +238,6 @@ function handleDamageLevelClick(event) {
|
|||||||
damageLevel += 1;
|
damageLevel += 1;
|
||||||
}
|
}
|
||||||
let damageType = $btn.attr("class").split(" ").filter(cls => cls.substr(0, 7) == "damage-" ? cls : false).toString().substr(7);
|
let damageType = $btn.attr("class").split(" ").filter(cls => cls.substr(0, 7) == "damage-" ? cls : false).toString().substr(7);
|
||||||
console.log("damageType is", damageType);
|
|
||||||
// add damage level to table row as as data attribute
|
// add damage level to table row as as data attribute
|
||||||
$btn.parents("tr.combatant-row").attr("data-damage-" + damageType, damageLevel);
|
$btn.parents("tr.combatant-row").attr("data-damage-" + damageType, damageLevel);
|
||||||
// select/unselect damage buttons above/below
|
// select/unselect damage buttons above/below
|
||||||
@ -368,9 +369,7 @@ function editCombatant() {
|
|||||||
ini = (ini != "") ? ini : rollForInitiative(dice, rea);
|
ini = (ini != "") ? ini : rollForInitiative(dice, rea);
|
||||||
// get correct row
|
// get correct row
|
||||||
let index = parseInt($("#combatant-modal").data("row"));
|
let index = parseInt($("#combatant-modal").data("row"));
|
||||||
console.log("row index is", index);
|
|
||||||
let $tr = $("tr.combatant-row").eq(index);
|
let $tr = $("tr.combatant-row").eq(index);
|
||||||
console.log("row is", $tr);
|
|
||||||
// set new values
|
// set new values
|
||||||
$tr.attr("data-true-ini", ini);
|
$tr.attr("data-true-ini", ini);
|
||||||
$tr.find(".combatant-name").text(name);
|
$tr.find(".combatant-name").text(name);
|
||||||
@ -416,10 +415,11 @@ function startNewRound() {
|
|||||||
|
|
||||||
// sort combatants by ini value and add contextual classes
|
// sort combatants by ini value and add contextual classes
|
||||||
function sortTable() {
|
function sortTable() {
|
||||||
// do some clean up: remove previous classes from rows, disable act buttons, remove effective ini and damage badges
|
// do some clean up: remove previous classes from rows, remove effective ini and damage badges
|
||||||
$(".combatant-row").removeClass("ko-or-dead max-ini zero-ini"); //REGULAR_INI
|
$(".combatant-row").removeClass("ko-or-dead max-ini zero-ini"); //REGULAR_INI
|
||||||
$(".combatant-row").find(".act-button").prop("disabled", true).attr("aria-disabled", "true");
|
|
||||||
$(".combatant-ini").empty();
|
$(".combatant-ini").empty();
|
||||||
|
// disable all act buttons
|
||||||
|
$(".combatant-row").find(".act-button").prop("disabled", true).attr("aria-disabled", "true");
|
||||||
// mark KO or death with class
|
// mark KO or death with class
|
||||||
$(".combatant-row").each(function() {
|
$(".combatant-row").each(function() {
|
||||||
if (parseInt($(this).attr("data-damage-stun")) == 10 || parseInt($(this).attr("data-damage-physical")) == 10) {
|
if (parseInt($(this).attr("data-damage-stun")) == 10 || parseInt($(this).attr("data-damage-physical")) == 10) {
|
||||||
@ -443,16 +443,16 @@ function sortTable() {
|
|||||||
$(this).find(".combatant-ini").append($.parseHTML(PHYSICAL_BADGE_HTML));
|
$(this).find(".combatant-ini").append($.parseHTML(PHYSICAL_BADGE_HTML));
|
||||||
$(this).find(".physical-badge").append(DAMAGE_NIVEAU[DAMAGE_PENALTY[$(this).attr("data-damage-physical")]]);
|
$(this).find(".physical-badge").append(DAMAGE_NIVEAU[DAMAGE_PENALTY[$(this).attr("data-damage-physical")]]);
|
||||||
}
|
}
|
||||||
// K.O./dead -> don't add anything
|
// K.O./dead -> do nothing
|
||||||
if ($(this).hasClass("ko-or-dead")) {
|
if ($(this).hasClass("ko-or-dead")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// ini = zero
|
// ini = zero -> set contextual class
|
||||||
if (parseInt($(this).find(".combatant-ini").text()) == 0) {
|
if (parseInt($(this).find(".combatant-ini").text()) == 0) {
|
||||||
$(this).addClass("zero-ini");
|
$(this).addClass("zero-ini");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// ini = max and non-zero
|
// ini = max and non-zero -> enable act-button
|
||||||
if (parseInt($(this).find(".combatant-ini").text()) == iniMax && iniMax > 0) {
|
if (parseInt($(this).find(".combatant-ini").text()) == iniMax && iniMax > 0) {
|
||||||
$(this).addClass("max-ini").find(".act-button").prop("disabled", false).removeAttr("aria-disabled");
|
$(this).addClass("max-ini").find(".act-button").prop("disabled", false).removeAttr("aria-disabled");
|
||||||
return true;
|
return true;
|
||||||
@ -469,6 +469,11 @@ function sortTable() {
|
|||||||
|
|
||||||
// validate a combatant row form by checking for all conditions, including regular HTML5 validation
|
// validate a combatant row form by checking for all conditions, including regular HTML5 validation
|
||||||
function validateCombatant() {
|
function validateCombatant() {
|
||||||
|
// do standard HTML5 form validation first
|
||||||
|
// (makes sure that name is not empty and that all other values are numbers within their individual ranges)
|
||||||
|
if ( ! $("#combatant-form").get(0).reportValidity() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// get input elements
|
// get input elements
|
||||||
let inputElements = {
|
let inputElements = {
|
||||||
name: $("#combatant-modal-name").get(0),
|
name: $("#combatant-modal-name").get(0),
|
||||||
@ -476,29 +481,20 @@ function validateCombatant() {
|
|||||||
dice: $("#combatant-modal-dice").get(0),
|
dice: $("#combatant-modal-dice").get(0),
|
||||||
rea: $("#combatant-modal-rea").get(0)
|
rea: $("#combatant-modal-rea").get(0)
|
||||||
};
|
};
|
||||||
// do standard HTML5 form validation first
|
|
||||||
// (makes sure that name is not empty and that all other values are numbers within their individual ranges)
|
|
||||||
let valid = true;
|
|
||||||
Object.values(inputElements).forEach( input => {
|
|
||||||
if (!input.reportValidity()) { valid = false; }
|
|
||||||
})
|
|
||||||
if (!valid) { return false; }
|
|
||||||
// now for some custom validation; first we need to get the input values
|
// now for some custom validation; first we need to get the input values
|
||||||
let ini = inputElements["ini"].value.trim();
|
let ini = inputElements["ini"].value.trim();
|
||||||
let dice = inputElements["dice"].value.trim();
|
let dice = inputElements["dice"].value.trim();
|
||||||
let rea = inputElements["rea"].value.trim();
|
let rea = inputElements["rea"].value.trim();
|
||||||
// invalidate if ini, dice and rea are all empty
|
// invalidate if ini, dice and rea are all empty
|
||||||
if (ini == "" && (dice == "" || rea == "")) {
|
if (ini == "" && (dice == "" || rea == "")) {
|
||||||
inputElements["ini"].setCustomValidity("Requiring values for ini dice and reaction, or initiative, or all three");
|
inputElements["ini"].setCustomValidity("Values required for either initiative, or dice and reaction, or all three");
|
||||||
inputElements["ini"].reportValidity();
|
inputElements["ini"].reportValidity();
|
||||||
inputElements["ini"].setCustomValidity("");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// invalidate if dice or rea is empty but not both
|
// invalidate if dice or rea is empty but not both
|
||||||
if ((dice == "") != (rea == "")) {
|
if ((dice == "") != (rea == "")) {
|
||||||
inputElements["dice"].setCustomValidity("Values required for both dice and reaction, or none (in which case ini is required)");
|
inputElements["dice"].setCustomValidity("Values required for both dice and reaction, or none (in which case ini is required)");
|
||||||
inputElements["dice"].reportValidity();
|
inputElements["dice"].reportValidity();
|
||||||
inputElements["dice"].setCustomValidity("");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// ok then
|
// ok then
|
||||||
@ -524,22 +520,29 @@ $(document).ready(function () {
|
|||||||
$("#confirm-modal-remove-combatant-ok-button").on("click", () => {
|
$("#confirm-modal-remove-combatant-ok-button").on("click", () => {
|
||||||
removeCombatant();
|
removeCombatant();
|
||||||
});
|
});
|
||||||
|
// add event handler to certain input elements that removes any custom validity message
|
||||||
|
$("#combatant-modal-dice #combatant-modal-rea #combatant-modal-ini").on("input", (event) => {
|
||||||
|
event.target.setCustomValidity("");
|
||||||
|
});
|
||||||
// add event listeners to damage sliders in combatant modal
|
// add event listeners to damage sliders in combatant modal
|
||||||
$("#combatant-modal-stun").on("change", () => {
|
$("#combatant-modal-stun").on("input change", () => {
|
||||||
if ($("#combatant-modal-stun").val() == "10") {
|
if ($("#combatant-modal-stun").val() == "10") {
|
||||||
$("#combatant-modal-penalty-stun").text("(K.O.)");
|
$("#combatant-modal-penalty-stun").text("(K.O.)");
|
||||||
|
} else if ($("#combatant-modal-stun").val() == "0") {
|
||||||
|
$("#combatant-modal-penalty-stun").text("");
|
||||||
} else {
|
} else {
|
||||||
$("#combatant-modal-penalty-stun").text("(wound penalty -" + DAMAGE_PENALTY[$("#combatant-modal-stun").val()] + ")");
|
$("#combatant-modal-penalty-stun").text("(wound penalty -" + DAMAGE_PENALTY[$("#combatant-modal-stun").val()] + ")");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$("#combatant-modal-physical").on("change", () => {
|
$("#combatant-modal-physical").on("input change", () => {
|
||||||
if ($("#combatant-modal-physical").val() == "10") {
|
if ($("#combatant-modal-physical").val() == "10") {
|
||||||
$("#combatant-modal-penalty-physical").text("(dead)");
|
$("#combatant-modal-penalty-physical").text("(dead)");
|
||||||
|
} else if ($("#combatant-modal-physical").val() == "0") {
|
||||||
|
$("#combatant-modal-penalty-physical").text("");
|
||||||
} else {
|
} else {
|
||||||
$("#combatant-modal-penalty-physical").text("(wound penalty -" + DAMAGE_PENALTY[$("#combatant-modal-physical").val()] + ")");
|
$("#combatant-modal-penalty-physical").text("(wound penalty -" + DAMAGE_PENALTY[$("#combatant-modal-physical").val()] + ")");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// always focus name input field when combatant modal appears
|
// always focus name input field when combatant modal appears
|
||||||
$('#combatant-modal').on('shown.bs.modal', () => $('#combatant-modal-name').focus());
|
$('#combatant-modal').on('shown.bs.modal', () => $('#combatant-modal-name').focus());
|
||||||
// always empty input fields when combatant modal disappears
|
// always empty input fields when combatant modal disappears
|
||||||
@ -555,3 +558,5 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
addTestCombatant();
|
addTestCombatant();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.exports = { rollForInitiative, validateCombatant, whoGoesFirst, getEffectiveIni };
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 16 KiB |
@ -1,31 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #004aa5;
|
|
||||||
}
|
|
||||||
|
|
||||||
div {
|
|
||||||
width: 60%;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
position: relative;
|
|
||||||
top: 100px;
|
|
||||||
|
|
||||||
|
|
||||||
border: 8px solid cyan;
|
|
||||||
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 16px;
|
|
||||||
|
|
||||||
background-color: rgba(0, 0, 0, .75);
|
|
||||||
box-shadow: 0 0 16px lightcyan, 0 0 32px lightcyan, 0 0 32px cyan, 0 0 64px cyan, 0 0 64px darkcyan, 0 0 128px darkcyan;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 384px;
|
|
||||||
height: 384px;
|
|
||||||
filter: invert(34%) sepia(78%) saturate(7014%) hue-rotate(316deg) brightness(125%) contrast(105%);
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head><link type="text/css" rel="stylesheet" href="tmp.css"></head>
|
|
||||||
<body><div><button><img src="dice512.png"></button></div></body></html>
|
|
||||||
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 2.1 MiB |
42
tools/favicon.css
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
body {
|
||||||
|
margin: 24px;
|
||||||
|
background: url("../../src/img/bg.jpg") -874px -1340px;
|
||||||
|
/* background-color: #004aa5;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#border {
|
||||||
|
width: 576px;
|
||||||
|
height: 576px;
|
||||||
|
|
||||||
|
border-radius: 0px; /*64px; */
|
||||||
|
padding: 64px;
|
||||||
|
|
||||||
|
/* background: linear-gradient(to bottom right, cyan, darkcyan);*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#button {
|
||||||
|
/* background-color: black;*/
|
||||||
|
/* border-radius: 32px;*/
|
||||||
|
|
||||||
|
padding: 32px;
|
||||||
|
|
||||||
|
width: 512px;
|
||||||
|
height: 512px;
|
||||||
|
|
||||||
|
--aug-tl: 48px;
|
||||||
|
--aug-br: 48px;
|
||||||
|
|
||||||
|
--aug-border-all: 24px;
|
||||||
|
--aug-border-bg: linear-gradient(to bottom right, cyan, darkcyan);
|
||||||
|
|
||||||
|
--aug-inlay-x: 24px;
|
||||||
|
--aug-inlay-y: 24px;
|
||||||
|
--aug-inlay-bg: rgba(0, 0, 0, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 512px;
|
||||||
|
height: 512px;
|
||||||
|
transform: scale(.8) translateX(-24px);
|
||||||
|
}
|
||||||
26
tools/favicon.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../../node_modules/augmented-ui/augmented-ui.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="favicon.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="border" >
|
||||||
|
<div id="button" data-augmented-ui="tl-clip-y br-clip-y both">
|
||||||
|
<svg viewport="0 0 512 512">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="gold" gradientTransform="rotate(60)">
|
||||||
|
<stop offset="15%" stop-color="yellow" />
|
||||||
|
<stop offset="55%" stop-color="gold" />
|
||||||
|
<stop offset="95%" stop-color="orange" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<path d="M 96 228 q 6 2 8 8 v 40 q -2 6 -8 8 h -88 q -6 -2 -8 -8 v -40 q 2 -6 8 -8 z" fill="url('#gold')" />
|
||||||
|
<path d="M 84 178 q -5.5 4.5 -11 0 l -24 -24 q -4.5 -5.5 0 -11 l 76 -76 q 9 -3 12 -4 h 68 q 6 2 8 8 v 368 q -2 6 -8 8 h -44 q -6 -2 -8 -8 v -324 q -0 -8 -5.5 -2.5 z" fill="url('#gold')" />
|
||||||
|
<path d="M 295 444 h 174 q 11 0 21 -11 l 11 -11 q 11 -11 11 -27 v -285 q 0 -16 -11 -27 l -11 -11 q -11 -11 -21 -11 h -174 q -11 0 -21 11 l -11 11 q -11 11 -11 27 v 285 q 0 16 11 27 l 11 11 q 11 11 21 11 z
|
||||||
|
M 452 144 v 216 q 0 8 -1 11 t -5 6 t -6 5 t -10 1 h -96 q -8 0 -10 -1 t -6 -5 t -5 -6 t -1 -11 v -216 q 0 -8 1 -11 t 5 -6 t 6 -5 t 10 -1 h 96 q 8 0 10 1 t 6 5 t 5 6 t 1 11 z" fill="url('#gold')" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1 +0,0 @@
|
|||||||
{"result":{"status":"success"},"favicon":{"package_url":"https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/favicon_package_v0.16.zip","files_urls":["https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/android-chrome-192x192.png","https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/android-chrome-512x512.png","https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/apple-touch-icon.png","https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/browserconfig.xml","https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/favicon-16x16.png","https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/favicon-32x32.png","https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/favicon.ico","https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/mstile-150x150.png","https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/package_files/site.webmanifest"],"html_code":"<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/icons/apple-touch-icon.png\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/icons/favicon-32x32.png\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/icons/favicon-16x16.png\">\n<link rel=\"manifest\" href=\"/icons/site.webmanifest\">\n<link rel=\"shortcut icon\" href=\"/icons/favicon.ico\">\n<meta name=\"msapplication-TileColor\" content=\"#004aa5\">\n<meta name=\"msapplication-config\" content=\"/icons/browserconfig.xml\">\n<meta name=\"theme-color\" content=\"#004aa5\">","compression":"false","overlapping_markups":["link[rel=\"apple-touch-icon\"]","link[rel=\"shortcut\"]","link[rel=\"shortcut icon\"]","link[rel=\"icon\",sizes=\"16x16\"]","link[rel=\"icon\",sizes=\"32x32\"]","meta[name=\"msapplication-TileColor\"]","meta[name=\"msapplication-config\"]","link[rel=\"manifest\"]","meta[name=\"theme-color\"]"]},"files_location":{"type":"path","path":"/icons"},"preview_picture_url":"https://realfavicongenerator.net/files/d925f2495c2cc5046691e320cba3357e995bcbb8/favicon_preview.png","version":"0.16"}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
"masterPicture": "tools/favicon-master-image.png",
|
|
||||||
"iconsPath": "/icons",
|
|
||||||
"design": {
|
|
||||||
"ios": {
|
|
||||||
"pictureAspect": "backgroundAndMargin",
|
|
||||||
"backgroundColor": "#004aa5",
|
|
||||||
"margin": "11%",
|
|
||||||
"assets": {
|
|
||||||
"ios6AndPriorIcons": false,
|
|
||||||
"ios7AndLaterIcons": false,
|
|
||||||
"precomposedIcons": false,
|
|
||||||
"declareOnlyDefaultIcon": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"desktopBrowser": {
|
|
||||||
"design": "raw"
|
|
||||||
},
|
|
||||||
"windows": {
|
|
||||||
"pictureAspect": "noChange",
|
|
||||||
"backgroundColor": "#004aa5",
|
|
||||||
"onConflict": "override",
|
|
||||||
"assets": {
|
|
||||||
"windows80Ie10Tile": false,
|
|
||||||
"windows10Ie11EdgeTiles": {
|
|
||||||
"small": false,
|
|
||||||
"medium": true,
|
|
||||||
"big": false,
|
|
||||||
"rectangle": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"androidChrome": {
|
|
||||||
"pictureAspect": "backgroundAndMargin",
|
|
||||||
"margin": "13%",
|
|
||||||
"backgroundColor": "#004aa5",
|
|
||||||
"themeColor": "#004aa5",
|
|
||||||
"manifest": {
|
|
||||||
"display": "standalone",
|
|
||||||
"orientation": "notSet",
|
|
||||||
"onConflict": "override",
|
|
||||||
"declared": true
|
|
||||||
},
|
|
||||||
"assets": {
|
|
||||||
"legacyIcon": false,
|
|
||||||
"lowResolutionIcons": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"scalingAlgorithm": "Mitchell",
|
|
||||||
"errorOnImageTooSmall": false,
|
|
||||||
"readmeFile": false,
|
|
||||||
"htmlCodeFile": false,
|
|
||||||
"usePathAsIs": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BIN
tools/favicon_package_v0.16.zip
Normal file
@ -1,23 +0,0 @@
|
|||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip-headtop">
|
|
||||||
<path d="M 0 144 v -144 h 216 v 112 h 80 v -112 h 216 v 144 Z" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath id="clip-coattop">
|
|
||||||
<path d="M 100 264 a 144 132 0 0 0 312 0 h 100 v 256 h -512 v -256 Z" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
|
|
||||||
<rect x="0" y="0" width="512" height="512" fill="green" stroke="none"/>
|
|
||||||
<path d="M 112 164 h 288 v 72 l -24 24 h -88 q -32 -128 -64 0 h -88 l -24 -24 v -72 Z" fill-rule="evenodd" /> <!-- glasses -->
|
|
||||||
<path d="M 136 280 a 132 164 0 0 0 240 0 Z" /> <!-- bottom of head -->
|
|
||||||
<path d="M 128 144 a 144 128 0 0 1 256 0 Z" clip-path="url(#clip-headtop)"/> <!-- top of head -->
|
|
||||||
<path d="M 232 0 h 48 v 96 h -48 Z" /> <!-- mohawk -->
|
|
||||||
<path d="M 64 304 h 384 v 48 l -64 176 h -256 l -64 -192 Z" clip-path="url(#clip-coattop)" /> <!-- coat -->
|
|
||||||
|
|
||||||
<path d="M 128 512 h -128 v -112 l 48 -32 l 48 144 Z" />
|
|
||||||
<path d="M 384 512 h 128 v -112 l -48 -32 l -48 144 Z" />
|
|
||||||
|
|
||||||
<!-- <path d="M 32 96 h 448 v 96 l -32 32 h -144 q -56 -160 -96 0 h -144 l -32 -32 v -96 Z" fill-rule="evenodd" /> glasses in big -->
|
|
||||||
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
@ -1,38 +0,0 @@
|
|||||||
import {manifest, version} from '@parcel/service-worker';
|
|
||||||
|
|
||||||
console.log("[Service Worker] Version:", version);
|
|
||||||
console.log("[Service Worker] Manifest:", manifest);
|
|
||||||
|
|
||||||
// install Service Worker
|
|
||||||
async function install() {
|
|
||||||
const cache = await caches.open(version); //cacheNAme
|
|
||||||
console.log("[Service Worker] Caching all: app shell and content");
|
|
||||||
await cache.addAll(manifest); // fileList
|
|
||||||
}
|
|
||||||
console.log("[Service Worker] Install");
|
|
||||||
self.addEventListener("install", e => e.waitUntil(install()));
|
|
||||||
|
|
||||||
// fetch content
|
|
||||||
self.addEventListener('fetch', (e) => {
|
|
||||||
e.respondWith((async () => {
|
|
||||||
const r = await caches.match(e.request);
|
|
||||||
console.log(`[Service Worker] Fetching resource: ${e.request.url}`);
|
|
||||||
if (r) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
const response = await fetch(e.request);
|
|
||||||
const cache = await caches.open(cacheName);
|
|
||||||
console.log(`[Service Worker] Caching new resource: ${e.request.url}`);
|
|
||||||
cache.put(e.request, response.clone());
|
|
||||||
return response;
|
|
||||||
})());
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// activate: clear outdated files from cache
|
|
||||||
async function activate() {
|
|
||||||
const keys = await caches.keys();
|
|
||||||
await Promise.all(keys.map(key => key !== version && caches.delete(key)));
|
|
||||||
};
|
|
||||||
console.log("[Service Worker] Activate");
|
|
||||||
self.addEventListener("activate", e => e.waitUntil(activate()));
|
|
||||||