diff --git a/WORKLOG.md b/WORKLOG.md index 1f63906f..14a4072c 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -11,6 +11,9 @@ * acp init * DO postgres +* only clear effects on post_resolve + electrify doesn't work if you ko the construct + ## SOON *SERVER* * modules diff --git a/client/assets/styles/account.less b/client/assets/styles/account.less index a5e763c3..a73faaae 100644 --- a/client/assets/styles/account.less +++ b/client/assets/styles/account.less @@ -1,19 +1,16 @@ @import 'colours.less'; -.account-page { - height: 100%; +.account { + margin-top: 2em; + grid-area: bottom; + display: grid; - - grid-template-rows: minmax(min-content, 2fr) 1fr; - grid-template-columns: 1fr; - - grid-template-areas: - "team" - "account"; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-gap: 0 1em; button { display: block; - height: 3em; + // height: 3em; width: 75%; } @@ -23,20 +20,20 @@ display: block; } - .team { - grid-area: team; - /* poor man's
*/ - border-bottom: 0.1em solid #444; - } + .list { + letter-spacing: 0.25em; + text-transform: uppercase; - .account { - margin: 2em 2em 0 0; - grid-area: account; + figure { + font-size: 125%; + display: flex; + flex-flow: column; - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - grid-gap: 0 1em; + button { + width: 100%; + } + } } } diff --git a/client/assets/styles/colours.less b/client/assets/styles/colours.less index d7e0fc49..cfed8007 100644 --- a/client/assets/styles/colours.less +++ b/client/assets/styles/colours.less @@ -31,3 +31,33 @@ svg { stroke: @blue; } } + +.green { + color: @green; + stroke: @green; +} + +.red { + color: @red; + stroke: @red; +} + +.red-fill { + fill: @red; +} + +.blue { + color: @blue; + stroke: @blue; + stroke-linecap: round; +} + +.gray { + color: #333; + stroke: #333; +} + +.white { + color: @white; + stroke: @white; +} diff --git a/client/assets/styles/controls.less b/client/assets/styles/controls.less index 5e4dbaad..0bc5c759 100644 --- a/client/assets/styles/controls.less +++ b/client/assets/styles/controls.less @@ -1,10 +1,17 @@ aside { grid-area: ctrl; display: grid; + + grid-template-areas: + "timer controls" + "timer controls" + "timer controls"; + + grid-template-columns: min-content 1fr; grid-template-rows: 1fr 1fr 1fr; grid-gap: 0.5em 0; - padding: 1em; + padding: 1em 1em 1em 0; div { text-align: right; @@ -28,6 +35,30 @@ aside { border-color: forestgreen; } } + + .timer-container { + grid-area: timer; + + display: flex; + flex: 1 1 100%; + + height: 100%; + min-height: 100%; + + width: 0.25em; + max-width: 0.25em; + + margin: 0 1em 0 0; + border: none; + } + + .timer { + background: whitesmoke; + transition-property: all; + transition-duration: 0.25s; + transition-delay: 0; + transition-timing-function: ease; + } } .ready-btn:hover, .ready-btn:focus, .ready-btn:active { diff --git a/client/assets/styles/footer.less b/client/assets/styles/footer.less new file mode 100644 index 00000000..8ab8873a --- /dev/null +++ b/client/assets/styles/footer.less @@ -0,0 +1,51 @@ +footer { + display: none; + flex-flow: row wrap; + grid-area: footer; + margin: 0; + + button { + margin: 0; + border: none; + background: #222; + font-size: 1.5em; + padding: 0.25em; + + &[disabled] { + color: #444; + } + + &:not(:last-child) { + background: #222; + border-right: 1px solid black; + } + + .ready { + background: forestgreen; + color: black; + } + } + + .timer-container { + display: flex; + flex: 1 1 100%; + width: 100%; + height: 0.25em; + max-height: 0.25em; + + border: none; + margin: 1em 0 0 0; + } + + .timer { + background: whitesmoke; + transition-property: all; + transition-duration: 0.25s; + transition-delay: 0; + transition-timing-function: ease; + } +} + +#nav-btn, #instance-nav { + display: none; +} diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index a2949889..e51237bc 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -323,15 +323,6 @@ pointer-events: none; } -/*@keyframes rotate { - 0% { - transform: rotateY(0deg); - } - 100% { - transform: rotateY(50deg); - } -} -*/ .resolving .skills button { opacity: 0; } @@ -339,80 +330,9 @@ .skill-animation { opacity: 0; stroke-width: 5px; + height: 5em; } -/* - COMBAT ANIMATIONS -*/ - -/* ---------------------------------------------- - * Generated by Animista on 2019-5-21 11:38:30 - * w: http://animista.net, t: @cssanimista - * ---------------------------------------------- */ - - -/*.attack-cast { - -webkit-animation: attack-cast 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both; - animation: attack-cast 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both; -} - -@-webkit-keyframes attack-cast { - 0% { - -webkit-transform: translateY(0); - transform: translateY(0); - opacity: 1; - } - 100% { - -webkit-transform: translateY(-5em); - transform: translateY(-5em); - opacity: 0; - } -} -@keyframes attack-cast { - 0% { - -webkit-transform: translateY(0); - transform: translateY(0); - opacity: 1; - } - 100% { - -webkit-transform: translateY(-5em); - transform: translateY(-5em); - opacity: 0; - } -} - -.attack-hit { - -webkit-animation: attack-hit 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both; - animation: attack-hit 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both; -} - -@-webkit-keyframes attack-hit { - 0% { - -webkit-transform: translateY(-5em) translateX(5em); - transform: translateY(-5em) translateX(5em); - opacity: 0; - } - 100% { - -webkit-transform: translateY(0) translateX(0); - transform: translateY(0) translateX(0); - opacity: 1; - } -} -@keyframes attack-hit { - 0% { - -webkit-transform: translateY(-5em) translateX(5em); - transform: translateY(-5em) translateX(5em); - opacity: 0; - } - 100% { - -webkit-transform: translateY(0) translateX(0); - transform: translateY(0) translateX(0); - opacity: 1; - } -} -*/ - - @media (max-width: 1000px) { .game { grid-template-areas: diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 40038876..4a4ee15b 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -421,6 +421,12 @@ margin-top: 1em; grid-area: playername; } + + .team { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(min-content, 33%)); + max-height: 100%; + } } /* Mobile Nav*/ diff --git a/client/assets/styles/menu.less b/client/assets/styles/menu.less new file mode 100644 index 00000000..c0367cc6 --- /dev/null +++ b/client/assets/styles/menu.less @@ -0,0 +1,85 @@ +@import 'colours.less'; + +.menu { + height: 100%; + display: grid; + + grid-template-rows: minmax(min-content, 2fr) 1fr; + grid-template-columns: 1fr; + + grid-template-areas: + "top" + "bottom"; + + .top { + padding: 0 0 0.5em 2em; + border-bottom: 0.1em solid #222; + box-sizing: border-box; + } + + .team { + display: grid; + grid-area: top; + grid-template-columns: repeat(auto-fill, minmax(min-content, 33%)); + max-height: 100%; + + .team-select:not(:nth-child(3n)) { + margin-right: 0.5em; + } + + .construct { + flex: 1 1 33%; + + display: flex; + flex-flow: column; + text-align: center; + justify-content: center; + + border: 1px solid black; + transition-property: border; + transition-duration: 0.25s; + transition-delay: 0; + transition-timing-function: ease; + + button:not(:last-child) { + margin-bottom: 1em; + } + + .avatar { + background-size: contain; + background-repeat: no-repeat; + background-position: center; + pointer-events: none; + height: 100%; + } + } + } + + .inventory { + margin-top: 2em; + grid-area: bottom; + + display: grid; + grid-template-columns: 1fr 1fr; + + h1 { + margin-bottom: 0.5em; + } + + .list { + letter-spacing: 0.25em; + text-transform: uppercase; + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-gap: 1em; + flex-flow: row wrap; + align-items: flex-end; + } + + figure { + font-size: 125%; + display: flex; + flex-flow: column; + } + } +} diff --git a/client/assets/styles/nav.less b/client/assets/styles/nav.less new file mode 100644 index 00000000..11184866 --- /dev/null +++ b/client/assets/styles/nav.less @@ -0,0 +1,98 @@ +nav { + grid-area: nav; + padding-left: 2em; + margin-right: 2em; + max-height: 100%; + + h1 { + margin-bottom: 0.5em; + } + + h2:first-child { + margin: 0; + } + + h2 { + margin-top: 2em; + } + + hr { + margin: 1em 0; + border-color: #444; + } + + button { + text-overflow: ellipsis; + display: block; + color: #888; + flex: 1 1 100%; + padding: 0; + margin: 0; + border-width: 0px; + } + + button.active { + color: whitesmoke; + } + + button[disabled], button[disabled]:hover { + color: #333; + text-decoration: none; + } + + button:hover { + color: whitesmoke; + text-decoration: underline; + } + + button:focus, button:active { + color: whitesmoke; + } + + .account-info { + display: flex; + } + + .account-header { + letter-spacing: 0.05em; + flex: 1; + display: inline; + } + + .account-info svg { + margin: 0.5em 0 0 1em; + height: 1em; + background-color: black; + stroke: whitesmoke; + } + + .ping-path { + fill: none; + stroke-width: 4px; + stroke-dasharray: 121, 242; + animation: saw 2s infinite linear; + + transition-property: stroke-color; + transition-duration: 0.25s; + transition-timing-function: ease; + } + + .ping-text { + margin-left: 1em; + min-width: 3em; + display: inline-block; + } + + .play-btn { + font-size: 150%; + } +} + +@keyframes saw { + 0% { + stroke-dashoffset: 363; + } + 100% { + stroke-dashoffset: 0; + } +} diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index 12bde5a2..dedefa13 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -1,11 +1,6 @@ @import 'colours.less'; -/* - GLOBAL -*/ - html, body, #mnml { - /*width: 100%;*/ margin: 0; background-color: black; @@ -66,6 +61,7 @@ h4 { } hr { + color: #222; margin: 1.5em 0; width: 100%; } @@ -85,74 +81,11 @@ figure { "nav main ctrl"; } -nav { - grid-area: nav; - padding-left: 2em; - margin-right: 2em; - max-height: 100%; - - h1 { - margin-bottom: 0.5em; - } -} - -nav h2:first-child { - margin: 0; -} - -nav h2 { - margin-top: 2em; -} - -nav hr { - margin: 1em 0; - border-color: #444; -} - -nav button { - text-overflow: ellipsis; - display: block; - color: #888; - flex: 1 1 100%; - padding: 0; - margin: 0; - border-width: 0px; -} - -nav button.active { - color: whitesmoke; -} - -nav button[disabled], nav button[disabled]:hover { - color: #333; - text-decoration: none; -} - -nav button:hover { - color: whitesmoke; - text-decoration: underline; -} - -nav button:focus, nav button:active { - color: whitesmoke; -} - main { padding: 1em; grid-area: main; } -tr.right:focus, tr.right:hover { - box-shadow: inset -0.5em 0 0 0 whitesmoke; -} - -tr { - transition-property: color, background; - transition-duration: 0.25s; - transition-delay: 0; - transition-timing-function: ease; -} - button, input { font-family: 'Jura'; color: whitesmoke; @@ -195,19 +128,6 @@ svg { height: 2em; } -.skill-animation { - height: 5em; -} - -.team .avatar { - object-fit: contain; - max-width: 100%; - max-height: 100%; - width: auto; - height: auto; - pointer-events: none; -} - table { table-layout: fixed; width: 100%; @@ -250,56 +170,6 @@ button[disabled] { border-color: #222; } -/* - COLOURS -*/ - -.green { - color: #1FF01F; - stroke: #1FF01F; -} - -.red { - color: #a52a2a; - stroke: #a52a2a; -} - -.red-fill { - fill: #a52a2a; -} - -.blue { - color: #3050f8; - stroke: #3050f8; - stroke-linecap: round; -} - -.yellow { - color: #FFD123; - stroke: #FFD123; -} - -.purple { - color: #A25AC1; - stroke: #A25AC1; -} - -.cyan { - color: #6AD1BF; - stroke: #6AD1BF; -} - -.gray { - color: #333; - stroke: #333; -} - -.white { - color: whitesmoke; - stroke: whitesmoke; -} - - /* LOGIN */ @@ -320,229 +190,6 @@ button[disabled] { border-color: #888; } -/* - account -*/ - -header { - display: flex; - flex-flow: row; - grid-area: hd; - margin-bottom: 1.5em; -} - -.header-title { - flex: 1; - letter-spacing: 0.05em; -} - -.account-info { - display: flex; -} - -.account-header { - letter-spacing: 0.05em; - flex: 1; - display: inline; -} - -.account-info svg { - margin: 0.5em 0 0 1em; - height: 1em; - background-color: black; - stroke: whitesmoke; -} - -.ping-path { - fill: none; - stroke-width: 4px; - stroke-dasharray: 121, 242; - animation: saw 2s infinite linear; - - transition-property: stroke-color; - transition-duration: 0.25s; - transition-timing-function: ease; -} - -.ping-text { - margin-left: 1em; - min-width: 3em; - display: inline-block; -} - -@keyframes saw { - 0% { - stroke-dashoffset: 363; - } - 100% { - stroke-dashoffset: 0; - } -} - -/* - TEAM -*/ - -.team { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(min-content, 33%)); - max-height: 100%; -} - -.menu-construct { - margin: 0.5em; - flex: 1 1 auto; - - display: flex; - flex-flow: column; - text-align: center; - justify-content: center; - - border: 1px solid black; - transition-property: border; - transition-duration: 0.25s; - transition-delay: 0; - transition-timing-function: ease; - - button:not(:last-child) { - margin-bottom: 1em; - } - - .avatar { - background-size: contain; - background-repeat: no-repeat; - background-position: center; - pointer-events: none; - height: 100%; - } -} - -.spawn-btn.menu-construct { - border: 1px solid #333; - color: #333; - display: flex; - flex-flow: row wrap; - align-content: center; - justify-content: center; -} - -.spawn-btn.menu-construct.selected { - color: whitesmoke; -} - -.spawn-btn.menu-construct:hover { - border: 1px solid whitesmoke; -} - -.spawn-btn input { - flex: 1 1 100%; - width: 100%; - margin: 1em; -} - -.spawn-btn button { - flex: 1 1 100%; - margin: 0.5em 1em; - padding: 0 0.5em; -} - -.spawn-btn input[disabled], .spawn-btn button[disabled] { - opacity: 0 -} - -.play { - height: 100%; - display: grid; - - grid-template-rows: minmax(min-content, 2fr) 1fr; - grid-template-columns: 1fr; - - grid-template-areas: - "team" - "inventory"; - - .team { - grid-area: team; - - /* poor man's
*/ - padding: 0.5em 2em 0 0; - border-bottom: 0.1em solid #444; - - } - - .menu-construct { - flex: 1 0 33%; - } - - .inventory { - margin: 2em 2em 0 0; - grid-area: inventory; - - display: grid; - grid-template-columns: 1fr 1fr; - - h1 { - margin-bottom: 0.5em; - } - - .list { - letter-spacing: 0.25em; - text-transform: uppercase; - display: grid; - grid-template-columns: repeat(4, 1fr); - grid-gap: 1em; - flex-flow: row wrap; - align-items: flex-end; - } - - figure { - font-size: 125%; - display: flex; - flex-flow: column; - } - } -} - -.menu-instance-btn { - flex: 1 1 100%; - font-size: 1.2em; -} - -.play-btn { - font-size: 150%; -} - -.refresh-btn { - border: 1px solid #222; - float: right; - font-size: 1.5em; -} - -.create-form { - grid-area: create; - flex: 1; - - justify-self: flex-end; - - display: flex; - flex-flow: row wrap; - margin-bottom: 1.5em; -} - -.create-form button { - flex: 1; - font-size: 1.5em; -} - -.create-form button:first-child { - margin-right: 1em; -} - -.create-form button:hover, .create-form button:focus { - border-color: whitesmoke; - text-decoration: none; -} - figure.gray { color: #333; stroke-color: #333; @@ -553,63 +200,11 @@ figure.gray { fill: none; } -main .top button { - width: 100%; -} - .credits { color: @yellow; font-weight: 800; } -.timer-container { - display: flex; - flex: 1 1 100%; - width: 100%; - height: 0.25em; - max-height: 0.25em; - - border: none; - margin: 1em 0 0 0; -} - -.timer { - background: whitesmoke; - transition-property: all; - transition-duration: 0.25s; - transition-delay: 0; - transition-timing-function: ease; -} - -footer { - display: none; - flex-flow: row wrap; - grid-area: footer; - margin: 0; -} - -footer button { - margin: 0; - border: none; - background: #222; - font-size: 1.5em; - padding: 0.25em; -} - -footer button:disabled { - color: #444; -} - -footer button:not(:last-child) { - background: #222; - border-right: 1px solid black; -} - -footer button .ready { - background: forestgreen; - color: black; -} - @media (max-width: 1500px) { #mnml { font-size: 75%; @@ -620,10 +215,6 @@ footer button .ready { } } -#nav-btn, #instance-nav { - display: none; -} - .mobile-title { display: none; -} +} \ No newline at end of file diff --git a/client/index.js b/client/index.js index da09b74d..8c76e1ff 100644 --- a/client/index.js +++ b/client/index.js @@ -1,9 +1,12 @@ require('./assets/styles/styles.less'); +require('./assets/styles/menu.less'); +require('./assets/styles/nav.less'); +require('./assets/styles/footer.less'); +require('./assets/styles/account.less'); +require('./assets/styles/controls.less'); require('./assets/styles/instance.less'); require('./assets/styles/vbox.less'); require('./assets/styles/game.less'); -require('./assets/styles/controls.less'); -require('./assets/styles/account.less'); require('./assets/styles/styles.mobile.css'); require('./assets/styles/instance.mobile.css'); diff --git a/client/src/components/account.management.jsx b/client/src/components/account.management.jsx index 102b846b..6bebfe10 100644 --- a/client/src/components/account.management.jsx +++ b/client/src/components/account.management.jsx @@ -1,6 +1,8 @@ const { connect } = require('preact-redux'); const preact = require('preact'); +const SpawnButton = require('./spawn.button'); + const { postData } = require('./../utils'); const actions = require('../actions'); @@ -9,6 +11,7 @@ const addState = connect( const { account, ping, + ws, } = state; @@ -16,10 +19,15 @@ const addState = connect( postData('/logout').then(() => window.location.reload(true)); } + function sendConstructSpawn(name) { + return ws.sendMtxConstructSpawn(name); + } + return { account, ping, logout, + sendConstructSpawn, }; }, ); @@ -30,6 +38,7 @@ function AccountStatus(args) { account, ping, logout, + sendConstructSpawn, } = args; if (!account) return null; @@ -83,6 +92,14 @@ function AccountStatus(args) { /> +
+
+
spawn new construct
+ +
+
); } diff --git a/client/src/components/account.page.jsx b/client/src/components/account.page.jsx index 17474fe8..021bb58b 100644 --- a/client/src/components/account.page.jsx +++ b/client/src/components/account.page.jsx @@ -23,7 +23,7 @@ function Account(args) { } = args; return ( -
+
diff --git a/client/src/components/game.ctrl.jsx b/client/src/components/game.ctrl.jsx index e63cea4a..a27e4e06 100644 --- a/client/src/components/game.ctrl.jsx +++ b/client/src/components/game.ctrl.jsx @@ -20,16 +20,22 @@ const addState = connect( return ws.sendGameReady(game.id); } + function getInstanceState() { + return ws.sendInstanceState(game.instance); + } + return { game, sendReady, account, + getInstanceState, animating, }; }, function receiveDispatch(dispatch) { function quit() { + dispatch(actions.setNav('transition')); dispatch(actions.setGame(null)); dispatch(actions.setInstance(null)); } @@ -74,6 +80,7 @@ function Controls(args) { animating, sendReady, quit, + getInstanceState, } = args; if (!game) return false; @@ -81,11 +88,43 @@ function Controls(args) { const opponent = game.players.find(t => t.id !== account.id); const player = game.players.find(t => t.id === account.id); + function quitClick() { + getInstanceState(); + quit(); + } + + const zero = Date.parse(game.phase_start); + const now = Date.now(); + const end = Date.parse(game.phase_end); + const timerPct = game.phase_end + ? ((now - zero) / (end - zero) * 100) + : 100; + + const displayColour = !game.phase_end + ? '#222' + : player.ready + ? 'forestgreen' + : timerPct > 80 + ? 'red' + : 'whitesmoke'; + + const timerStyles = { + height: `${timerPct > 100 ? 100 : timerPct}%`, + background: displayColour, + }; + + const timer = ( +
+
 
+
+ ); + const readyBtn = ; - const quitBtn = ; + const quitBtn = ; return (