diff --git a/assets/dice/image/1.webp b/assets/dice/image/1.webp new file mode 100644 index 00000000..7cac6498 Binary files /dev/null and b/assets/dice/image/1.webp differ diff --git a/assets/dice/image/2.webp b/assets/dice/image/2.webp new file mode 100644 index 00000000..28108406 Binary files /dev/null and b/assets/dice/image/2.webp differ diff --git a/assets/dice/image/3.webp b/assets/dice/image/3.webp new file mode 100644 index 00000000..cae5a7c3 Binary files /dev/null and b/assets/dice/image/3.webp differ diff --git a/assets/dice/image/4.webp b/assets/dice/image/4.webp new file mode 100644 index 00000000..b689cbd2 Binary files /dev/null and b/assets/dice/image/4.webp differ diff --git a/assets/dice/image/5.webp b/assets/dice/image/5.webp new file mode 100644 index 00000000..e6043fcf Binary files /dev/null and b/assets/dice/image/5.webp differ diff --git a/assets/dice/image/6-crit.webp b/assets/dice/image/6-crit.webp new file mode 100644 index 00000000..f00f54a3 Binary files /dev/null and b/assets/dice/image/6-crit.webp differ diff --git a/assets/dice/image/6.webp b/assets/dice/image/6.webp new file mode 100644 index 00000000..88264398 Binary files /dev/null and b/assets/dice/image/6.webp differ diff --git a/assets/dice/image/ghost-1.webp b/assets/dice/image/ghost-1.webp new file mode 100644 index 00000000..d5b88468 Binary files /dev/null and b/assets/dice/image/ghost-1.webp differ diff --git a/assets/dice/image/ghost-2.webp b/assets/dice/image/ghost-2.webp new file mode 100644 index 00000000..1c4ba8f6 Binary files /dev/null and b/assets/dice/image/ghost-2.webp differ diff --git a/assets/dice/image/ghost-3.webp b/assets/dice/image/ghost-3.webp new file mode 100644 index 00000000..f5c14950 Binary files /dev/null and b/assets/dice/image/ghost-3.webp differ diff --git a/assets/dice/image/ghost-4.webp b/assets/dice/image/ghost-4.webp new file mode 100644 index 00000000..6789e92d Binary files /dev/null and b/assets/dice/image/ghost-4.webp differ diff --git a/assets/dice/image/ghost-5.webp b/assets/dice/image/ghost-5.webp new file mode 100644 index 00000000..144b5e84 Binary files /dev/null and b/assets/dice/image/ghost-5.webp differ diff --git a/assets/dice/image/ghost-6.webp b/assets/dice/image/ghost-6.webp new file mode 100644 index 00000000..c3c151b2 Binary files /dev/null and b/assets/dice/image/ghost-6.webp differ diff --git a/assets/dice/image/grad-1.webp b/assets/dice/image/grad-1.webp new file mode 100644 index 00000000..ae122615 Binary files /dev/null and b/assets/dice/image/grad-1.webp differ diff --git a/assets/dice/image/grad-2.webp b/assets/dice/image/grad-2.webp new file mode 100644 index 00000000..c743b40e Binary files /dev/null and b/assets/dice/image/grad-2.webp differ diff --git a/assets/dice/image/grad-3.webp b/assets/dice/image/grad-3.webp new file mode 100644 index 00000000..32a132d3 Binary files /dev/null and b/assets/dice/image/grad-3.webp differ diff --git a/assets/dice/image/grad-4.webp b/assets/dice/image/grad-4.webp new file mode 100644 index 00000000..ab763735 Binary files /dev/null and b/assets/dice/image/grad-4.webp differ diff --git a/assets/dice/image/grad-5.webp b/assets/dice/image/grad-5.webp new file mode 100644 index 00000000..c3328cbe Binary files /dev/null and b/assets/dice/image/grad-5.webp differ diff --git a/assets/dice/image/grad-6-crit.webp b/assets/dice/image/grad-6-crit.webp new file mode 100644 index 00000000..792e595d Binary files /dev/null and b/assets/dice/image/grad-6-crit.webp differ diff --git a/assets/dice/image/grad-6.webp b/assets/dice/image/grad-6.webp new file mode 100644 index 00000000..88264398 Binary files /dev/null and b/assets/dice/image/grad-6.webp differ diff --git a/css/style.min.css b/css/style.min.css index 084fabb3..3ac73553 100644 --- a/css/style.min.css +++ b/css/style.min.css @@ -2219,21 +2219,30 @@ template { position: absolute; z-index: -1; height: 100%; - width: calc(100% + 24px); transform-origin: 0% 50%; top: 0px; background: var(--csq-icon-bright); display: block; } -:root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg { + width: calc(100% + 30px); + right: -7px; + transform: skewX(-45deg); +} +:root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 30px); transform-origin: 100% 50%; + right: calc(-0.5 * var(--container-height)); + transform: skewX(45deg); } -:root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { - width: calc(100% + 40px); - margin-left: -10px; + width: calc(100% + 35px); } :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label, :root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label { @@ -2269,24 +2278,21 @@ template { :root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container { right: 100%; } -:root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg { - left: -7px; - transform: skewX(45deg); -} :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, :root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container { left: 105%; } -:root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg { - right: -7px; - transform: skewX(-45deg); +:root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container { + right: 100%; + transform: translate(0%, 0%) !important; + top: 0%; } :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, :root * .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container { right: 100%; - bottom: 12px; + transform: translate(0%, -50%) !important; + top: 50%; } :root .comp.consequence-display-container .consequence-type-container, :root * .comp.consequence-display-container .consequence-type-container { @@ -3981,18 +3987,24 @@ template { position: absolute; z-index: -1; height: 100%; - width: calc(100% + 24px); transform-origin: 0% 50%; top: 0px; background: var(--csq-icon-bright); display: block; } -:root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { +:root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg { + width: calc(100% + 30px); + right: -7px; + transform: skewX(-45deg); +} +:root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 30px); transform-origin: 100% 50%; + right: calc(-0.5 * var(--container-height)); + transform: skewX(45deg); } -:root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { - width: calc(100% + 40px); - margin-left: -10px; +:root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 35px); } :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label { position: relative; @@ -4024,20 +4036,18 @@ template { :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container { right: 100%; } -:root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg { - left: -7px; - transform: skewX(45deg); -} :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container { left: 105%; } -:root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg { - right: -7px; - transform: skewX(-45deg); +:root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container { + right: 100%; + transform: translate(0%, 0%) !important; + top: 0%; } :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container { right: 100%; - bottom: 12px; + transform: translate(0%, -50%) !important; + top: 50%; } :root body.vtt.game.system-eunos-blades #clocks-overlay .comp.consequence-display-container .consequence-type-container { position: absolute; @@ -7443,30 +7453,48 @@ template { position: absolute; z-index: -1; height: 100%; - width: calc(100% + 24px); transform-origin: 0% 50%; top: 0px; background: var(--csq-icon-bright); display: block; } -:root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg { + width: calc(100% + 30px); + right: -7px; + transform: skewX(-45deg); +} +:root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 30px); transform-origin: 100% 50%; + right: calc(-0.5 * var(--container-height)); + transform: skewX(45deg); } -:root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { - width: calc(100% + 40px); - margin-left: -10px; + width: calc(100% + 35px); } :root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label, :root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label, @@ -7514,14 +7542,6 @@ template { :root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container { right: 100%; } -:root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg { - left: -7px; - transform: skewX(45deg); -} :root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, :root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, :root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, @@ -7529,13 +7549,14 @@ template { :root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container { left: 105%; } -:root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg { - right: -7px; - transform: skewX(-45deg); +:root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root body.vtt.game.system-eunos-blades #navigation .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container { + right: 100%; + transform: translate(0%, 0%) !important; + top: 0%; } :root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, :root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, @@ -7543,7 +7564,8 @@ template { :root body.vtt.game.system-eunos-blades #hotbar .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, :root body.vtt.game.system-eunos-blades #players .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container { right: 100%; - bottom: 12px; + transform: translate(0%, -50%) !important; + top: 50%; } :root body.vtt.game.system-eunos-blades #interface .comp.consequence-display-container .consequence-type-container, :root body.vtt.game.system-eunos-blades #controls .comp.consequence-display-container .consequence-type-container, @@ -10522,30 +10544,48 @@ template { position: absolute; z-index: -1; height: 100%; - width: calc(100% + 24px); transform-origin: 0% 50%; top: 0px; background: var(--csq-icon-bright); display: block; } -:root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, +:root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg { + width: calc(100% + 30px); + right: -7px; + transform: skewX(-45deg); +} +:root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, +:root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 30px); transform-origin: 100% 50%; + right: calc(-0.5 * var(--container-height)); + transform: skewX(45deg); } -:root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, +:root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { - width: calc(100% + 40px); - margin-left: -10px; + width: calc(100% + 35px); } :root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label, :root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label, @@ -10593,14 +10633,6 @@ template { :root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container { right: 100%; } -:root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg { - left: -7px; - transform: skewX(45deg); -} :root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, :root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, :root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, @@ -10608,13 +10640,14 @@ template { :root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container { left: 105%; } -:root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, -:root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg { - right: -7px; - transform: skewX(-45deg); +:root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root body.vtt.game.system-eunos-blades #navigation #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, +:root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container { + right: 100%; + transform: translate(0%, 0%) !important; + top: 0%; } :root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, :root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, @@ -10622,7 +10655,8 @@ template { :root body.vtt.game.system-eunos-blades #hotbar #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, :root body.vtt.game.system-eunos-blades #players #chat .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container { right: 100%; - bottom: 12px; + transform: translate(0%, -50%) !important; + top: 50%; } :root body.vtt.game.system-eunos-blades #interface #chat .comp.consequence-display-container .consequence-type-container, :root body.vtt.game.system-eunos-blades #controls #chat .comp.consequence-display-container .consequence-type-container, @@ -12805,6 +12839,17 @@ template { pointer-events: auto; z-index: 20; } +:root body.vtt.game.system-eunos-blades #interface #chat #chat-controls, :root body.vtt.game.system-eunos-blades #interface #chat #chat-form, +:root body.vtt.game.system-eunos-blades #controls #chat #chat-controls, +:root body.vtt.game.system-eunos-blades #controls #chat #chat-form, +:root body.vtt.game.system-eunos-blades #navigation #chat #chat-controls, +:root body.vtt.game.system-eunos-blades #navigation #chat #chat-form, +:root body.vtt.game.system-eunos-blades #hotbar #chat #chat-controls, +:root body.vtt.game.system-eunos-blades #hotbar #chat #chat-form, +:root body.vtt.game.system-eunos-blades #players #chat #chat-controls, +:root body.vtt.game.system-eunos-blades #players #chat #chat-form { + display: none; +} :root body.vtt.game.system-eunos-blades #interface #chat, :root body.vtt.game.system-eunos-blades #interface #chat *, :root body.vtt.game.system-eunos-blades #controls #chat, @@ -12851,7 +12896,7 @@ template { :root body.vtt.game.system-eunos-blades #navigation #chat .flexrow.jump-to-bottom, :root body.vtt.game.system-eunos-blades #hotbar #chat .flexrow.jump-to-bottom, :root body.vtt.game.system-eunos-blades #players #chat .flexrow.jump-to-bottom { - bottom: 154px; + bottom: 25px; z-index: 5; } :root body.vtt.game.system-eunos-blades #interface #chat #chat-controls, :root body.vtt.game.system-eunos-blades #interface #chat #chat-form, @@ -12869,6 +12914,13 @@ template { place-self: stretch flex-end; z-index: 1; } +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message:not(.display-ok), +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message:not(.display-ok), +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message:not(.display-ok), +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message:not(.display-ok), +:root body.vtt.game.system-eunos-blades #players #chat .chat-message:not(.display-ok) { + opacity: 0 !important; +} :root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll], :root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll], :root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll], @@ -12894,32 +12946,60 @@ template { background: transparent; border: 2px ouset var(--blades-white); } -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll]:not(.active-chat-roll) .trait-label.trait-verb, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll]:not(.active-chat-roll) .trait-label.trait-verb, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll]:not(.active-chat-roll) .trait-label.trait-verb, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll]:not(.active-chat-roll) .trait-label.trait-verb, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll]:not(.active-chat-roll) .trait-label.trait-verb { +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .blades-roll > *:not(.chat-message-speaker-portrait-wrapper), +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .blades-roll > *:not(.chat-message-speaker-portrait-wrapper), +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .blades-roll > *:not(.chat-message-speaker-portrait-wrapper), +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .blades-roll > *:not(.chat-message-speaker-portrait-wrapper), +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .blades-roll > *:not(.chat-message-speaker-portrait-wrapper) { + filter: sepia(1) grayscale(0.5) brightness(0.6); +} +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .trait-label.trait-verb, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .trait-label.trait-verb, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .trait-label.trait-verb, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .trait-label.trait-verb, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .trait-label.trait-verb { display: none; } -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence { +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence { animation: none !important; } -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll]:not(.active-chat-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img { +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .consequence-icon-container .consequence-icon-circle.base-consequence img { animation: none !important; } -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll].active-chat-roll, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll].active-chat-roll, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll].active-chat-roll, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll].active-chat-roll, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].active-chat-roll { +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .chat-message-speaker-portrait-wrapper, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .chat-message-speaker-portrait-wrapper, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .chat-message-speaker-portrait-wrapper, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .chat-message-speaker-portrait-wrapper, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll]:not(.unresolved-action-roll) .chat-message-speaker-portrait-wrapper { + --border-gradient: linear-gradient(-72deg, + #565656, + #9b9b9b 16%, + #565656 21%, + #9b9b9b 24%, + #383838 27%, + #565656 36%, + #9b9b9b 45%, + #9b9b9b 60%, + #565656 72%, + #9b9b9b 80%, + #565656 84%, + #232323); + transform-origin: 50% 0%; + scale: 0.6 0.75; +} +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll].unresolved-action-roll, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll].unresolved-action-roll, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll].unresolved-action-roll, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll].unresolved-action-roll, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].unresolved-action-roll { --bg-controlled: url("../assets/animations/chat/roll-position-controlled.webp"); --bg-risky: url("../assets/animations/chat/roll-position-risky.webp"); --bg-desperate: url("../assets/animations/chat/roll-position-desperate.webp"); @@ -12934,18 +13014,18 @@ template { background: transparent; outline: none; } -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll].active-chat-roll .trait-label.trait-past-verb, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll].active-chat-roll .trait-label.trait-past-verb, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll].active-chat-roll .trait-label.trait-past-verb, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll].active-chat-roll .trait-label.trait-past-verb, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].active-chat-roll .trait-label.trait-past-verb { +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll].unresolved-action-roll .trait-label.trait-past-verb, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll].unresolved-action-roll .trait-label.trait-past-verb, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll].unresolved-action-roll .trait-label.trait-past-verb, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll].unresolved-action-roll .trait-label.trait-past-verb, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].unresolved-action-roll .trait-label.trait-past-verb { display: none; } -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll].active-chat-roll .message-content .blades-roll .dice-roll-strip, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll].active-chat-roll .message-content .blades-roll .dice-roll-strip, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll].active-chat-roll .message-content .blades-roll .dice-roll-strip, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll].active-chat-roll .message-content .blades-roll .dice-roll-strip, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].active-chat-roll .message-content .blades-roll .dice-roll-strip { +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll].unresolved-action-roll .message-content .blades-roll .dice-roll-strip, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll].unresolved-action-roll .message-content .blades-roll .dice-roll-strip, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll].unresolved-action-roll .message-content .blades-roll .dice-roll-strip, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll].unresolved-action-roll .message-content .blades-roll .dice-roll-strip, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].unresolved-action-roll .message-content .blades-roll .dice-roll-strip { margin-top: 5px; } :root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll], @@ -13000,6 +13080,19 @@ template { :root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .chat-message-speaker-portrait-wrapper, :root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll] .chat-message-speaker-portrait-wrapper, :root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .chat-message-speaker-portrait-wrapper { + --border-gradient: linear-gradient(-72deg, + #6b5630, + #9e7f46 16%, + #6b5630 21%, + #9e7f46 24%, + #46381f 27%, + #6b5630 36%, + #9e7f46 45%, + #9e7f46 60%, + #6b5630 72%, + #9e7f46 80%, + #6b5630 84%, + #2c2315); height: var(--speaker-portrait-height); width: calc(var(--speaker-portrait-height)); position: absolute; @@ -13009,7 +13102,7 @@ template { border-radius: calc(0.5 * var(--speaker-portrait-height)); scale: 0.8 1; transform-origin: 50% 50%; - background: linear-gradient(-72deg, #6b5630, #9e7f46 16%, #6b5630 21%, #9e7f46 24%, #46381f 27%, #6b5630 36%, #9e7f46 45%, #9e7f46 60%, #6b5630 72%, #9e7f46 80%, #6b5630 84%, #2c2315); + background: var(--border-gradient); background-repeat: no-repeat; outline: 3px solid black; box-shadow: 0 0 5px 5px black; @@ -13072,11 +13165,11 @@ template { :root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].action-roll + .chat-message.resistance-roll { margin-top: calc(-1 * var(--chat-vertical-gap)); } -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll].action-roll.active-chat-roll + .chat-message.resistance-roll, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll].action-roll.active-chat-roll + .chat-message.resistance-roll, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll].action-roll.active-chat-roll + .chat-message.resistance-roll, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll].action-roll.active-chat-roll + .chat-message.resistance-roll, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].action-roll.active-chat-roll + .chat-message.resistance-roll { +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll].action-roll.unresolved-action-roll + .chat-message.resistance-roll, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll].action-roll.unresolved-action-roll + .chat-message.resistance-roll, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll].action-roll.unresolved-action-roll + .chat-message.resistance-roll, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll].action-roll.unresolved-action-roll + .chat-message.resistance-roll, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll].action-roll.unresolved-action-roll + .chat-message.resistance-roll { margin-top: 0; } :root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll, @@ -13566,6 +13659,40 @@ template { padding: 4px; gap: 0; } +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label { + font-family: var(--font-emphasis-narrow); + font-size: 12px; + line-height: 12px; + display: block; + transform: translate(0%, -50%); + top: 50%; + text-align: center; + white-space: nowrap; + color: var(--side-color-secondary); +} +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong { + color: var(--side-color-secondary) !important; + font-weight: 900 !important; +} +:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state, +:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state, +:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state, +:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state, +:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state { + white-space: nowrap; + font-size: 18px; + line-height: 18px; + text-shadow: var(--text-shadow-dark-strong); + color: var(--side-color-main); +} :root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container.roll-state-container-left h4.roll-state-label, :root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container.roll-state-container-left h4.roll-state-label, :root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container.roll-state-container-left h4.roll-state-label, @@ -13580,6 +13707,7 @@ template { :root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container.roll-state-container-left h3.roll-state, :root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container.roll-state-container-left h3.roll-state { position: absolute; + transform-origin: 100% 0%; top: 5px; right: 5px; scale: var(--side-left-x-scale) 1; @@ -13601,46 +13729,12 @@ template { :root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container.roll-state-container-right h3.roll-state { width: 100%; position: absolute; + transform-origin: 0% 0%; bottom: 5px; left: 5px; text-align: left; scale: var(--side-right-x-scale) 1; } -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label { - font-family: var(--font-emphasis-narrow); - font-size: 12px; - line-height: 12px; - display: block; - transform: translate(0%, -50%); - top: 50%; - text-align: center; - white-space: nowrap; - color: var(--side-color-secondary); -} -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h4.roll-state-label strong { - color: var(--side-color-secondary) !important; - font-weight: 900 !important; -} -:root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state, -:root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state, -:root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state, -:root body.vtt.game.system-eunos-blades #hotbar #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state, -:root body.vtt.game.system-eunos-blades #players #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-state-container h3.roll-state { - white-space: nowrap; - font-size: 18px; - line-height: 18px; - transform-origin: 0% 0%; - text-shadow: var(--text-shadow-dark-strong); - color: var(--side-color-main); -} :root body.vtt.game.system-eunos-blades #interface #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-result-container, :root body.vtt.game.system-eunos-blades #controls #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-result-container, :root body.vtt.game.system-eunos-blades #navigation #chat .chat-message[class*=-roll] .message-content .blades-roll .roll-outcome-container .roll-result-container, @@ -15136,18 +15230,24 @@ template { position: absolute; z-index: -1; height: 100%; - width: calc(100% + 24px); transform-origin: 0% 50%; top: 0px; background: var(--csq-icon-bright); display: block; } -:root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { +:root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg { + width: calc(100% + 30px); + right: -7px; + transform: skewX(-45deg); +} +:root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 30px); transform-origin: 100% 50%; + right: calc(-0.5 * var(--container-height)); + transform: skewX(45deg); } -:root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { - width: calc(100% + 40px); - margin-left: -10px; +:root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 35px); } :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label { position: relative; @@ -15179,20 +15279,18 @@ template { :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container { right: 100%; } -:root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg { - left: -7px; - transform: skewX(45deg); -} :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container { left: 105%; } -:root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg { - right: -7px; - transform: skewX(-45deg); +:root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container { + right: 100%; + transform: translate(0%, 0%) !important; + top: 0%; } :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container { right: 100%; - bottom: 12px; + transform: translate(0%, -50%) !important; + top: 50%; } :root body.vtt.game.system-eunos-blades .app.window-app .comp.consequence-display-container .consequence-type-container { position: absolute; @@ -20875,6 +20973,11 @@ template { margin-right: 5px; flex-grow: 2; } +:root body.vtt.game.system-eunos-blades .app.window-app.sheet.dialog .window-content .consequence-section .roll-consequence-row input.consequence-name.consequence-name-none { + box-shadow: none; + background: none; + cursor: default; +} :root body.vtt.game.system-eunos-blades .app.window-app.sheet.dialog .window-content .consequence-section .roll-consequence-row .roll-consequence-type-select { min-width: 130px; } @@ -21583,6 +21686,16 @@ template { right: 6px; flex-basis: auto; } +:root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab.gm-roll-collab .window-content form .sheet-root .split-root .split-root-right .sheet-main.roll-consequences { + min-height: 330px; +} +:root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab.gm-roll-collab .window-content form .sheet-root .split-root .split-root-right .sheet-main.roll-consequences h3 { + margin-bottom: 10px; +} +:root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab.gm-roll-collab .window-content form .sheet-root .split-root .split-root-right .sheet-main.factor-controls { + min-height: 112px; + place-self: stretch flex-end; +} :root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab .window-header { opacity: 0; top: -45px; @@ -22000,8 +22113,8 @@ template { :root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab .window-content form .sheet-root .full-root .split-root-left.split-root-left, :root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab .window-content form .sheet-root .full-root .split-root-right.split-root-left, :root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab .window-content form .sheet-root .full-root .full-root-container.split-root-left { - flex-basis: 85%; - max-width: 85%; + flex-basis: 80%; + max-width: 80%; } :root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab .window-content form .sheet-root .split-root .split-root-left.split-root-right, :root body.vtt.game.system-eunos-blades .app.window-app.sheet.roll-collab .window-content form .sheet-root .split-root .split-root-right.split-root-right, diff --git a/css/tinymce/content.min.css b/css/tinymce/content.min.css index f4f2135f..2527a44e 100644 --- a/css/tinymce/content.min.css +++ b/css/tinymce/content.min.css @@ -1315,18 +1315,24 @@ html .comp.consequence-display-container .consequence-icon-container .consequenc position: absolute; z-index: -1; height: 100%; - width: calc(100% + 24px); transform-origin: 0% 50%; top: 0px; background: var(--csq-icon-bright); display: block; } -html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { +html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg { + width: calc(100% + 30px); + right: -7px; + transform: skewX(-45deg); +} +html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 30px); transform-origin: 100% 50%; + right: calc(-0.5 * var(--container-height)); + transform: skewX(45deg); } -html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { - width: calc(100% + 40px); - margin-left: -10px; +html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 35px); } html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label { position: relative; @@ -1358,20 +1364,18 @@ html .comp.consequence-display-container .consequence-icon-container .consequenc html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container { right: 100%; } -html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg { - left: -7px; - transform: skewX(45deg); -} html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container { left: 105%; } -html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg { - right: -7px; - transform: skewX(-45deg); +html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container { + right: 100%; + transform: translate(0%, 0%) !important; + top: 0%; } html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container { right: 100%; - bottom: 12px; + transform: translate(0%, -50%) !important; + top: 50%; } html .comp.consequence-display-container .consequence-type-container, :root .comp.consequence-display-container .consequence-type-container { position: absolute; @@ -2995,18 +2999,24 @@ html .comp.consequence-display-container .consequence-icon-container .consequenc position: absolute; z-index: -1; height: 100%; - width: calc(100% + 24px); transform-origin: 0% 50%; top: 0px; background: var(--csq-icon-bright); display: block; } -html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { +html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-accept-button-bg { + width: calc(100% + 30px); + right: -7px; + transform: skewX(-45deg); +} +html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-resist-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 30px); transform-origin: 100% 50%; + right: calc(-0.5 * var(--container-height)); + transform: skewX(45deg); } -html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { - width: calc(100% + 40px); - margin-left: -10px; +html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-armor-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-bg.consequence-special-button-bg { + width: calc(100% + 35px); } html .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container .consequence-button-label { position: relative; @@ -3038,20 +3048,18 @@ html .comp.consequence-display-container .consequence-icon-container .consequenc html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container { right: 100%; } -html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-resist-button-container .consequence-button-bg { - left: -7px; - transform: skewX(45deg); -} html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container { left: 105%; } -html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-accept-button-container .consequence-button-bg { - right: -7px; - transform: skewX(-45deg); +html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-armor-button-container { + right: 100%; + transform: translate(0%, 0%) !important; + top: 0%; } html .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container, :root .comp.consequence-display-container .consequence-icon-container .consequence-button-container.consequence-special-button-container { right: 100%; - bottom: 12px; + transform: translate(0%, -50%) !important; + top: 50%; } html .comp.consequence-display-container .consequence-type-container, :root .comp.consequence-display-container .consequence-type-container { position: absolute; diff --git a/module/BladesActor.js b/module/BladesActor.js index de4722fa..76f020c8 100644 --- a/module/BladesActor.js +++ b/module/BladesActor.js @@ -837,7 +837,12 @@ class BladesActor extends Actor { get rollPrimaryID() { return this.id; } get rollPrimaryDoc() { return this; } get rollPrimaryName() { return this.name; } - get rollPrimaryType() { return this.type; } + get rollPrimaryType() { + if (![BladesActorType.pc, BladesActorType.crew].includes(this.type)) { + throw new Error(`BladesActor of type '${this.type}' ("${this.name}") cannot be RollPrimary.`); + } + return this.type; + } get rollPrimaryImg() { return this.img; } // #region BladesCrew Implementation ~ get members() { diff --git a/module/BladesChat.js b/module/BladesChat.js index 94f18850..56c4dc90 100644 --- a/module/BladesChat.js +++ b/module/BladesChat.js @@ -8,6 +8,7 @@ class BladesChat extends ChatMessage { ApplyTooltipAnimations(html); ApplyConsequenceAnimations(html); BladesConsequence.ApplyChatListeners(html); + setTimeout(() => { html.addClass("display-ok"); }, 2000); }); return loadTemplates([ "systems/eunos-blades/templates/chat/roll-result-action-roll.hbs", diff --git a/module/BladesDialog.js b/module/BladesDialog.js index b6b5d70b..c0310c9a 100644 --- a/module/BladesDialog.js +++ b/module/BladesDialog.js @@ -1,7 +1,9 @@ import { ApplyTooltipAnimations } from "./core/gsap.js"; import U from "./core/utilities.js"; import { BladesActor, BladesPC } from "./documents/BladesActorProxy.js"; +import BladesItem from "./BladesItem.js"; import BladesRoll from "./BladesRoll.js"; +import BladesConsequence from "./sheets/roll/BladesConsequence.js"; import C, { RollResult, ConsequenceType, AttributeTrait, Position } from "./core/constants.js"; import BladesAI, { AGENTS } from "./core/ai.js"; export var SelectionCategory; @@ -30,6 +32,7 @@ export var SelectionCategory; })(SelectionCategory || (SelectionCategory = {})); export var BladesDialogType; (function (BladesDialogType) { + BladesDialogType["Input"] = "Input"; BladesDialogType["Selection"] = "Selection"; BladesDialogType["Consequence"] = "Consequence"; })(BladesDialogType || (BladesDialogType = {})); @@ -46,9 +49,39 @@ class BladesDialog extends Dialog { return loadTemplates([ "systems/eunos-blades/templates/dialog-selection.hbs", "systems/eunos-blades/templates/dialog-consequence.hbs", + "systems/eunos-blades/templates/dialog-input.hbs", "systems/eunos-blades/templates/parts/dialog-consequence-block.hbs" ]); } + static async DisplaySimpleInputDialog(parent, prompt, target, flagTarget) { + const app = new BladesDialog({ + parent, + title: parent instanceof BladesRoll ? "Roll Input" : `${parent.name}: Input`, + dialogType: BladesDialogType.Input, + content: "", + prompt, + target, + flagTarget, + buttons: { + apply: { + icon: '', + label: "Apply", + callback: (html) => app + .writeToRollInstance(html) + }, + cancel: { + icon: '', + label: game.i18n.localize("Cancel"), + callback: (html) => { + eLog.checkLog3("dialog", "Callback Scope", { this: app, html }); + return false; + } + } + }, + default: "apply" + }, { classes: ["eunos-blades", "sheet", "dialog", "simple-input-dialog"] }); + return app._render(true, { width: app.width }).then(() => eLog.checkLog3("dialog", "Input Dialog Instance", { this: app })); + } static async DisplaySelectionDialog(parent, title, docType, tabs, tags) { const app = new BladesDialog({ parent, @@ -97,12 +130,7 @@ class BladesDialog extends Dialog { }, { classes: ["eunos-blades", "sheet", "dialog", "consequence-dialog"] }); return app._render(true, { width: app.width }).then(() => eLog.checkLog3("dialog", "Dialog Instance", { this: app })); } - get template() { - if (this.dialogType === BladesDialogType.Selection) { - return "systems/eunos-blades/templates/dialog-selection.hbs"; - } - return "systems/eunos-blades/templates/dialog-consequence.hbs"; - } + get template() { return `systems/eunos-blades/templates/dialog-${U.lCase(this.dialogType)}.hbs`; } get hasItems() { return Object.values(this.tabs ?? []).some((tabItems) => tabItems.length > 0); } @@ -113,12 +141,19 @@ class BladesDialog extends Dialog { width; docType; csqData; + prompt; + target; + flagTarget; constructor(data, options) { super(data, options); this.dialogType = data.dialogType ?? BladesDialogType.Selection; this.parent = data.parent; - this.width = 500; + this.width = options?.width ?? 500; + this.prompt = data.prompt; + this.target = data.target; + this.flagTarget = data.flagTarget; switch (this.dialogType) { + case BladesDialogType.Input: return; case BladesDialogType.Selection: this.constructSelectionData(data /* , options */); return; @@ -183,11 +218,18 @@ class BladesDialog extends Dialog { getData() { const data = super.getData(); switch (this.dialogType) { + case BladesDialogType.Input: return this.prepareInputData(data); case BladesDialogType.Selection: return this.prepareSelectionData(data); case BladesDialogType.Consequence: return this.prepareConsequenceData(data); default: return null; } } + prepareInputData(data) { + data.prompt = this.prompt; + data.target = this.target; + data.flagTarget = this.flagTarget; + return data; + } prepareSelectionData(data) { data.title = this.title; data.tabs = this.tabs; @@ -225,9 +267,18 @@ class BladesDialog extends Dialog { } return {}; } - updateConsequenceData(html, cData) { - const csqElem$ = html.find(`.roll-consequence-row[data-csq-id='${cData.id}']`); // flag-target="rollCollab.consequenceData.${rollPos}.${rollResult}.${i}.attribute"]`) - // Update Type + updateInputText(inputElem$) { + const value = inputElem$.val(); + if (this.parent instanceof BladesRoll) { + const flagTarget = inputElem$.data("flagTarget"); + eLog.checkLog3("dialog", "updateInputText", { value, flagTarget }); + this.parent.setFlagVal(flagTarget, value, true); + } + else if (this.parent instanceof BladesItem || this.parent instanceof BladesActor) { + this.parent.update({ [inputElem$.data("target")]: inputElem$.val() }); + } + } + updateConsequenceType(csqElem$, cData) { const type$ = csqElem$.find(".roll-consequence-type-select"); const typeVal = type$.val(); if (typeVal && typeVal in ConsequenceType) { @@ -235,61 +286,142 @@ class BladesDialog extends Dialog { cData.icon = C.ConsequenceIcons[cData.type]; cData.typeDisplay = C.ConsequenceDisplay[cData.type]; } - // Update Resistance Attribute - if (/Resolve/.exec(cData.type)) { - cData.attribute = AttributeTrait.resolve; - } - else if (/Insight/.exec(cData.type)) { + } + updateConsequenceAttribute(csqElem$, cData) { + if (/Insight/.exec(cData.type)) { cData.attribute = AttributeTrait.insight; } else if (/Prowess/.exec(cData.type)) { cData.attribute = AttributeTrait.prowess; } + else if (/Resolve/.exec(cData.type)) { + cData.attribute = AttributeTrait.resolve; + } else { const attribute$ = csqElem$.find(".roll-consequence-attribute-select"); const attrVal = attribute$.val(); - if (attrVal && attrVal in AttributeTrait) { + if (attrVal) { cData.attribute = attrVal; - if (this.parent.rollPrimaryDoc instanceof BladesPC) { - cData.attributeVal = this.parent.rollPrimaryDoc.attributes[cData.attribute]; - } - else if (this.parent.rollPrimaryDoc?.parent instanceof BladesPC) { - cData.attributeVal = this.parent.rollPrimaryDoc.parent.attributes[cData.attribute]; + } + } + } + updateConsequenceAttributeVal(cData) { + if (this.parent.rollPrimaryDoc instanceof BladesPC) { + cData.attributeVal = this.parent.rollPrimaryDoc.attributes[cData.attribute]; + } + else if (this.parent.rollPrimaryDoc?.parent instanceof BladesPC) { + cData.attributeVal = this.parent.rollPrimaryDoc.parent.attributes[cData.attribute]; + } + else { + eLog.error(`Unable to get attribute from rollPrimaryDoc '${this.parent.rollPrimaryDoc?.name}' of type '${this.parent.rollPrimaryDoc?.rollPrimaryType}' (may need to log via flags if either of the previous show 'undefined'.`); + } + } + getSelectedResistOption(cData) { + return Object.values(cData?.resistOptions ?? {}).find((rCsq) => rCsq.isSelected) ?? false; + } + updateConsequenceResist(csqElem$, cData) { + const resistOptions = cData.resistOptions ?? {}; + // If consequence is already minimal, toggle resistNegates to true and set 'resistTo' to None-type + const minimalCsqTypes = Object.entries(C.ResistedConsequenceTypes) + .filter(([_, rCsqType]) => rCsqType === ConsequenceType.None) + .map(([csqType]) => csqType); + if (minimalCsqTypes.includes(cData.type)) { + cData.resistNegates = true; + const noneCsq = BladesConsequence.None; + cData.resistOptions = { [noneCsq.id]: noneCsq }; + cData.resistTo = noneCsq; + return; + } + else { + // Clear 'resistTo' (will be redetermined below) + delete cData.resistTo; + delete cData.resistNegates; + csqElem$.find(".consequence-resist-option").each((_, elem) => { + const resCsqID = $(elem).data("csq-id"); + resistOptions[resCsqID] ??= { id: resCsqID, name: "", type: undefined, isSelected: false }; + // Update Resistance Option Type + const resType$ = $(elem).find(".roll-consequence-type-select"); + const resTypeVal = resType$.val(); + if (resTypeVal && resTypeVal in ConsequenceType) { + resistOptions[resCsqID].type = resTypeVal; + resistOptions[resCsqID].icon = C.ConsequenceIcons[resistOptions[resCsqID].type]; + resistOptions[resCsqID].typeDisplay = C.ConsequenceDisplay[resistOptions[resCsqID].type]; } - else { - eLog.error(`Unable to get attribute from rollPrimaryDoc '${this.parent.rollPrimaryDoc?.name}' of type '${this.parent.rollPrimaryDoc?.rollPrimaryType}' (may need to log via flags if either of the previous show 'undefined'.`); + // Update Resistance Option Name + const resName$ = $(elem).find(".consequence-name"); + const resNameVal = resName$.val(); + resistOptions[resCsqID].name = resNameVal ?? ""; + // If this is selected, update 'resistTo' data as well + if (resistOptions[resCsqID].isSelected) { + cData.resistTo = resistOptions[resCsqID]; } - } + }); + } + cData.resistOptions = resistOptions; + } + updateConsequenceArmorResist(csqElem$, cData) { + // If consequence is already minimal, toggle armorNegates to true and set 'armorTo' to None-type + const minimalCsqTypes = Object.entries(C.ResistedConsequenceTypes) + .filter(([_, rCsqType]) => rCsqType === ConsequenceType.None) + .map(([csqType]) => csqType); + if (minimalCsqTypes.includes(cData.type)) { + cData.armorNegates = true; + cData.armorTo = BladesConsequence.None; + } + else { + delete cData.armorNegates; + cData.armorTo = this.getSelectedResistOption(cData); + } + } + updateConsequenceSpecialArmorResist(csqElem$, cData) { + // If consequence is already minimal, toggle specialArmorNegates to true and set 'specialArmorTo' to None-type + const minimalCsqTypes = Object.entries(C.ResistedConsequenceTypes) + .filter(([_, rCsqType]) => rCsqType === ConsequenceType.None) + .map(([csqType]) => csqType); + if (minimalCsqTypes.includes(cData.type)) { + cData.specialArmorNegates = true; + cData.specialArmorTo = BladesConsequence.None; } + else { + delete cData.specialArmorNegates; + cData.specialArmorNegates ??= false; + cData.specialArmorTo = this.getSelectedResistOption(cData); + } + } + updateConsequenceData(html, cData) { + const csqElem$ = html.find(`.roll-consequence-row[data-csq-id='${cData.id}']`); + // Update Type + this.updateConsequenceType(csqElem$, cData); // Update Name - const name$ = csqElem$.find(".consequence-name"); - const nameVal = name$.val(); - cData.name = nameVal ?? ""; + if (cData.type === ConsequenceType.None) { + cData.name = ""; + } + else { + const name$ = csqElem$.find(".consequence-name"); + const nameVal = name$.val(); + cData.name = nameVal ?? ""; + } + // Update Resistance Attribute + this.updateConsequenceAttribute(csqElem$, cData); + this.updateConsequenceAttributeVal(cData); // Update Resistance Options - const resistOptions = cData.resistOptions ?? {}; - // Clear 'resistTo' (will be redetermined below) - delete cData.resistTo; - csqElem$.find(".consequence-resist-option").each((_, elem) => { - const resCsqID = $(elem).data("csq-id"); - resistOptions[resCsqID] ??= { id: resCsqID, name: "", type: undefined, isSelected: false }; - // Update Resistance Option Type - const resType$ = $(elem).find(".roll-consequence-type-select"); - const resTypeVal = resType$.val(); - if (resTypeVal && resTypeVal in ConsequenceType) { - resistOptions[resCsqID].type = resTypeVal; - resistOptions[resCsqID].icon = C.ConsequenceIcons[resistOptions[resCsqID].type]; - resistOptions[resCsqID].typeDisplay = C.ConsequenceDisplay[resistOptions[resCsqID].type]; - } - // Update Resistance Option Name - const resName$ = $(elem).find(".consequence-name"); - const resNameVal = resName$.val(); - resistOptions[resCsqID].name = resNameVal ?? ""; - // If this is selected, update 'resistTo' data as well - if (resistOptions[resCsqID].isSelected) { - cData.resistTo = resistOptions[resCsqID]; - } - }); - cData.resistOptions = resistOptions; + this.updateConsequenceResist(csqElem$, cData); + // Update Armor Options + if (this.parent.canResistWithArmor(cData)) { + cData.isDisplayingArmorToggle = true; + this.updateConsequenceArmorResist(csqElem$, cData); + } + else { + cData.isDisplayingArmorToggle = false; + } + // Update Special Armor Options + if (this.parent.canResistWithSpecialArmor(cData)) { + cData.isDisplayingSpecialArmorToggle = true; + this.updateConsequenceSpecialArmorResist(csqElem$, cData); + } + else { + cData.isDisplayingSpecialArmorToggle = false; + } return cData; } updateConsequenceDialog(html, isRendering = true) { @@ -325,6 +457,14 @@ class BladesDialog extends Dialog { } } _consequenceAI; + getCsqDataFromElem(elem, paramCount = 3) { + const dataAction = elem.dataset.action; + if (dataAction) { + const params = dataAction.split(/-/).reverse().slice(0, paramCount); + return params.reverse(); + } + return []; + } async queryAI(event) { if (!this.csqData) { return; @@ -333,19 +473,32 @@ class BladesDialog extends Dialog { if (!this._consequenceAI) { this._consequenceAI = new BladesAI(AGENTS.ConsequenceAdjuster); } - // Get the name of the consequence. - const dataAction = event.currentTarget.dataset.action; - if (dataAction && dataAction.startsWith("ai-query")) { - const [rollPosition, rollResult, csqID] = dataAction.split(/-/).slice(2); - const csqName = this.csqData[rollPosition][rollResult][csqID]?.name; - if (csqName) { - const response = await this._consequenceAI?.query(csqName, csqName); - if (response) { - this.refreshResistanceOptions(rollPosition, rollResult, csqID, response.split("|")); - } + const [rollPosition, rollResult, csqID] = this.getCsqDataFromElem(event.currentTarget); + const csqName = this.csqData[rollPosition][rollResult][csqID]?.name; + if (csqName) { + const response = await this._consequenceAI?.query(csqName, csqName); + if (response) { + this.refreshResistanceOptions(rollPosition, rollResult, csqID, response.split("|")); } } } + async spawnBlankResistOption(event) { + if (!this.csqData) { + return; + } + const [rollPosition, rollResult, csqID] = this.getCsqDataFromElem(event.currentTarget); + const rCsqID = randomID(); + this.csqData[rollPosition][rollResult][csqID] + .resistOptions = { + [rCsqID]: { + id: rCsqID, + name: "", + type: undefined, + isSelected: true + } + }; + this.render(); + } async setFlagVal(target, value) { if (this.parent instanceof BladesRoll) { return this.parent.setFlagVal(target, value, false); @@ -383,49 +536,85 @@ class BladesDialog extends Dialog { if (!this.csqData) { return; } - eLog.checkLog3("dialog", "Clicked Resistance Option", event); - const dataAction = event.currentTarget.dataset.action; - if (dataAction && dataAction.startsWith("gm-select-toggle")) { - const [rollPosition, rollResult, csqIndex, resIndex] = dataAction.split(/-/).slice(3); - eLog.checkLog3("dialog", "... Action Passed", { rollResult, csqIndex, resIndex }); - // Get consequence data - const cData = this.csqData[rollPosition][rollResult][csqIndex]; - cData.resistOptions ??= {}; - // Toggle clicked resistance option - cData.resistOptions[resIndex].isSelected = !cData.resistOptions[resIndex].isSelected; - // If resistance option is now selected... - if (cData.resistOptions[resIndex].isSelected) { - // ... deselect other options - Object.keys(cData.resistOptions) - .filter((key) => key !== resIndex) - .forEach((key) => { - cData.resistOptions[key].isSelected = false; - }); - // ... and set 'resistTo' to this consequence. - cData.resistTo = cData.resistOptions[resIndex]; - } - else { - // Otherwise, set 'resistTo' to false. - cData.resistTo = false; - } - // Assign new cData instance. - this.csqData[rollPosition][rollResult][csqIndex] = cData; - this.render(); + const [rollPosition, rollResult, csqID, resID] = this.getCsqDataFromElem(event.currentTarget, 4); + eLog.checkLog3("dialog", "... Action Passed", { rollResult, csqIndex: csqID, resIndex: resID }); + // Get consequence data + const cData = this.csqData[rollPosition][rollResult][csqID]; + cData.resistOptions ??= {}; + // Toggle clicked resistance option + cData.resistOptions[resID].isSelected = !cData.resistOptions[resID].isSelected; + // If resistance option is now selected... + if (cData.resistOptions[resID].isSelected) { + // ... deselect & hide other options + Object.keys(cData.resistOptions) + .filter((key) => key !== resID) + .forEach((key) => { + Object.assign(cData.resistOptions?.[key] ?? {}, { isSelected: false, isVisible: false }); + }); + // ... and set 'resistTo' to this consequence. + cData.resistTo = cData.resistOptions[resID]; } + else { + // Otherwise, set 'resistTo' to false... + cData.resistTo = false; + // ... and unhide other options. + Object.keys(cData.resistOptions) + .filter((key) => key !== resID) + .forEach((key) => { + Object.assign(cData.resistOptions?.[key] ?? {}, { isVisible: true }); + }); + } + // Assign new cData instance. + this.csqData[rollPosition][rollResult][csqID] = cData; + this.render(); + } + async clearResistOptions(event) { + if (!this.csqData) { + return; + } + const [rollPosition, rollResult, csqID] = this.getCsqDataFromElem(event.currentTarget); + this.csqData[rollPosition][rollResult][csqID].resistOptions = {}; + this.render(); + } + async toggleArmor(event) { + if (!this.csqData) { + return; + } + const [rollPosition, rollResult, csqID] = this.getCsqDataFromElem(event.currentTarget); + const cData = this.csqData[rollPosition][rollResult][csqID]; + cData.canArmor = !cData.canArmor; + this.render(); + } + async toggleSpecialArmor(event) { + if (!this.csqData) { + return; + } + const [rollPosition, rollResult, csqID] = this.getCsqDataFromElem(event.currentTarget); + const cData = this.csqData[rollPosition][rollResult][csqID]; + cData.canSpecialArmor = !cData.canSpecialArmor; + this.render(); } activateListeners(html) { super.activateListeners(html); // ~ Tooltips ApplyTooltipAnimations(html); switch (this.dialogType) { + case BladesDialogType.Input: + this.activateInputListeners(html); + break; case BladesDialogType.Selection: this.activateSelectionListeners(html); break; - case BladesDialogType.Consequence: + case BladesDialogType.Consequence: { this.activateConsequenceListeners(html); + // Select --> updateConsequenceDialog -> updateConsequenceData(each csq) break; + } } } + activateInputListeners(html) { + html.find("textarea").on({ change: (event) => this.updateInputText($(event.currentTarget)) }); + } activateSelectionListeners(html) { const self = this; // ~ Changing Width on Tab Change Depending on Number of Items @@ -458,8 +647,17 @@ class BladesDialog extends Dialog { activateConsequenceListeners(html) { html.find("input").on({ change: () => this.updateConsequenceDialog(html) }); html.find("select").on({ change: () => this.updateConsequenceDialog(html) }); - html.find('[data-action^="ai-query"]').on({ click: (event) => this.queryAI(event) }); + html.find('[data-action^="ai-query"]').on({ + click: (event) => this.queryAI(event), + contextmenu: (event) => this.clearResistOptions(event) + }); + html.find('[data-action^="blank-option"]').on({ + click: (event) => this.spawnBlankResistOption(event), + contextmenu: (event) => this.clearResistOptions(event) + }); html.find('[data-action^="gm-select-toggle"]').on({ click: (event) => this.selectResistOption(event) }); + html.find('[data-action^="toggle-armor"]').on({ click: (event) => this.toggleArmor(event) }); + html.find('[data-action^="toggle-special"]').on({ click: (event) => this.toggleSpecialArmor(event) }); } } export default BladesDialog; diff --git a/module/BladesItem.js b/module/BladesItem.js index e13d5731..df11b533 100644 --- a/module/BladesItem.js +++ b/module/BladesItem.js @@ -171,7 +171,17 @@ class BladesItem extends Item { get rollPrimaryID() { return this.id; } get rollPrimaryDoc() { return this; } get rollPrimaryName() { return this.name; } - get rollPrimaryType() { return this.type; } + get rollPrimaryType() { + if (![ + BladesItemType.cohort_gang, + BladesItemType.cohort_expert, + BladesItemType.gm_tracker, + BladesItemType.score + ].includes(this.type)) { + throw new Error(`BladesItem of type '${this.type}' ("${this.name}") cannot be RollPrimary.`); + } + return this.type; + } get rollPrimaryImg() { return this.img; } get rollModsData() { // Const rollModData = BladesRollMod.ParseDocRollMods(this); @@ -211,7 +221,21 @@ class BladesItem extends Item { get rollOppImg() { return this.img; } get rollOppName() { return this.name; } get rollOppSubName() { return ""; } - get rollOppType() { return this.type; } + get rollOppType() { + if (![ + BladesItemType.cohort_gang, + BladesItemType.cohort_expert, + BladesItemType.gm_tracker, + BladesItemType.score, + BladesItemType.location, + BladesItemType.project, + BladesItemType.design, + BladesItemType.ritual + ].includes(this.type)) { + throw new Error(`BladesItem of type '${this.type}' ("${this.name}") cannot be RollOpposition.`); + } + return this.type; + } get rollOppModsData() { return []; } // #endregion // #region BladesRoll.ParticipantDoc Implementation @@ -219,7 +243,16 @@ class BladesItem extends Item { get rollParticipantDoc() { return this; } get rollParticipantIcon() { return this.img; } get rollParticipantName() { return this.name; } - get rollParticipantType() { return this.type; } + get rollParticipantType() { + if (![ + BladesItemType.cohort_gang, + BladesItemType.cohort_expert, + BladesItemType.gm_tracker + ].includes(this.type)) { + throw new Error(`BladesItem of type '${this.type}' ("${this.name}") cannot be RollParticipant.`); + } + return this.type; + } get rollParticipantModsData() { return []; } // #endregion // #endregion @@ -309,12 +342,12 @@ class BladesItem extends Item { const expClueData = {}; [...Object.values(system.experience_clues).filter((clue) => /[A-Za-z]/.test(clue)), " "].forEach((clue, i) => { expClueData[(i + 1).toString()] = clue; }); system.experience_clues = expClueData; - eLog.checkLog3("experienceClues", { expClueData }); + // eLog.checkLog3("experienceClues", {expClueData}) if (BladesItem.IsType(this, BladesItemType.playbook)) { const gatherInfoData = {}; [...Object.values(system.gather_info_questions).filter((question) => /[A-Za-z]/.test(question)), " "].forEach((question, i) => { gatherInfoData[(i + 1).toString()] = question; }); system.gather_info_questions = gatherInfoData; - eLog.checkLog3("gatherInfoQuestions", { gatherInfoData }); + // eLog.checkLog3("gatherInfoQuestions", {gatherInfoData}); } } } diff --git a/module/BladesRoll.js b/module/BladesRoll.js index 03a8387b..85598b0b 100644 --- a/module/BladesRoll.js +++ b/module/BladesRoll.js @@ -1,6 +1,6 @@ // #region IMPORTS ~ import U from "./core/utilities.js"; -import C, { BladesActorType, BladesItemType, RollPermissions, RollType, RollSubType, RollModStatus, RollModSection, ActionTrait, DowntimeAction, AttributeTrait, Position, Effect, Factor, RollResult, RollPhase, ConsequenceType, Tag } from "./core/constants.js"; +import C, { BladesActorType, BladesItemType, BladesPhase, RollPermissions, RollType, RollSubType, RollModStatus, RollModSection, ActionTrait, DowntimeAction, AttributeTrait, Position, Effect, Factor, RollResult, RollPhase, ConsequenceType, Tag } from "./core/constants.js"; import { BladesActor, BladesPC, BladesCrew } from "./documents/BladesActorProxy.js"; import { BladesItem, BladesGMTracker } from "./documents/BladesItemProxy.js"; import { ApplyTooltipAnimations, ApplyConsequenceAnimations } from "./core/gsap.js"; @@ -522,6 +522,10 @@ class BladesRollMod { return BladesActor.IsType(rollPrimaryDoc, BladesActorType.pc) && rollPrimaryDoc.system.stress.max - rollPrimaryDoc.system.stress.value >= val; } + case "Heat": { + return (BladesPC.IsType(rollPrimaryDoc) && BladesCrew.IsType(rollPrimaryDoc.crew)) + || BladesCrew.IsType(rollPrimaryDoc); + } default: throw new Error(`Unrecognize Payable Key: ${traitStr}`); } }); @@ -758,7 +762,6 @@ class BladesRollPrimary { || BladesItem.IsType(doc, BladesItemType.cohort_expert, BladesItemType.cohort_gang, BladesItemType.gm_tracker); } // #endregion - rollInstance; rollPrimaryID; _rollPrimaryDoc; get rollPrimaryDoc() { @@ -812,18 +815,78 @@ class BladesRollPrimary { return this.rollPrimaryDoc.applyWorsePosition(); } } + get hasArmor() { + if (!this.rollPrimaryDoc) { + return false; + } + if (this.rollPrimaryType === BladesActorType.pc) { + const rollPrimaryDoc = this.rollPrimaryDoc; + // Can PC spend normal armor? + if (!rollPrimaryDoc.system.armor.checked.light + && (rollPrimaryDoc.system.armor.active.light + || rollPrimaryDoc.remainingLoad >= 2)) { + return true; + } + // Otherwise, can PC spend heavy armor? + if (!rollPrimaryDoc.system.armor.checked.heavy + && (rollPrimaryDoc.system.armor.active.heavy + || rollPrimaryDoc.remainingLoad >= 3)) { + return true; + } + } + if (BladesItem.IsType(this.rollPrimaryDoc, BladesItemType.cohort_gang, BladesItemType.cohort_expert)) { + const { value, max } = this.rollPrimaryDoc.system.armor; + return max - value > 1; + } + return false; + } + get hasSpecialArmor() { + if (!this.rollPrimaryDoc) { + return false; + } + if (!BladesPC.IsType(this.rollPrimaryDoc)) { + return false; + } + if (!this.rollPrimaryDoc.system.armor.active.special) { + return false; + } + if (this.rollPrimaryDoc.system.armor.checked.special) { + return false; + } + return true; + } + async spendArmor() { + if (this.hasArmor) { + if (BladesPC.IsType(this.rollPrimaryDoc)) { + if (this.rollPrimaryDoc.system.armor.checked.light) { + await this.rollPrimaryDoc.update({ "system.armor.checked.heavy": true }); + } + else { + await this.rollPrimaryDoc.update({ "system.armor.checked.light": true }); + } + } + else if (BladesItem.IsType(this.rollPrimaryDoc, BladesItemType.cohort_gang, BladesItemType.cohort_expert)) { + await this.rollPrimaryDoc.update({ "system.armor.value": this.rollPrimaryDoc.system.armor.value + 1 }); + } + } + } + async spendSpecialArmor() { + if (this.hasSpecialArmor) { + await this.rollPrimaryDoc.update({ "system.armor.checked.special": true }); + } + } // #region Constructor ~ - constructor(rollInstance, { rollPrimaryID, rollPrimaryName, rollPrimaryType, rollPrimaryImg, rollModsData, rollFactors }) { + constructor(rollInstance, { rollPrimaryID, rollPrimaryName, rollPrimaryType, rollPrimaryImg, rollModsData, rollFactors } = {}) { // Identify ID, Doc, Name, SubName, Type & Image, to best of ability - this.rollInstance = rollInstance; + // this.rollInstance = rollInstance; this.rollPrimaryID = rollPrimaryID - ?? this.rollInstance.rollPrimary.rollPrimaryID - ?? this.rollInstance.rollPrimary.rollPrimaryDoc?.rollPrimaryID; - rollPrimaryName ??= this.rollInstance.rollPrimary.rollPrimaryName; - rollPrimaryType ??= this.rollInstance.rollPrimary.rollPrimaryType; - rollPrimaryImg ??= this.rollInstance.rollPrimary.rollPrimaryImg; - rollModsData ??= this.rollInstance.rollPrimary.rollModsData; - rollFactors ??= this.rollInstance.rollPrimary.rollFactors; + ?? rollInstance?.rollPrimary.rollPrimaryID + ?? rollInstance?.rollPrimary.rollPrimaryDoc?.rollPrimaryID; + rollPrimaryName ??= rollInstance?.rollPrimary.rollPrimaryName; + rollPrimaryType ??= rollInstance?.rollPrimary.rollPrimaryType; + rollPrimaryImg ??= rollInstance?.rollPrimary.rollPrimaryImg; + rollModsData ??= rollInstance?.rollPrimary.rollModsData; + rollFactors ??= rollInstance?.rollPrimary.rollFactors; if (BladesRollPrimary.IsDoc(this.rollPrimaryDoc)) { this.rollPrimaryName = rollPrimaryName ?? this.rollPrimaryDoc.rollPrimaryName; this.rollPrimaryType = this.rollPrimaryDoc.rollPrimaryType; @@ -914,8 +977,21 @@ class BladesRollOpposition { rollOppImg; rollOppModsData; rollFactors; + _clockData; + get clockData() { return this._clockData ?? {}; } + set clockData(val) { + val.id ??= randomID(); + val.display ??= ""; + val.value ??= 0; + val.max ??= 8; + val.color ??= "white"; + val.isActive = true; + val.isNameVisible = false; + val.isVisible = true; + this._clockData = val; + } // #region Constructor ~ - constructor(rollInstance, { rollOppID, rollOppDoc, rollOppName, rollOppSubName, rollOppType, rollOppImg, rollOppModsData, rollFactors } = {}) { + constructor(rollInstance, { rollOppID, rollOppDoc, rollOppName, rollOppSubName, rollOppType, rollOppImg, rollOppModsData, rollFactors, rollOppClock } = {}) { this.rollInstance = rollInstance; // Attempt to fetch an associated BladesActor or BladesItem document const doc = BladesRollOpposition.GetDoc(rollOppDoc ?? rollOppID ?? rollOppName); @@ -940,9 +1016,6 @@ class BladesRollOpposition { if (!rollOppName) { throw new Error("Must include a rollOppName when constructing a BladesRollOpposition object."); } - if (!rollOppSubName) { - throw new Error("Must include a rollOppSubName when constructing a BladesRollOpposition object."); - } if (!rollOppType) { throw new Error("Must include a rollOppType when constructing a BladesRollOpposition object."); } @@ -957,6 +1030,9 @@ class BladesRollOpposition { this.rollOppImg = rollOppImg ?? ""; this.rollOppModsData = rollOppModsData ?? []; this.rollFactors = rollFactors; + if (rollOppClock) { + this.clockData = rollOppClock; + } } // #endregion get flagParams() { @@ -970,7 +1046,8 @@ class BladesRollOpposition { rollOppType: this.rollOppType, rollOppImg: this.rollOppImg, rollOppModsData: this.rollOppModsData, - rollFactors: this.rollFactors + rollFactors: this.rollFactors, + rollOppClock: this.clockData }; } async updateRollFlags() { @@ -1463,7 +1540,7 @@ class BladesRoll extends DocumentSheet { } static async PrepareActionRoll(rollID, config) { // Validate the rollTrait - if (!(U.isInt(config.rollTrait) || U.lCase(config.rollTrait) in { ...ActionTrait, ...Factor })) { + if (!(config.rollTrait === "" || U.isInt(config.rollTrait) || U.lCase(config.rollTrait) in { ...ActionTrait, ...Factor })) { throw new Error(`[PrepareActionRoll()] Bad RollTrait for Action Roll: ${config.rollTrait}`); } // Retrieve the roll users @@ -1699,6 +1776,7 @@ class BladesRoll extends DocumentSheet { _rollPrimary; _rollOpposition; _rollParticipants; + projectSelectOptions; constructor(userID, rollID, rollPermission) { const rollUser = game.users.get(userID); if (!rollUser) { @@ -1712,6 +1790,11 @@ class BladesRoll extends DocumentSheet { if (rollFlagData.rollOppData) { this._rollOpposition = new BladesRollOpposition(this, rollFlagData.rollOppData); } + else if (rollFlagData.rollDowntimeAction === DowntimeAction.LongTermProject) { + this.projectSelectOptions = Array.from(game.items) + .filter((item) => BladesItem.IsType(item, BladesItemType.project)) + .map((project) => ({ value: project.id ?? "", display: project.name })); + } if (rollFlagData.rollParticipantData) { this._rollParticipants = {}; for (const [rollSection, rollParticipantList] of Object.entries(rollFlagData.rollParticipantData)) { @@ -1952,18 +2035,18 @@ class BladesRoll extends DocumentSheet { } getFlagVal(flagKey) { if (flagKey) { - return this.document.getFlag(C.SYSTEM_ID, `rollCollab.${flagKey}`); + return this.document.getFlag(C.SYSTEM_ID, `rollCollab.${flagKey}`.replace(/(rollCollab\.)+/g, "rollCollab.")); } return this.document.getFlag(C.SYSTEM_ID, "rollCollab"); } async setFlagVal(flagKey, flagVal, isRerendering = true) { - await this.document.setFlag(C.SYSTEM_ID, `rollCollab.${flagKey}`, flagVal); + await this.document.setFlag(C.SYSTEM_ID, `rollCollab.${flagKey}`.replace(/(rollCollab\.)+/g, "rollCollab."), flagVal); if (isRerendering) { socketlib.system.executeForEveryone("renderRollCollab", this.rollID); } } async clearFlagVal(flagKey, isRerendering = true) { - await this.document.unsetFlag(C.SYSTEM_ID, `rollCollab.${flagKey}`); + await this.document.unsetFlag(C.SYSTEM_ID, `rollCollab.${flagKey}`.replace(/(rollCollab\.)+/g, "rollCollab.")); if (isRerendering) { socketlib.system.executeForEveryone("renderRollCollab", this.rollID); } @@ -2370,6 +2453,18 @@ class BladesRoll extends DocumentSheet { return [...this._rollMods].sort((modA, modB) => this.compareMods(modA, modB)); } set rollMods(val) { this._rollMods = val; } + canResistWithArmor(csqData) { + if (!this.rollPrimary.hasArmor) { + return false; + } + return csqData.attribute === AttributeTrait.prowess; + } + canResistWithSpecialArmor(_csqData) { + if (!BladesPC.IsType(this.rollPrimary.rollPrimaryDoc)) { + return false; + } + return this.rollPrimary.rollPrimaryDoc.armorStatus.special; + } // #endregion // #region CONSEQUENCES: Getting, Accepting, Resisting get _csqData() { @@ -2407,6 +2502,147 @@ class BladesRoll extends DocumentSheet { const sheetData = this.getSheetData(this.getIsGM(), this.getRollCosts()); return { ...context, ...sheetData }; } + getFortuneRollModsData() { + const modsData = []; + if (this.rollSubType === RollSubType.Engagement) { + modsData.push({ + id: "BoldPlan-positive-roll", + name: "Bold Plan", + section: RollModSection.roll, + base_status: RollModStatus.ToggledOff, + posNeg: "positive", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

" + }); + modsData.push({ + id: "ComplexPlan-negative-roll", + name: "Complex Plan", + section: RollModSection.roll, + base_status: RollModStatus.ToggledOff, + posNeg: "negative", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

" + }); + modsData.push({ + id: "ExploitWeakness-positive-roll", + name: "Exploiting a Weakness", + section: RollModSection.roll, + base_status: RollModStatus.ToggledOff, + posNeg: "positive", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

" + }); + modsData.push({ + id: "WellDefended-negative-roll", + name: "Well-Defended", + section: RollModSection.roll, + base_status: RollModStatus.ToggledOff, + posNeg: "negative", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

" + }); + modsData.push({ + id: "HelpFromFriend-positive-roll", + name: "Help From a Friend", + section: RollModSection.position, + base_status: RollModStatus.ToggledOff, + posNeg: "positive", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

Help From a Friend

Add +1d if you enlist the help of a friend or contact.

" + }); + modsData.push({ + id: "EnemyInterference-negative-roll", + name: "Enemy Interference", + section: RollModSection.roll, + base_status: RollModStatus.ToggledOff, + posNeg: "negative", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

" + }); + } + return modsData; + } + getDowntimeActionRollModsData() { + const modsData = []; + modsData.push({ + id: "HelpFromFriend-positive-roll", + name: "Help From a Friend", + section: RollModSection.position, + base_status: RollModStatus.ToggledOff, + posNeg: "positive", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

Help From a Friend

Add +1d if you enlist the help of a friend or contact.

" + }); + if (this.rollDowntimeAction !== DowntimeAction.IndulgeVice) { + modsData.push({ + id: "CanBuyResultLevel-positive-after", + name: "Buying Result Level", + section: RollModSection.after, + base_status: RollModStatus.ForcedOn, + posNeg: "positive", + modType: "general", + value: 0, + effectKeys: [], + tooltip: "

Buying Result Level

After your roll, you can increase the result level by one for each Coin you spend.

" + }); + } + switch (this.rollDowntimeAction) { + case DowntimeAction.AcquireAsset: { + modsData.push({ + id: "RepeatPurchase-positive-roll", + name: "Repeat Purchase", + section: RollModSection.roll, + base_status: RollModStatus.ToggledOff, + posNeg: "positive", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

Repeat Purchase Bonus

Add +1d if you have previously acquired this asset or service with a Acquire Asset Downtime activity.

" + }); + modsData.push({ + id: "RestrictedItem-negative-after", + name: "Restricted", + section: RollModSection.after, + base_status: RollModStatus.Hidden, + posNeg: "negative", + modType: "general", + value: 0, + effectKeys: ["Cost-Heat2"], + tooltip: "

Restricted

Whether contraband goods or dangerous materials, this Acquire Asset Downtime activity will add +2 Heat to your crew.

" + }); + break; + } + default: break; + } + /* + modsData.push({ + id: "--", + name: "", + section: RollModSection, + base_status: RollModStatus, + posNeg: "", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

" + }) + */ + return modsData; + } /** * Gets the roll modifications data. * @returns {BladesRoll.RollModData[]} The roll modifications data. @@ -2416,18 +2652,30 @@ class BladesRoll extends DocumentSheet { ...BladesRoll.DefaultRollMods, ...this.rollPrimary.rollModsData ]; - if (this.rollType === RollType.Action && this.rollPrimary.isWorsePosition) { - defaultMods.push({ - id: "WorsePosition-negative-position", - name: "Worse Position", - section: RollModSection.position, - base_status: RollModStatus.ForcedOn, - posNeg: "negative", - modType: "general", - value: 1, - effectKeys: [], - tooltip: "

Worse Position

A Consequence on a previous roll has worsened your Position.

" - }); + if (this.rollDowntimeAction) { + defaultMods.push(...this.getDowntimeActionRollModsData()); + } + if (this.rollType === RollType.Action) { + if (this.rollPrimary.isWorsePosition) { + defaultMods.push({ + id: "WorsePosition-negative-position", + name: "Worse Position", + section: RollModSection.position, + base_status: RollModStatus.ForcedOn, + posNeg: "negative", + modType: "general", + value: 1, + effectKeys: [], + tooltip: "

Worse Position

A Consequence on a previous roll has worsened your Position.

" + }); + } + switch (this.rollDowntimeAction) { + case DowntimeAction.AcquireAsset: { + defaultMods.push(); + break; + } + default: break; + } } if (this.rollType === RollType.Action && this.acceptedConsequences.some((csq) => csq.type === ConsequenceType.ReducedEffect)) { @@ -2535,6 +2783,7 @@ class BladesRoll extends DocumentSheet { const GMBoostsData = this.calculateGMBoostsData(rData); const positionEffectTradeData = this.calculatePositionEffectTradeData(); const userPermission = U.objFindKey(baseData.userPermissions, (v) => v.includes(game.user.id ?? "")); + // const downtimeData = this.processDowntimeActions(); return { ...baseData, ...(this.rollPrimary.rollPrimaryDoc ? { rollPrimary: this.rollPrimary.rollPrimaryDoc } : {}), @@ -2543,9 +2792,36 @@ class BladesRoll extends DocumentSheet { ...rollResultData, ...GMBoostsData, ...positionEffectTradeData, - userPermission + // ...downtimeData, + userPermission, + gamePhase: game.eunoblades.Tracker?.phase || BladesPhase.Freeplay }; } + // type BladesSelectOption = { + // value: valueType, + // display: displayType + // }; + // private processDowntimeActions() { + // const downtimeData: Record; + // if (BladesActor.IsType(this.rollPrimary.rollPrimaryDoc, BladesActorType.pc)) { + // downtimeData.canDoDowntimeActions = true; + // downtimeData.downtimeActionsRemaining = this.rollPrimary.rollPrimaryDoc.remainingDowntimeActions; + // const availableDowntimeActions: DowntimeAction[] = []; + // if (this.rollType === RollType.Action) { + // availableDowntimeActions.push(...[ + // DowntimeAction.AcquireAsset, + // DowntimeAction.LongTermProject, + // DowntimeAction.Recover, + // DowntimeAction.ReduceHeat + // ]); + // } else if (this.rollType === RollType.Fortune) { + // availableDowntimeActions.push(...[ + // DowntimeAction. + // ]) + // } + // downtimeData.downtimeActionOptions = + // downtimeActionOptions?: Array + // } calculatePositionData(finalPosition) { return { rollPositions: Object.values(Position), @@ -2798,7 +3074,24 @@ class BladesRoll extends DocumentSheet { return this.isRollingZero ? this.dieVals.slice(1) : this.dieVals; } getDieClass(val, i) { - eLog.checkLog3("rollCollab", `getDieClass(${val}, ${i})`, { inst: this }); + switch (this.rollType) { + case RollType.Resistance: { + if (val === 6 && i <= 1 && this.rollResult === -1) { + return "blades-die-critical"; + } + if (i === 0) { + return "blades-die-resistance"; + } + return "blades-die-fail"; + } + case RollType.IndulgeVice: { + if (i === 0) { + return "blades-die-indulge-vice"; + } + return "blades-die-fail"; + } + default: break; + } if (val === 6 && i <= 1 && this.rollResult === RollResult.critical) { val++; } @@ -2813,28 +3106,32 @@ class BladesRoll extends DocumentSheet { "blades-die-critical" ][val]; } + getDieImage(val, i, isGhost = false) { + let imgPath = "systems/eunos-blades/assets/dice/image/"; + if (isGhost) { + imgPath += "ghost-"; + } + else if ([RollType.Resistance, RollType.IndulgeVice].includes(this.rollType) + || this.rollDowntimeAction) { + imgPath += "grad-"; + } + imgPath += val; + if (!isGhost && val === 6 && i <= 1 && this.isCritical) { + imgPath += "-crit"; + } + imgPath += ".webp"; + return imgPath; + } get dieValsHTML() { eLog.checkLog3("rollCollab", "[get dieValsHTML()]", { roll: this, dieVals: this.dieVals }); const dieVals = [...this.dieVals]; const ghostNum = this.isRollingZero ? dieVals.shift() : null; - if (this.rollType === RollType.Resistance) { - const numHighlightedDice = this.rollResult === RollResult.critical ? 2 : 1; - const highlightClass = this.rollResult === RollResult.critical ? "blades-die-critical" : "blades-die-resistance"; - return [ - ...dieVals.map((val, i) => ``), - ghostNum ? `` : null - ] - .filter((val) => typeof val === "string") - .join(""); - } - else { - return [ - ...dieVals.map((val, i) => ``), - ghostNum ? `` : null - ] - .filter((val) => typeof val === "string") - .join(""); - } + return [ + ...dieVals.map((val, i) => ``), + ghostNum ? `` : null + ] + .filter((val) => typeof val === "string") + .join(""); } // #endregion // #region RESULT GETTERS ~ @@ -2897,6 +3194,7 @@ class BladesRoll extends DocumentSheet { await this.setRollPhase(RollPhase.Complete); } // Apply Stress & Special Armor Costs + eLog.checkLog2("bladesRoll", "Costs", this.getRollCosts()); if (BladesPC.IsType(this.rollPrimaryDoc)) { const rollCostData = this.getRollCosts(); const stressCost = this.getTotalStressCost(this.getStressCosts(rollCostData)); @@ -2921,7 +3219,7 @@ class BladesRoll extends DocumentSheet { if (csqID && chatID) { const resistedCsq = await BladesConsequence.GetFromID(chatID, csqID); if (resistedCsq) { - await resistedCsq.applyResistedConsequence(); + await resistedCsq.applyResistedConsequence("resist"); } } if (BladesPC.IsType(this.rollPrimaryDoc)) { @@ -3328,7 +3626,8 @@ class BladesRoll extends DocumentSheet { .on({ change: this._onSelectChange.bind(this) }); html .find("[data-action=\"gm-edit-consequences\"]") - .on({ click: () => BladesDialog.DisplayRollConsequenceDialog(this) }); + // .on({click: () => BladesDialog.DisplayRollConsequenceDialog(this)}); + .on({ click: () => BladesDialog.DisplaySimpleInputDialog(this, "What consequence would you add?", undefined, "rollCollab.inputDialogTest") }); html .find("[data-action='gm-text-input']") .on({ blur: this._onTextInputBlur.bind(this) }); diff --git a/module/core/ai.js b/module/core/ai.js index b2f0aac4..12f27c21 100644 --- a/module/core/ai.js +++ b/module/core/ai.js @@ -413,7 +413,7 @@ export const AGENTS = { { human: "Soul Destroyed", ai: "Fully Corrupted|Lost In Darkness|Spirit Broken" }, { human: "Humiliated", ai: "Embarrassed|Momentarily Off-Balance|Enraged" }, { human: "She Escapes!", ai: "She Spots a Means of Escape|She Puts More Distance Between You|She Stops to Gloat" }, - { human: "The fire spreads to the hostages.", ai: "The fire approaches the hostages|The hostages must be evacuated|The fire billows choking black smoke." } + { human: "The fire spreads to the hostages.", ai: "The fire approaches the hostages.|The hostages must be evacuated.|The fire billows choking black smoke." } ] } }; diff --git a/module/core/constants.js b/module/core/constants.js index 6a4256e2..2c318c84 100644 --- a/module/core/constants.js +++ b/module/core/constants.js @@ -399,6 +399,14 @@ const C = { AI_FILE_IDS: { BladesPDF: "file-n72HTTNwt051piPbswQ8isUa" }, + DowntimeActionDisplay: { + [DowntimeAction.AcquireAsset]: "Acquire an Asset", + [DowntimeAction.IndulgeVice]: "Indulge Your Vice", + [DowntimeAction.LongTermProject]: "Work on a Project", + [DowntimeAction.Recover]: "Heal", + [DowntimeAction.ReduceHeat]: "Reduce the Crew's Heat", + [DowntimeAction.Train]: "Train" + }, Consequences: { [Position.controlled]: { [RollResult.partial]: [ diff --git a/module/core/gsapBROKEN.js b/module/core/gsapBROKEN.js new file mode 100644 index 00000000..b07afc37 --- /dev/null +++ b/module/core/gsapBROKEN.js @@ -0,0 +1,582 @@ +import U from "./utilities.js"; +import C from "./constants.js"; +// eslint-disable-next-line import/no-unresolved +import { TextPlugin } from "/scripts/greensock/esm/all.js"; +const gsapPlugins = [ + TextPlugin +]; +const gsapEffects = { + /* Basic Element Effects */ + fadeOut: { + effect: (targets, config) => { + const tl = U.gsap.timeline({ + paused: config.paused, + runBackwards: config.reversed + }) + .to(targets, { + autoAlpha: 0, + duration: config.duration, + ease: config.ease + }); + // if (config.reversed) { + // tl.seek(config.duration); + // } + return tl; + }, + defaults: { + paused: false, + reversed: false, + duration: 0.5, + ease: "power4.out" + } + }, + blurOut: { + effect: (targets, config) => { + const tl = U.gsap.timeline({ + paused: config.paused, + runBackwards: config.reversed + }) + .to(targets, { + skewX: config.skewX, + duration: 0.5 * config.duration, + ease: "power4.out" + }) + .to(targets, { + x: `+=${config.rangeX}`, + marginBottom(i, target) { + return U.get(target, "height") * -1; + }, + marginRight(i, target) { + return U.get(target, "width") * -1; + }, + scale: config.scale, + filter: `blur(${config.blurStrength}px)`, + duration: 0.75 * config.duration + }, 0.25 * config.duration) + .to(targets, { + autoAlpha: 0, + duration: 0.5 * config.duration, + ease: "power3.in" + }, 0.5 * config.duration); + // if (config.reversed) { + // tl.seek(config.duration); + // } + return tl; + }, + defaults: { + paused: false, + reversed: false, + duration: 0.5, + skewX: -20, + rangeX: 300, + scale: 1.5, + blurStrength: 10 + } + }, + slideOut: { + effect: (targets, config) => { + const scaleKey = ["up", "down"].includes(config.dir) ? "scaleY" : "scaleX"; + const tl = U.gsap.timeline({ + paused: config.paused, + runBackwards: config.reversed + }) + .to(targets, { + [scaleKey]: 0, + duration: config.duration, + ease: config.ease + }); + // if (config.reversed) { + // tl.seek(config.duration); + // } + return tl; + }, + defaults: { + paused: false, + reversed: false, + duration: 0.5, + ease: "back.out(3)" + } + }, + brighten: { + effect: (targets, config) => { + const tl = U.gsap.timeline({ + paused: config.paused, + runBackwards: config.reversed + }) + .fromTo(targets, { + filter: `brightness(${config.startStrength})` + }, { + filter: `brightness(${config.strength})`, + duration: config.duration, + ease: config.ease + }); + return tl; + }, + defaults: { + paused: false, + reversed: false, + initialStrength: 1, + strength: 1.5, + duration: 0.5, + ease: "none" + } + }, + enlarge: { + effect: (targets, config) => { + const tl = U.gsap.timeline({ + paused: config.paused, + runBackwards: config.reversed + }) + .fromTo(targets, { + scale: config.startScale + }, { + scale: config.scale, + duration: config.duration, + ease: config.ease + }); + return tl; + }, + defaults: { + paused: false, + reversed: false, + startScale: 1, + scale: 1.5, + duration: 0.5, + ease: "sine.out" + } + }, + changeColor: { + effect: (targets, config) => { + const tl = U.gsap.timeline({ + paused: config.paused, + runBackwards: config.reversed + }) + .to(targets, { + color: config.color, + duration: config.duration, + ease: config.ease + }); + return tl; + }, + defaults: { + paused: false, + reversed: false, + color: C.Colors.bWHITE, + duration: 0.5, + ease: "sine" + } + }, + skewX: { + effect: (targets, config) => { + const tl = U.gsap.timeline({ + paused: config.paused, + runBackwards: config.reversed + }) + .to(targets, { + skewX: config.angle, + duration: config.duration, + ease: config.ease + }); + return tl; + }, + defaults: { + paused: false, + reversed: false, + angle: -45, + duration: 0.5, + ease: "sine" + } + }, + blurRemove: { + effect: (targets, config) => U.gsap.timeline() + .to(targets, { + skewX: config.skewX, + duration: config.duration / 2, + ease: "power4.out" + }) + .to(targets, { + x: config.x, + marginBottom(i, target) { + return U.get(target, "height") * -1; + }, + marginRight(i, target) { + return U.get(target, "width") * -1; + }, + scale: config.scale, + filter: config.filter, + duration: (3 / 4) * config.duration + }, config.duration / 4) + .to(targets, { + opacity: 0, + duration: config.duration / 2, + ease: "power3.in" + }, config.duration / 2), + defaults: { + skewX: -20, + duration: 0.5, + x: "+=300", + scale: 1.5, + filter: "blur(10px)" + } + }, + slideUp: { + effect: (targets) => U.gsap.to(targets, { + height: 0, + // PaddingTop: 0, + // paddingBottom: 0, + duration: 0.5, + ease: "power3" + }), + defaults: {} + }, + pulse: { + effect: (targets, config) => U.gsap.to(targets, { + repeat: config.repCount, + yoyo: true, + duration: config.duration / config.repCount, + ease: config.ease, + opacity: 0.25 + }), + defaults: { + repCount: 3, + duration: 5, + ease: "sine.inOut" + } + }, + throb: { + effect: (targets, config) => U.gsap.to(targets, { + repeat: config.stagger ? undefined : 1, + yoyo: config.stagger ? undefined : true, + duration: config.duration / 2, + scale: config.scale, + filter: config.filter, + ease: config.ease, + stagger: config.stagger + ? { + ...config.stagger, + repeat: 1, + yoyo: true + } + : {} + }), + defaults: { + duration: 1, + scale: 1, + filter: "saturate(1) brightness(2)", + ease: "power2.in" + }, + extendTimeline: true + }, + pulseClockWedges: { + effect: () => U.gsap.timeline({ duration: 0 }), + defaults: {} + }, + reversePulseClockWedges: { + effect: () => U.gsap.timeline({ duration: 0 }), + defaults: {} + }, + fillCoins: { + effect: (targets, config) => { + // Targets will be all coins from zero to where fill currently is + // Some will already be full, others not. + // Stagger in timeline + // Pulse in size and color + // Shimmer as they shrink back ? + return U.gsap.effects.throb(targets, { stagger: { + amount: 0.25, + from: "start", + repeat: 1, + yoyo: true + }, ...config ?? {} }); + }, + defaults: {} + }, + hoverTooltip: { + effect: (tooltip, config) => { + const tl = U.gsap.timeline({ paused: true, defaults: {} }); + if (!tooltip) { + return tl; + } + // Tooltip = $(tooltip); + if (config.scalingElems.length > 0) { + tl.to(config.scalingElems, { + scale: "+=0.2", + filter: "none", + color: C.Colors.WHITE, + opacity: 1, + duration: 0.125, + ease: "back" + }, 0.5); + } + if (tooltip) { + tl.fromTo(tooltip, { + filter: "blur(50px)", + opacity: 0, + scale: 2 * config.tooltipScale + }, { + filter: "none", + opacity: 1, + scale: config.tooltipScale, + x: config.xMotion, + duration: 0.25, + ease: "power2" + }, 1); + } + return tl; + }, + defaults: { + xMotion: "+=200", + tooltipScale: 1.25 + } + } +}; +/** + * Registers relevant GSAP plugins and effects. + */ +export function Initialize() { + if (gsapPlugins.length) { + U.gsap.registerPlugin(...gsapPlugins); + } + Object.entries(gsapEffects).forEach(([name, effect]) => { + U.gsap.registerEffect(Object.assign(effect, { name, extendTimeline: true })); + }); +} +/** + * Applies listeners to '.tooltip-trigger' elements in the document. + * @param {JQuery} html The document to be searched. + */ +export function ApplyTooltipAnimations(html) { + html.find(".tooltip-trigger").each((_, el) => { + const tooltipElem = $(el).find(".tooltip")[0] ?? $(el).next(".tooltip")[0]; + if (!tooltipElem) { + return; + } + $(el).data("hoverTimeline", U.gsap.effects.hoverTooltip(tooltipElem, { + scalingElems: [...$(el).find(".tooltip-scaling-elem")].filter((elem) => Boolean(elem)), + xMotion: $(tooltipElem).hasClass("tooltip-left") ? "-=250" : "+=200", + tooltipScale: $(tooltipElem).hasClass("tooltip-small") ? 1 : 1.2 + })); + $(el).on({ + mouseenter: function () { + $(el).css("z-index", 10); + $(el).data("hoverTimeline").play(); + }, + mouseleave: function () { + $(el).data("hoverTimeline").reverse().then(() => { + $(el).css("z-index", ""); + }); + } + }); + }); +} +/** + * Applies listeners to .consequence-display-container and children found in document. + * @param {JQuery} html The document to be searched. + */ +export function ApplyConsequenceAnimations(html) { + /** + * TIMELINES + * .comp.consequence-display-container:mouseenter + * = fade in grey interaction buttons + * ...:mouseleave = reverse + * + * .consequence-accept-button-container:mouseenter + * = turn type line white, text shadow + * slide out .consequence-accept-button-bg from left + * turn .consequence-accept-button i black, and scale + * turn .consequence-accept-button-label black, add letter spacing, bold + * ...:mouseleave = reverse + * + * .consequence-resist-button-container:mouseenter + * = slide in .consequence-type-bg.base-consequence to left + * fade out all .base-consequence:not(.consequence-type-bg) + * slide out .consequence-type.resist-consequence from left + * slide out .consequence-resist-button-bg from right + * slide out .consequence-footer-bg.resist-consequence from left + * slide out .consequence-resist-attribute from left + * slide out .consequence-name.resist-consequence from left + * fade in .consequence-icon-circle.resist-consequence + * ...:mouseleave = reverse + * --> IF resistTo.type === "None", blurRemove the base_consequence name and type instead of sliding them in, + * and don't slide the resistance ones out at all. + * */ + html + .find(".comp.consequence-display-container") + .each((_i, csqContainer) => { + if (!$(csqContainer).hasClass("consequence-accepted")) { + const csqRoot = U.gsap.utils.selector(csqContainer); + const csqBgImg = csqRoot(".consequence-bg-image"); + const [iconContainer] = csqRoot(".consequence-icon-container"); + const iconRoot = U.gsap.utils.selector(iconContainer); + const typeRoot = U.gsap.utils.selector(csqRoot(".consequence-type-container")[0]); + const nameRoot = U.gsap.utils.selector(csqRoot(".consequence-name-container")[0]); + const footerRoot = U.gsap.utils.selector(csqRoot(".consequence-footer-container")[0]); + const csqOptions = ["base", "accept"]; + ["resist", "armor", "special"].forEach((csqOpt) => { + if (iconRoot(`.${csqOpt}-consequence`).length) { + csqOptions.push(csqOpt); + } + }); + const interactionPads = {}; + const iconCircles = {}; + const buttonContainers = {}; + const buttonBGs = {}; + const buttonIcons = {}; + const buttonLabels = {}; + const typeLabels = {}; + const typeBGs = {}; + const nameLabels = {}; + const nameBGs = {}; + const footerLabels = {}; + const footerBGs = {}; + ["right", "left", "left-resist", "left-armor", "left-special"].forEach((iPadOpt) => { + [interactionPads[iPadOpt]] = csqRoot(`.consequence-interaction-pad.interaction-pad-${iPadOpt}`); + }); + ["base", "accept", "resist", "armor", "special"].forEach((csqOpt) => { + [iconCircles[csqOpt]] = iconRoot(`.consequence-icon-circle.${csqOpt}-consequence`); + [buttonContainers[csqOpt]] = iconRoot(`.consequence-button-container.${csqOpt}-consequence`); + [buttonBGs[csqOpt]] = iconRoot(`.consequence-button-container.${csqOpt}-consequence .consequence-button-bg`); + [buttonIcons[csqOpt]] = iconRoot(`.consequence-button-container.${csqOpt}-consequence .button-icon i`); + [buttonLabels[csqOpt]] = iconRoot(`.consequence-button-container.${csqOpt}-consequence .consequence-button-label`); + [typeLabels[csqOpt]] = typeRoot(`.consequence-type.${csqOpt}-consequence`); + if (csqOpt === "accept") { + [typeBGs[csqOpt]] = typeRoot(`.consequence-type-bg.${csqOpt}-consequence`); + } + [nameLabels[csqOpt]] = nameRoot(`.consequence-name.${csqOpt}-consequence`); + [nameBGs[csqOpt]] = nameRoot(`.consequence-name-bg.${csqOpt}-consequence`); + [footerLabels[csqOpt]] = footerRoot(`.consequence-footer-message.${csqOpt}-consequence`); + [footerBGs[csqOpt]] = footerRoot(`.consequence-footer-bg.${csqOpt}-consequence`); + }); + [ + interactionPads, + iconCircles, + buttonContainers, buttonBGs, buttonIcons, buttonLabels, + typeLabels, typeBGs, + nameLabels, nameBGs, + footerLabels, footerBGs + ] + .forEach((elemRecord) => U.objCompact(elemRecord, [undefined, null, false], true)); + // Apply master on-enter hover timeline to consequence container. + $(csqContainer).data("hoverTimelines", [ + U.gsap.effects.fadeOut([typeLabels.base, nameLabels.base], { paused: true, duration: 0.5 }), + U.gsap.effects.fadeOut([typeLabels.accept, nameLabels.accept], { paused: true, reversed: true, duration: 0.25 }), + U.gsap.effects.brighten([csqContainer], { paused: true, duration: 0.5 }), + U.gsap.effects.enlarge([iconCircles.base], { paused: true, duration: 0.75, startScale: 0.75, scale: 0.85 }) + ]); + $(csqContainer).on({ + mouseenter: function () { + $(csqContainer).css("z-index", 10); + $(csqContainer).data("hoverTimelines").forEach((tl) => tl.play()); + }, + mouseleave: function () { + if (!($(iconContainer).data("isToggled"))) { + $(csqContainer).css("z-index", ""); + $(csqContainer).data("hoverTimelines").forEach((tl) => tl.reverse()); + } + } + }); + // Apply click timeline to icon circle + $(iconContainer).data("clickTimelines", [ + U.gsap.timeline({ paused: true }) + .fromTo([csqBgImg], { + xPercent: 110, + yPercent: -50 + }, { + xPercent: -60, + yPercent: -50, + duration: 0.5, + ease: "back" + }), + U.gsap.effects.fadeOut([iconCircles.base], { paused: true }), + U.gsap.effects.fadeOut([iconCircles.accept], { paused: true, reversed: true }), + U.gsap.effects.blurOut([buttonContainers], { paused: true, reversed: true }) + ]); + $(iconContainer).on({ + click: function () { + if ($(iconContainer).data("isToggled")) { + $(iconContainer).data("isToggled", false); + $(iconContainer).data("clickTimelines").forEach((tl) => tl.reverse()); + } + else { + $(iconContainer).data("isToggled", true); + $(iconContainer).data("clickTimelines").forEach((tl) => tl.play()); + // Find any siblings with toggled-on iconContainers, and toggle them off + Array.from($(csqContainer).siblings(".consequence-display-container")) + .forEach((containerElem) => { + const iContainer$ = $(containerElem).find(".consequence-icon-container"); + if (iContainer$?.data("isToggled")) { + iContainer$.data("isToggled", false); + $(containerElem).css("z-index", ""); + [ + ...iContainer$.data("clickTimelines"), + ...$(containerElem).data("hoverTimelines") + ].forEach((tl) => tl.reverse()); + } + }); + } + } + }); + // Apply hover timelines to right (accept) interaction pad + $(interactionPads.right).data("hoverTimelines", [ + U.gsap.effects.changeColor([typeLabels.accept], { paused: true, color: C.Colors.WHITE }), + U.gsap.effects.slideOut([typeBGs.accept, buttonBGs.accept], { paused: true, reversed: true, dir: "left" }), + U.gsap.effects.skewX([typeBGs.accept, buttonBGs.accept], { paused: true, angle: -45 }), + U.gsap.effects.changeColor([buttonIcons.accept, buttonLabels.accept], { paused: true, color: C.Colors.dBLACK }), + U.gsap.effects.enlarge([buttonIcons.accept], { paused: true, scale: 1.25 }) + ]); + $(interactionPads.right).on({ + mouseenter: function () { + if ($(iconContainer).data("isToggled")) { + $(interactionPads.right).data("hoverTimelines").forEach((tl) => tl.play()); + } + }, + mouseleave: function () { + if ($(iconContainer).data("isToggled")) { + $(interactionPads.right).data("hoverTimelines").forEach((tl) => tl.reverse()); + } + } + }); + // Apply hover timeline to left (resist/armor/special) interaction pad + $(interactionPads.left).data("hoverTimelines", [ + U.gsap.effects.fadeOut([typeLabels.accept, nameLabels.accept, iconCircles.accept, buttonContainers.accept], { paused: true, duration: 0.25 }) + ]); + $(interactionPads.left).on({ + mouseenter: function () { + if ($(iconContainer).data("isToggled")) { + $(interactionPads.left).data("hoverTimelines").forEach((tl) => tl.play()); + } + }, + mouseleave: function () { + if ($(iconContainer).data("isToggled")) { + $(interactionPads.left).data("hoverTimelines").forEach((tl) => tl.reverse()); + } + } + }); + // Apply hover timelines to specific left interaction pads where they exist + ["resist", "armor", "special"].forEach((csqOpt) => { + if (interactionPads[`left-${csqOpt}`]) { + $(interactionPads[`left-${csqOpt}`]).data("hoverTimelines", [ + U.gsap.effects.fadeOut([iconCircles[csqOpt], typeLabels[csqOpt]], { paused: true, reversed: true }), + U.gsap.effects.slideOut([buttonBGs[csqOpt], nameLabels[csqOpt], footerBGs[csqOpt], footerLabels[csqOpt]], { paused: true, reversed: true, dir: "left" }), + U.gsap.effects.skewX([buttonBGs[csqOpt], nameLabels[csqOpt], footerBGs[csqOpt], footerLabels[csqOpt]], { paused: true, angle: -45 }), + U.gsap.effects.changeColor([buttonIcons[csqOpt], buttonLabels[csqOpt]], { paused: true, color: C.Colors.dBLACK }), + U.gsap.effects.enlarge([buttonIcons[csqOpt]], { paused: true, scale: 1.25 }) + ]); + $(interactionPads[`left-${csqOpt}`]).on({ + mouseenter: function () { + if ($(iconContainer).data("isToggled")) { + $(interactionPads[`left-${csqOpt}`]).data("hoverTimelines").forEach((tl) => tl.play()); + } + }, + mouseleave: function () { + if ($(iconContainer).data("isToggled")) { + $(interactionPads[`left-${csqOpt}`]).data("hoverTimelines").forEach((tl) => tl.reverse()); + } + } + }); + } + }); + } + }); +} +export default U.gsap; diff --git a/module/core/utilities.js b/module/core/utilities.js index c90ac9ee..e462458b 100644 --- a/module/core/utilities.js +++ b/module/core/utilities.js @@ -1021,7 +1021,7 @@ function objFindKey(obj, keyFunc, valFunc) { * @param {testFunc} [valFunc] The testing function for values. * @returns {Type} The filtered object. */ -const objFilter = (obj, keyFunc, valFunc) => { +const objFilter = (obj, keyFunc, valFunc, isMutating = false) => { // if (!valFunc) { valFunc = keyFunc; @@ -1031,10 +1031,23 @@ const objFilter = (obj, keyFunc, valFunc) => { keyFunc = ((k) => k); } if (isArray(obj)) { - return obj.filter(valFunc); + const keptValues = obj.filter(valFunc); + if (isMutating) { + obj.splice(0, obj.length, ...keptValues); + return obj; + } + return keptValues; } const kFunc = keyFunc || (() => true); const vFunc = valFunc || (() => true); + if (isMutating) { + const entriesToRemove = Object.entries(obj) + .filter(([key, val]) => !(kFunc(key, val) && vFunc(val, key))); + for (const [key] of entriesToRemove) { + delete obj[key]; + } + return obj; + } return Object.fromEntries(Object.entries(obj) .filter(([key, val]) => kFunc(key, val) && vFunc(val, key))); }; @@ -1048,7 +1061,7 @@ const objForEach = (obj, func) => { } }; // Prunes an object of given set of values, [undefined, null] default -const objCompact = (obj, removeWhiteList = [undefined, null]) => objFilter(obj, (val) => !removeWhiteList.includes(val)); +const objCompact = (obj, removeWhiteList = [undefined, null], isMutating = false) => objFilter(obj, (val) => !removeWhiteList.includes(val), undefined, isMutating); const objClone = (obj, isStrictlySafe = false) => { const cloneArray = (arr) => [...arr]; const cloneObject = (o) => ({ ...o }); diff --git a/module/documents/actors/BladesPC.js b/module/documents/actors/BladesPC.js index 60219e6a..adc906cf 100644 --- a/module/documents/actors/BladesPC.js +++ b/module/documents/actors/BladesPC.js @@ -8,6 +8,23 @@ class BladesPC extends BladesActor { static IsType(doc) { return super.IsType(doc, BladesActorType.pc); } + static GetFromUser(userRef) { + let user; + if (typeof userRef === "string") { + user = game.users.get(userRef) ?? game.users.getName(userRef); + } + else if (userRef instanceof User) { + user = userRef; + } + if (!user) { + throw new Error(`Unable to find user '${userRef}'`); + } + const actor = game.actors.get(user.character?.id ?? ""); + if (BladesPC.IsType(actor)) { + return actor; + } + return undefined; + } static async create(data, options = {}) { data.token = data.token || {}; data.system = data.system ?? {}; @@ -209,6 +226,12 @@ class BladesPC extends BladesActor { } await this.update({ "system.stash.value": Math.min(this.system.stash.value + amount, this.system.stash.max) }); } + get remainingDowntimeActions() { + if (!BladesActor.IsType(this, BladesActorType.pc)) { + return 0; + } + return this.system.downtime_actions.max + this.system.downtime_action_bonus - this.system.downtime_actions.value; + } // #endregion // #region BladesRoll.PrimaryDoc Implementation get rollModsData() { diff --git a/module/documents/items/BladesClock.js b/module/documents/items/BladesClock.js new file mode 100644 index 00000000..adb3762c --- /dev/null +++ b/module/documents/items/BladesClock.js @@ -0,0 +1,45 @@ +import BladesItem from "../../BladesItem.js"; +import { BladesActorType, Factor } from "../../core/constants.js"; +import U from "../../core/utilities.js"; +import BladesActor from "../../BladesActor.js"; +class BladesLocation extends BladesItem { + get rollFactors() { + const factorData = {}; + [ + Factor.tier, + Factor.quality, + Factor.scale + ].forEach((factor, i) => { + const factorTotal = this.getFactorTotal(factor); + factorData[factor] = { + name: factor, + value: factorTotal, + max: factorTotal, + baseVal: factorTotal, + display: factor === Factor.tier ? U.romanizeNum(factorTotal) : `${factorTotal}`, + isActive: i === 0, + isPrimary: i === 0, + isDominant: false, + highFavorsPC: true, + cssClasses: `factor-gold${i === 0 ? " factor-main" : ""}` + }; + }); + return factorData; + } + getFactorTotal(factor) { + switch (factor) { + case Factor.tier: return this.system.tier.value; + case Factor.quality: return this.getFactorTotal(Factor.tier); + case Factor.scale: return this.system.scale; + // no default + } + return 0; + } + get rollOppImg() { return this.img ?? ""; } + // #region OVERRIDES: _onUpdate + async _onUpdate(changed, options, userId) { + await super._onUpdate(changed, options, userId); + BladesActor.GetTypeWithTags(BladesActorType.pc).forEach((actor) => actor.render()); + } +} +export default BladesLocation; diff --git a/module/sheets/actor/BladesActorSheet.js b/module/sheets/actor/BladesActorSheet.js index fe0b4478..f92b8c87 100644 --- a/module/sheets/actor/BladesActorSheet.js +++ b/module/sheets/actor/BladesActorSheet.js @@ -1,9 +1,9 @@ // #region IMPORTS~ import U from "../../core/utilities.js"; import G, { ApplyTooltipAnimations } from "../../core/gsap.js"; -import C, { BladesActorType, BladesItemType, AttributeTrait, ActionTrait, Factor, RollType } from "../../core/constants.js"; +import C, { BladesActorType, BladesItemType, DowntimeAction, AttributeTrait, ActionTrait, Factor, RollType } from "../../core/constants.js"; import Tags from "../../core/tags.js"; -import BladesActor from "../../BladesActor.js"; +import { BladesActor, BladesPC } from "../../documents/BladesActorProxy.js"; import BladesItem from "../../BladesItem.js"; import BladesDialog from "../../BladesDialog.js"; import BladesActiveEffect from "../../BladesActiveEffect.js"; @@ -352,7 +352,7 @@ class BladesActorSheet extends ActorSheet { if (!doc) { return; } - await G.effects.blurRemove(elem$).then(async () => { + await G.effects.blurOut(elem$).then(async () => { if (doc instanceof BladesItem) { await this.actor.remSubItem(doc); } @@ -367,7 +367,7 @@ class BladesActorSheet extends ActorSheet { if (!doc) { return; } - await G.effects.blurRemove(elem$).then(async () => await doc.delete()); + await G.effects.blurOut(elem$).then(async () => await doc.delete()); } async _onItemToggleClick(event) { event.preventDefault(); @@ -419,6 +419,77 @@ class BladesActorSheet extends ActorSheet { } await BladesRoll.NewRoll(rollData); } + async _onDowntimeActionClick(event) { + const elem$ = $(event.currentTarget); + // Check whether character has downtime actions remaining. + // If not, prompt for whether spending Coin or Rep for extra + // If so, increase character's downtime count by one + const downtimeAction = elem$.data("downtimeAction"); + const rollConfig = { + rollType: RollType.Action, + rollDowntimeAction: downtimeAction + }; + // Determine Trait from action type + switch (downtimeAction) { + case DowntimeAction.AcquireAsset: { + rollConfig.rollTrait = Factor.tier; + break; + } + case DowntimeAction.IndulgeVice: { + if (!BladesPC.IsType(this.actor)) { + return; + } + rollConfig.rollType = RollType.IndulgeVice; + rollConfig.rollTrait = Object.values(AttributeTrait) + .reduce((minAttr, curAttr) => this.actor.attributes[curAttr] + < this.actor.attributes[minAttr] + ? curAttr + : minAttr, AttributeTrait.insight); + // GM needs to be able to set the desired asset as the rollOpposition, so can set minimum quality + break; + } + case DowntimeAction.LongTermProject: { + rollConfig.rollTrait = ""; + // BladesRoll can search actor subitems for project/rituals and set up their clocks as the 'opposition' + break; + } + case DowntimeAction.Recover: { + // If clicked on by player from an NPC sheet -> rollPrimary is the NPC, trait is quality + // Otherwise -> Search 'ActivePC' characters for 'Physicker' Ability; if more than one will have to prompt user + // ... OR ... + // ActiveEffect added to any BladesActor that can heal, along with reference to the trait they roll. + rollConfig.rollTrait = ActionTrait.tinker || Factor.quality; + break; + } + case DowntimeAction.ReduceHeat: { + rollConfig.rollTrait = ""; + break; + } + case DowntimeAction.Train: { + // Element will have target: Attribute or Playbook. + // Will have to check for crew upgrades that increase XP gained. + // If too much XP gained, will have to store excess so it can roll over after the player advances. + // Then, because this doesn't take a roll, we just return. + return; + } + } + // ... Pretty much everything else should be done over in BladesRoll. + BladesRoll.NewRoll(rollConfig); + } + async _onGatherInfoClick(event) { + const elem$ = $(event.currentTarget); + if (elem$.data("isFortuneRoll")) { + BladesRoll.NewRoll({ + rollType: RollType.Fortune + }); + } + else { + BladesRoll.NewRoll({ + rollType: RollType.Action, + rollTrait: "" + }); + } + } // #endregion // #region Active Effect Handlers _onActiveEffectControlClick(event) { diff --git a/module/sheets/roll/BladesConsequence.js b/module/sheets/roll/BladesConsequence.js index 6e300cc4..29e1f062 100644 --- a/module/sheets/roll/BladesConsequence.js +++ b/module/sheets/roll/BladesConsequence.js @@ -3,6 +3,15 @@ import C, { BladesActorType, AttributeTrait, ConsequenceType, RollResult, RollTy import U from "../../core/utilities.js"; import BladesRoll, { BladesRollPrimary } from "../../BladesRoll.js"; class BladesConsequence { + static get None() { + return { + id: randomID(), + name: "", + type: ConsequenceType.None, + isSelected: true, + isVisible: true + }; + } static GetActiveRollChatID() { return Array.from(game.messages).filter((msg) => $(msg.content ?? "").data("chat-id")).pop()?.id ?? undefined; } @@ -25,6 +34,14 @@ class BladesConsequence { else if (roll$.hasClass("roll-type-indulgevice")) { roll$.closest(".chat-message").addClass("indulgevice-roll"); } + // If this message is an action roll result AND there are unresolved consequences, add 'unresolved-action-roll' class. + if (roll$.hasClass("roll-type-action") + && Array.from(roll$.find(".comp.consequence-display-container:not(.consequence-accepted)")).length >= 1) { + roll$.closest(".chat-message").addClass("unresolved-action-roll"); + } + else { + roll$.closest(".chat-message").removeClass("unresolved-action-roll"); + } // If this message is the last one, add 'active-chat-roll' class and remove it from all others if (BladesConsequence.GetActiveRollChatID() === roll$.data("chatId")) { $(document).find(".chat-message").removeClass("active-chat-roll"); @@ -34,7 +51,7 @@ class BladesConsequence { roll$.closest(".chat-message").removeClass("active-chat-roll"); } const rollPhase = roll$.data("rollPhase"); - eLog.checkLog3("rollCollab", "ApplyChatListeners", { html, roll$, rollPhase }); + // eLog.checkLog3("rollCollab", "ApplyChatListeners", {html, roll$, rollPhase}); if (rollPhase !== RollPhase.AwaitingConsequences) { return; } @@ -151,7 +168,7 @@ class BladesConsequence { static async GetFromChatMessage(message, csqID) { const html$ = $(await message.getHTML()); const bCsqs = []; - html$.find(".blades-roll .consequence-container .comp.consequence-display-container").each((_, elem) => { + html$.find(".blades-roll .consequence-container .comp.consequence-display-container:not(.consequence-accepted)").each((_, elem) => { bCsqs.push(BladesConsequence.GetFromCsqElem(elem)); }); if (csqID) { @@ -269,7 +286,7 @@ class BladesConsequence { this._name = name; this._primaryID = primaryID; this._primaryType = primaryType; - this._primaryDoc = primaryDoc; + this._primaryDoc = new BladesRollPrimary(undefined, primaryDoc); this._type = type; this._position = position; this._effect = effect; @@ -436,11 +453,7 @@ class BladesConsequence { this._isAccepted = true; await this._chatMessage.update({ content: message$[0].outerHTML }); } - async resistConsequence() { - eLog.checkLog3("rollCollab", `Resisting Consequence id ${this._id}`); - if (!this._resistTo || !this.resistToData) { - throw new Error(`Cannot find resistTo for resistance roll for csq id '${this._id}' in message '${this._chatMessage.id}'`); - } + get rollFlagData() { // Get rollPrimaryData from archived roll flags on user document. let rollFlagData = this._user.getFlag(C.SYSTEM_ID, "rollCollab"); if (rollFlagData.rollID !== this._rollID) { @@ -449,6 +462,15 @@ class BladesConsequence { if (!rollFlagData) { throw new Error(`Unable to locate flag data for roll id '${this._rollID}'`); } + return rollFlagData; + } + async resistConsequence() { + eLog.checkLog3("rollCollab", `Resisting Consequence id ${this._id}`); + if (!this._resistTo || !this.resistToData) { + throw new Error(`Cannot find resistTo for resistance roll for csq id '${this._id}' in message '${this._chatMessage.id}'`); + } + // Get rollPrimaryData from archived roll flags on user document. + const rollFlagData = this.rollFlagData; const resistConfig = { rollType: RollType.Resistance, rollUserID: this._user.id, @@ -468,17 +490,24 @@ class BladesConsequence { }; BladesRoll.NewRoll(resistConfig); } - async applyResistedConsequence() { - if (this._resistTo) { - await this._resistTo.applyConsequenceToPrimary(); - await this.transformToConsequence("resist"); - } + async applyResistedConsequence(resistType) { + const rCsq = { + resist: this._resistTo, + armor: this._armorTo, + special: this._specialTo + }[resistType]; + if (rCsq) { + await rCsq.applyConsequenceToPrimary(); + } + await this.transformToConsequence(resistType); } async resistArmorConsequence() { - /* ... */ + this._primaryDoc.spendArmor(); + this.applyResistedConsequence("armor"); } async resistSpecialArmorConsequence() { - /* ... */ + await this._primaryDoc.spendSpecialArmor(); + this.applyResistedConsequence("special"); } } export default BladesConsequence; diff --git a/scss/chat/_chat.scss b/scss/chat/_chat.scss index 9f5dc9bb..f2be44d5 100644 --- a/scss/chat/_chat.scss +++ b/scss/chat/_chat.scss @@ -17,7 +17,7 @@ .flexrow.jump-to-bottom { - bottom: 154px; + bottom: 25px; z-index: 5; } @@ -29,7 +29,7 @@ z-index: 1; } } - +.chat-message:not(.display-ok) { opacity: 0 !important; } .chat-message[class*=-roll] { --font-primary: Beaufort !important; @@ -58,7 +58,12 @@ background: transparent; border: 2px ouset var(--blades-white); - &:not(.active-chat-roll) { + + + &:not(.unresolved-action-roll) { + .blades-roll > *:not(.chat-message-speaker-portrait-wrapper) { + filter: sepia(1) grayscale(0.5) brightness(0.6); + } .trait-label.trait-verb { display: none; } .consequence-icon-container { .consequence-icon-circle.base-consequence { @@ -66,10 +71,33 @@ img { animation: none !important; } } } + .chat-message-speaker-portrait-wrapper { + $border-color-bright: #9b9b9b; // #aa5a29; + $border-color-med: #565656; // #5a2f17; + $border-color-dark: #383838; // #531c06; + $border-color-darkest: #232323; // #3b1201; // 46381f 6b5630 9e7f46 + + --border-gradient: linear-gradient(-72deg, + #{$border-color-med}, + #{$border-color-bright} 16%, + #{$border-color-med} 21%, + #{$border-color-bright} 24%, + #{$border-color-dark} 27%, + #{$border-color-med} 36%, + #{$border-color-bright} 45%, + #{$border-color-bright} 60%, + #{$border-color-med} 72%, + #{$border-color-bright} 80%, + #{$border-color-med} 84%, + #{$border-color-darkest}); + + transform-origin: 50% 0%; + scale: 0.6 0.75; + } } } -.chat-message[class*=-roll].active-chat-roll { +.chat-message[class*=-roll].unresolved-action-roll { --bg-controlled: url("../assets/animations/chat/roll-position-controlled.webp"); --bg-risky: url("../assets/animations/chat/roll-position-risky.webp"); --bg-desperate: url("../assets/animations/chat/roll-position-desperate.webp"); @@ -150,7 +178,7 @@ $border-color-dark: #46381f; // #531c06; $border-color-darkest: #2c2315; // #3b1201; // 46381f 6b5630 9e7f46 - $border-gradient: linear-gradient(-72deg, + --border-gradient: linear-gradient(-72deg, #{$border-color-med}, #{$border-color-bright} 16%, #{$border-color-med} 21%, @@ -175,7 +203,7 @@ scale: 0.8 1; transform-origin: 50% 50%; - background: $border-gradient; + background: var(--border-gradient); background-repeat: no-repeat; outline: 3px solid black; box-shadow: 0 0 5px 5px black; @@ -223,7 +251,7 @@ &.action-roll + .chat-message.resistance-roll { margin-top: calc(-1 * var(--chat-vertical-gap)); } - &.action-roll.active-chat-roll + .chat-message.resistance-roll { + &.action-roll.unresolved-action-roll + .chat-message.resistance-roll { margin-top: 0; } @@ -578,6 +606,28 @@ padding: 4px; gap: 0; + h4.roll-state-label { + font-family: var(--font-emphasis-narrow); + font-size: 12px; + line-height: 12px; + display: block; + transform: translate(0%, -50%); + top: 50%; + text-align: center; + white-space: nowrap; + color: var(--side-color-secondary); + + strong { color: var(--side-color-secondary) !important; font-weight: 900 !important; } + } + + h3.roll-state { + white-space: nowrap; + font-size: 18px; + line-height: 18px; + text-shadow: var(--text-shadow-dark-strong); + color: var(--side-color-main); + } + &.roll-state-container-left { h4.roll-state-label { position: absolute; @@ -585,6 +635,7 @@ } h3.roll-state { position: absolute; + transform-origin: 100% 0%; top: 5px; right: 5px; scale: var(--side-left-x-scale) 1; @@ -601,6 +652,7 @@ h3.roll-state { width: 100%; position: absolute; + transform-origin: 0% 0%; bottom: 5px; left: 5px; text-align: left; @@ -608,29 +660,6 @@ scale: var(--side-right-x-scale) 1; } } - - h4.roll-state-label { - font-family: var(--font-emphasis-narrow); - font-size: 12px; - line-height: 12px; - display: block; - transform: translate(0%, -50%); - top: 50%; - text-align: center; - white-space: nowrap; - color: var(--side-color-secondary); - - strong { color: var(--side-color-secondary) !important; font-weight: 900 !important; } - } - - h3.roll-state { - white-space: nowrap; - font-size: 18px; - line-height: 18px; - transform-origin: 0% 0%; - text-shadow: var(--text-shadow-dark-strong); - color: var(--side-color-main); - } } diff --git a/scss/components/_comps.scss b/scss/components/_comps.scss index b8d3a9bc..bda4b08e 100644 --- a/scss/components/_comps.scss +++ b/scss/components/_comps.scss @@ -1082,20 +1082,29 @@ position: absolute; z-index: -1; height: 100%; - width: calc(100% + 24px); transform-origin: 0% 50%; top: 0px; background: var(--csq-icon-bright); display: block; + &.consequence-accept-button-bg { + width: calc(100% + 30px); + right: -7px; + transform: skewX(-45deg); + } + &.consequence-resist-button-bg, + &.consequence-armor-button-bg, &.consequence-special-button-bg { + width: calc(100% + 30px); transform-origin: 100% 50%; + right: calc(-0.5 * var(--container-height)); + transform: skewX(45deg); } + &.consequence-armor-button-bg, &.consequence-special-button-bg { - width: calc(100% + 40px); - margin-left: -10px; + width: calc(100% + 35px); } } @@ -1136,23 +1145,20 @@ &.consequence-resist-button-container { right: 100%; - - .consequence-button-bg { - left: -7px; - transform: skewX(45deg); - } } &.consequence-accept-button-container { left: 105%; - .consequence-button-bg { - right: -7px; - transform: skewX(-45deg); - } + } + &.consequence-armor-button-container { + right: 100%; + transform: translate(0%, 0%) !important; + top: 0%; } &.consequence-special-button-container { right: 100%; - bottom: 12px; + transform: translate(0%, -50%) !important; + top: 50%; } } } diff --git a/scss/dialog/_dialogs.scss b/scss/dialog/_dialogs.scss index a6e12065..e6be6f58 100644 --- a/scss/dialog/_dialogs.scss +++ b/scss/dialog/_dialogs.scss @@ -244,6 +244,12 @@ font-family: var(--font-emphasis-narrow); margin-right: 5px; flex-grow: 2; + + &.consequence-name-none { + box-shadow: none; + background: none; + cursor: default; + } } .roll-consequence-type-select { diff --git a/scss/sheets/_roll-collab-sheet.scss b/scss/sheets/_roll-collab-sheet.scss index 530f58ef..ef604460 100644 --- a/scss/sheets/_roll-collab-sheet.scss +++ b/scss/sheets/_roll-collab-sheet.scss @@ -872,6 +872,20 @@ .sheet-main { right: 6px; flex-basis: auto; + + &.roll-opp-block { + + } + + &.roll-consequences { + min-height: 330px; + h3 { margin-bottom: 10px; } + } + + &.factor-controls { + min-height: 112px; + place-self: stretch flex-end; + } } } } @@ -1444,8 +1458,8 @@ z-index: 5; &.split-root-left { - flex-basis: 85%; - max-width: 85%; + flex-basis: 80%; + max-width: 80%; // max-width: 370px; } diff --git a/scss/style.scss b/scss/style.scss index b15601b9..750be5e4 100644 --- a/scss/style.scss +++ b/scss/style.scss @@ -103,6 +103,7 @@ @import "./core/reset"; @import './core/globals'; + #chat-controls, #chat-form { display: none } &, * { --font-heading: var(--font-emphasis); diff --git a/template.json b/template.json index ed11ec70..cf6eddb2 100644 --- a/template.json +++ b/template.json @@ -45,7 +45,12 @@ "Ability": 0, "Cohort": 0, "CohortType": 0 - } + }, + "downtime_actions": { + "value": 0, + "max": 2 + }, + "downtime_action_bonus": 0 }, "hold": { "hold": "strong" @@ -420,6 +425,10 @@ "value": 0, "max": 4 }, + "armor": { + "value": 0, + "max": 0 + }, "scale_bonus": 0, "quality_bonus": 0 }, diff --git a/templates/actor-sheet.hbs b/templates/actor-sheet.hbs index a609450a..4f3a59b0 100644 --- a/templates/actor-sheet.hbs +++ b/templates/actor-sheet.hbs @@ -246,8 +246,8 @@ dataFlagTarget=false dataDType="String" dataDocType=false - selected=loadData.selLoadLevel - options=loadData.selectOptions }} + selected=loadData.selected + options=loadData.options }} {{#if loadData.selLoadCount}}(Max {{loadData.selLoadCount}} Load){{/if}} diff --git a/templates/components/consequence.hbs b/templates/components/consequence.hbs index de39b79d..277b28b3 100644 --- a/templates/components/consequence.hbs +++ b/templates/components/consequence.hbs @@ -23,12 +23,12 @@
- {{#if armorTo}} -
- {{/if}} {{#if specialArmorTo}}
{{/if}} + {{#if armorTo}} +
+ {{/if}}
{{!-- Icon --}} @@ -175,4 +175,6 @@ + + diff --git a/templates/dialog-input.hbs b/templates/dialog-input.hbs new file mode 100644 index 00000000..b3d1eda6 --- /dev/null +++ b/templates/dialog-input.hbs @@ -0,0 +1,14 @@ + +
+

{{prompt}}

+ +
+ +
+ {{#each buttons as |bData bName|}} + + {{/each}} +
\ No newline at end of file diff --git a/templates/parts/dialog-consequence-block.hbs b/templates/parts/dialog-consequence-block.hbs index 3c11b474..dba37ab4 100644 --- a/templates/parts/dialog-consequence-block.hbs +++ b/templates/parts/dialog-consequence-block.hbs @@ -38,38 +38,48 @@ selected=cData.attribute options=../consequenceAttributeOptions }} + {{!-- Blank Options Trigger --}} + {{> "systems/eunos-blades/templates/components/button-icon.hbs" + blockClass="blank-option-button" + buttonClass="fa-duotone fa-credit-card-blank" + action=(concat "blank-option-" ../rollPosition "-" ../rollResult "-" cID) + }} {{!-- AI Trigger --}} + {{#unless cData.resistNegates}} {{> "systems/eunos-blades/templates/components/button-icon.hbs" blockClass="ai-query-button" buttonClass="fa-solid fa-brain-circuit" tooltip="Query AI
Query OpenAI for suggestions on resisted versions of this consequence." action=(concat "ai-query-" ../rollPosition "-" ../rollResult "-" cID) }} - {{!-- Armor Toggles --}} - {{#if (test cData.attribute "==" "prowess")}} + {{/unless}} + {{!-- Armor Toggle --}} + {{#if cData.isDisplayingArmorToggle}} {{> "systems/eunos-blades/templates/components/toggle-icon.hbs" - isToggled=cData.canArmorA - blockClass="armor-toggle armor-toggle-a" - targetFlagKey=(concat "rollCollab.consequenceData." ../rollPosition "." ../rollResult "." cID ".canArmorA") + isToggled=cData.canArmor + blockClass="armor-toggle" + dataAction=(concat "toggle-armor-" ../rollPosition "-" ../rollResult "-" cID) activeClass="fa-sharp fa-solid fa-shield" inactiveClass="fa-sharp fa-regular fa-shield" }} - {{#if cData.canArmorA}} - {{> "systems/eunos-blades/templates/components/toggle-icon.hbs" - isToggled=cData.canArmorB - blockClass="armor-toggle armor-toggle-b" - targetFlagKey=(concat "rollCollab.consequenceData." ../rollPosition "." ../rollResult "." cID ".canArmorB") - activeClass="fa-sharp fa-solid fa-shield" - inactiveClass="fa-sharp fa-regular fa-shield" - }} - {{/if}} {{/if}} + {{!-- Special Armor Toggle --}} + {{#if cData.isDisplayingSpecialArmorToggle}} + {{> "systems/eunos-blades/templates/components/toggle-icon.hbs" + isToggled=cData.canSpecialArmor + blockClass="special-armor-toggle" + dataAction=(concat "toggle-special-" ../rollPosition "-" ../rollResult "-" cID) + activeClass="fa-sharp fa-duotone fa-shield-quartered" + inactiveClass="fa-sharp fa-regular fa-shield-quartered" + }} + {{/if}} {{!-- Name --}} {{!-- AI Options --}}
{{#each cData.resistOptions as |rData rID|}} + {{#unless (test rData.isVisible "==" false)}}
{{!-- Select Resist Option --}} {{#if rData.isSelected}} @@ -97,8 +107,13 @@ selected=rData.type options=../../consequenceTypeOptionsAll }} {{!-- Name --}} + {{#if (test rData.type "==" "None")}} + + {{else}} + {{/if}}
+ {{/unless}} {{/each}}
diff --git a/templates/roll/partials/roll-collab-action-gm.hbs b/templates/roll/partials/roll-collab-action-gm.hbs index d4d2416a..fd2a66a0 100644 --- a/templates/roll/partials/roll-collab-action-gm.hbs +++ b/templates/roll/partials/roll-collab-action-gm.hbs @@ -242,7 +242,7 @@
{{#each csqData.partial as |cData cIndex|}} {{#if cData.resistTo}} - {{> "systems/eunos-blades/templates/components/consequence.hbs" cData + {{> "systems/eunos-blades/templates/components/consequence-accepted.hbs" cData isResistanceVisible=true }} {{/if}} {{/each}} @@ -251,7 +251,7 @@
{{#each csqData.fail as |cData cIndex|}} {{#if cData.resistTo}} - {{> "systems/eunos-blades/templates/components/consequence.hbs" cData + {{> "systems/eunos-blades/templates/components/consequence-accepted.hbs" cData isResistanceVisible=true }} {{/if}} {{/each}} diff --git a/templates/roll/partials/roll-collab-action.hbs b/templates/roll/partials/roll-collab-action.hbs index b9021e59..8b79464d 100644 --- a/templates/roll/partials/roll-collab-action.hbs +++ b/templates/roll/partials/roll-collab-action.hbs @@ -42,6 +42,12 @@
+{{#if (test gamePhase "==" "Downtime")}}{{#if (test rollPrimary.rollPrimaryType "==" "pc")}} +
+ {{gamePhase}} +
+{{/if}}{{/if}} +
@@ -242,9 +248,17 @@
- {{#if rollOpposition}}{{/if}} + {{#if rollOpposition}} + {{#if (test rollOpposition.rollOppType "==" "clock")}} + {{> "systems/eunos-blades/templates/components/clock.hbs" rollOpposition.clockData}} + {{else}} + + {{/if}} + {{/if}}
+ {{#unless (test rollOpposition.rollOppType "==" "clock")}}
+ {{/unless}}