diff --git a/client/assets/styles/controls.less b/client/assets/styles/controls.less new file mode 100644 index 00000000..33f14c8d --- /dev/null +++ b/client/assets/styles/controls.less @@ -0,0 +1,35 @@ +aside { + grid-area: ctrl; + display: grid; + + padding: 1em; + + button { + width: 100%; + font-size: 150%; + } + + button.ready { + &:hover { + color: forestgreen; + border-color: forestgreen; + } + + &:active, &:focus { + background: forestgreen; + color: black; + border-color: forestgreen; + } + } +} + +.ready-btn:hover, .ready-btn:focus, .ready-btn:active { + color: forestgreen; +} + +.ready { + color: forestgreen; + transition-property: color, background; + transition-duration: 0.5s; + transition-timing-function: ease; +} diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index 6b46cefa..29a71047 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -4,20 +4,11 @@ overflow: hidden; display: grid; grid-template-rows: 1fr 0.5fr 1.5fr; - grid-template-columns: 1fr 0.15fr; + grid-template-columns: 1fr; grid-template-areas: - "opponent controls" - "target controls" - "player controls"; - - .controls { - margin: 1em 1em 0 0; - grid-area: controls; - - button { - width: 100%; - } - } + "opponent" + "target " + "player "; } .game .team { @@ -430,10 +421,6 @@ grid-template-rows: 1fr 0.2fr 1.5fr; grid-template-columns: 1fr; - - .controls { - display: none; - } } .game .stats div { diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 49bc3604..190a28be 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -35,41 +35,26 @@ } .scoreboard { - display: flex; - flex-flow: column; - align-items: center; - - table { - flex: 1; - } - - button { - flex: 1; - margin-bottom: 1em; - width: 75%; - font-size: 150%; - line-height: 3em; - } + flex: 1; } .instance .info { /*font-size: 75%;*/ - margin-left: 1em; + margin: 3em 0 0 1em; grid-area: info; display: flex; flex-flow: column; - justify-content: center; - white-space: pre-wrap; + // white-space: pre-wrap; + + > *:first-child { + margin-bottom: 1em; + } } .instance .info h2 { text-transform: uppercase; } -.instance .info .combos { - margin-top: 1.5em; -} - .instance .constructs { grid-area: constructs; } @@ -371,8 +356,7 @@ .thresholds { display: flex; - flex-flow: column; - text-align: center; + flex-flow: row; } .thresholds svg { @@ -383,13 +367,21 @@ margin: 1em 0; } -.colour-reqs { - display: flex; - flex-flow: row; - justify-content: space-around; +.spec-goal { + margin-top: 0.5em; + + div { + display: flex; + margin: 0 1em 1em 0; + } + + .bonus { + justify-content: flex-end; + } } .thresholds figure svg { + margin-right: 0.25em; height: 1.5em; } diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index 4a2a57bf..d9b99561 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -77,12 +77,12 @@ figure { #mnml { display: grid; - grid-template-columns: minmax(min-content, 1fr) 8fr; + grid-template-columns: minmax(min-content, 1fr) 8fr 1fr; grid-template-rows: min-content 1fr min-content; grid-template-areas: - "hd hd" - "nav main" - "nav main"; + "hd hd ctrl" + "nav main ctrl" + "nav main ctrl"; } nav { @@ -453,6 +453,9 @@ header { .inventory { margin-right: 2em; grid-area: inventory; + + display: grid; + grid-template-columns: 1fr 1fr; } .inventory .list { @@ -476,11 +479,11 @@ header { display: grid; grid-template-rows: minmax(min-content, 2fr) 1fr; - grid-template-columns: 1fr 1fr; + grid-template-columns: 1fr; grid-template-areas: - "team team" - "inventory join"; + "team" + "inventory"; .join { grid-area: join; @@ -587,35 +590,6 @@ main .top button { width: 100%; } - -.ready-btn:hover, .ready-btn:focus, .ready-btn:active { - color: forestgreen; -} - -.ready { - color: forestgreen; - transition-property: color, background; - transition-duration: 0.5s; - transition-timing-function: ease; -} - -button.ready { - width: 75%; - font-size: 150%; - line-height: 3em; - - &:hover { - color: forestgreen; - border-color: forestgreen; - } - - &:active, &:focus { - background: forestgreen; - color: black; - border-color: forestgreen; - } -} - .timer-container { display: flex; flex: 1 1 100%; diff --git a/client/assets/styles/styles.mobile.css b/client/assets/styles/styles.mobile.css index 68e27ca9..fc6a30bf 100644 --- a/client/assets/styles/styles.mobile.css +++ b/client/assets/styles/styles.mobile.css @@ -21,6 +21,10 @@ display: none; } + aside { + display: none; + } + footer { display: flex; } diff --git a/client/index.js b/client/index.js index adbb294e..a3db2940 100644 --- a/client/index.js +++ b/client/index.js @@ -1,9 +1,10 @@ require('./assets/styles/styles.less'); -require('./assets/styles/styles.mobile.css'); require('./assets/styles/instance.less'); require('./assets/styles/vbox.less'); -require('./assets/styles/instance.mobile.css'); require('./assets/styles/game.less'); +require('./assets/styles/controls.less'); +require('./assets/styles/styles.mobile.css'); +require('./assets/styles/instance.mobile.css'); // kick it off require('./src/app'); diff --git a/client/src/components/controls.jsx b/client/src/components/controls.jsx index fb182e47..cc4fe990 100644 --- a/client/src/components/controls.jsx +++ b/client/src/components/controls.jsx @@ -1,33 +1,40 @@ const preact = require('preact'); const { connect } = require('preact-redux'); +const InstanceCtrl = require('./instance.ctrl'); +const GameCtrl = require('./game.ctrl'); +const PlayCtrl = require('./play.ctrl'); + const addState = connect( function receiveState(state) { const { ws, - game + game, + instance, + nav, } = state; - function sendGameReady() { - document.activeElement.blur() - return ws.sendGameReady(game.id); - } - - return { game, sendGameReady }; + return { + game, + instance, + nav, + }; }, ); function Controls(args) { const { game, - sendGameReady + instance, + nav, + sendGameReady, } = args; - return ( -
- -
- ); + if (instance) return ; + if (game) return ; + if (nav === 'play' || !nav) return + + return false; } module.exports = addState(Controls); diff --git a/client/src/components/faceoff.jsx b/client/src/components/faceoff.jsx index 2da6db6a..a2a1b5a9 100644 --- a/client/src/components/faceoff.jsx +++ b/client/src/components/faceoff.jsx @@ -4,6 +4,7 @@ const { connect } = require('preact-redux'); const actions = require('../actions'); const { ConstructAvatar } = require('./construct'); +const Controls = require('./controls'); const addState = connect( function receiveState(state) { @@ -81,7 +82,6 @@ function Faceoff(props) { {OpponentTeam(otherTeam)} {PlayerTeam(playerTeam)}

{playerTeam.name}

- ); } diff --git a/client/src/components/game.ctrl.jsx b/client/src/components/game.ctrl.jsx new file mode 100644 index 00000000..e158ce7e --- /dev/null +++ b/client/src/components/game.ctrl.jsx @@ -0,0 +1,38 @@ +const preact = require('preact'); +const { connect } = require('preact-redux'); + +const InstanceCtrl = require('./instance.ctrl'); + +const addState = connect( + function receiveState(state) { + const { + ws, + game, + } = state; + + function sendGameReady() { + document.activeElement.blur() + return ws.sendGameReady(game.id); + } + + return { + game, + sendGameReady, + }; + }, +); + +function Controls(args) { + const { + game, + sendGameReady + } = args; + + return ( + + ); +} + +module.exports = addState(Controls); diff --git a/client/src/components/game.jsx b/client/src/components/game.jsx index 65dbecd3..10954d87 100644 --- a/client/src/components/game.jsx +++ b/client/src/components/game.jsx @@ -101,7 +101,6 @@ function Game(props) { {otherTeams.map(OpponentTeam)} {PlayerTeam(playerTeam, setActiveSkill)} - ); } diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index cdc6cb3b..ec023e3f 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -9,13 +9,16 @@ const ScoreBoard = require('./scoreboard'); function InfoComponent(args) { const { - info, itemInfo, combiner, player, instance, + info, } = args; + // args.info = 'Life'; + // const { info } = args; + function Info() { if (!info) return false; const fullInfo = itemInfo.items.find(i => i.item === info) || INFO[info]; @@ -47,7 +50,12 @@ function InfoComponent(args) { const thresholds = colourReqs.map((bonus, i) => { const colours = ['red', 'green', 'blue']; - const colourGoals = colours.map(c => { + const colourGoals = { + red: [], + green: [], + blue: [], + }; + colours.forEach(c => { const colourReq = bonus.req[c]; if (colourReqs === 0) return false; @@ -62,18 +70,16 @@ function InfoComponent(args) { ? 'unmet' : ''; - return ( + colourGoals[c].push(
- {shapes.square([c])} + {shapes.vboxColour(c)}
); + + return true; }); - return ( -
- {dots} -
- ); + return dots; }); const reqsMet = colours.every(c => teamColours[c] >= bonus.req[c]); @@ -82,14 +88,20 @@ function InfoComponent(args) { ? '' : 'unmet'; + const goals = colours.map((c, j) => { + if (colourGoals[c].length) { + return ( +
{colourGoals[c]}
+ ); + } + return false; + }); + return (
-
- {colourGoals} -
-
+ {goals} +
+ {bonus.bonus} -
); diff --git a/client/src/components/instance.ctrl.jsx b/client/src/components/instance.ctrl.jsx new file mode 100644 index 00000000..9d7c3329 --- /dev/null +++ b/client/src/components/instance.ctrl.jsx @@ -0,0 +1,33 @@ +const preact = require('preact'); +const { connect } = require('preact-redux'); + +const addState = connect( + function receiveState(state) { + const { + ws, + instance + } = state; + + function sendInstanceReady() { + document.activeElement.blur() + return ws.sendInstanceReady(instance.id); + } + + return { instance, sendInstanceReady }; + }, +); + +function Controls(args) { + const { + instance, + sendInstanceReady + } = args; + + return ( + + ); +} + +module.exports = addState(Controls); diff --git a/client/src/components/inventory.jsx b/client/src/components/inventory.jsx index e17d23d6..4f074240 100644 --- a/client/src/components/inventory.jsx +++ b/client/src/components/inventory.jsx @@ -62,13 +62,17 @@ function Inventory(args) { return (
-

¤ {account.balance}

-
- {shop.owned.map(useMtx)} +
+

¤ {account.balance}

+
+ {shop.owned.map(useMtx)} +
-

Shop

-
- {shop.available.map(availableMtx)} +
+

Shop

+
+ {shop.available.map(availableMtx)} +
); diff --git a/client/src/components/main.jsx b/client/src/components/main.jsx index 1bfd2c16..0e01cd59 100644 --- a/client/src/components/main.jsx +++ b/client/src/components/main.jsx @@ -27,8 +27,6 @@ function Main(props) { return ; } - if (nav === 'play') return ; - if (game) { return ; } @@ -37,6 +35,7 @@ function Main(props) { return ; } + if (nav === 'play') return ; if (nav === 'team') return ; return ( diff --git a/client/src/components/mnml.jsx b/client/src/components/mnml.jsx index 1ed39d70..30ae1d10 100644 --- a/client/src/components/mnml.jsx +++ b/client/src/components/mnml.jsx @@ -4,6 +4,7 @@ const { connect } = require('preact-redux'); // const Header = require('./header'); const Main = require('./main'); const Nav = require('./nav'); +const Controls = require('./controls'); const Footer = require('./footer'); const addState = connect( @@ -14,6 +15,7 @@ const Mnml = ({ showNav }) =>
; diff --git a/client/src/components/join.jsx b/client/src/components/play.ctrl.jsx similarity index 53% rename from client/src/components/join.jsx rename to client/src/components/play.ctrl.jsx index c77ebc39..9efd672a 100644 --- a/client/src/components/join.jsx +++ b/client/src/components/play.ctrl.jsx @@ -27,23 +27,20 @@ function JoinButtons(args) { } = args; return ( -
-

Join Game

-
- - -
-
+ ); } diff --git a/client/src/components/play.jsx b/client/src/components/play.jsx index 13fa2adb..43d8ebe9 100644 --- a/client/src/components/play.jsx +++ b/client/src/components/play.jsx @@ -4,7 +4,6 @@ const preact = require('preact'); const { stringSort } = require('./../utils'); const { ConstructAvatar } = require('./construct'); const actions = require('./../actions'); -const Join = require('./join'); const Inventory = require('./inventory'); const idSort = stringSort('id'); @@ -113,7 +112,6 @@ function Play(args) { {constructPanels}
- ); } diff --git a/client/src/components/scoreboard.jsx b/client/src/components/scoreboard.jsx index 010b8f47..ee2e9e1d 100644 --- a/client/src/components/scoreboard.jsx +++ b/client/src/components/scoreboard.jsx @@ -8,18 +8,13 @@ const addState = connect( instance } = state; - function sendInstanceReady() { - return ws.sendInstanceReady(instance.id); - } - - return { instance, sendInstanceReady }; + return { instance }; }, ); function ScoreBoard(args) { const { instance, - sendInstanceReady } = args; const players = instance.players.map((p, i) => { @@ -46,14 +41,11 @@ function ScoreBoard(args) { }); return ( -
- - - - {players} - -
-
+ + + {players} + +
); } diff --git a/client/src/components/vertical.thresholds.js b/client/src/components/vertical.thresholds.js new file mode 100644 index 00000000..ab079170 --- /dev/null +++ b/client/src/components/vertical.thresholds.js @@ -0,0 +1,172 @@ +const preact = require('preact'); +const range = require('lodash/range'); + +const { INFO } = require('./../constants'); +const { convertItem } = require('../utils'); +const shapes = require('./shapes'); + +const ScoreBoard = require('./scoreboard'); + +function InfoComponent(args) { + const { + itemInfo, + combiner, + player, + instance, + } = args; + + args.info = 'PowerRG'; + const { info } = args; + + function Info() { + if (!info) return false; + const fullInfo = itemInfo.items.find(i => i.item === info) || INFO[info]; + if (!fullInfo) return false; + const isSkill = fullInfo.skill; + const isSpec = fullInfo.spec; + + if (isSkill) { + return ( +
+

{fullInfo.item}

+
{fullInfo.description}
+
+ ); + } + + if (isSpec) { + let red = 0; + let blue = 0; + let green = 0; + player.constructs.forEach(construct => { + red += construct.colours.red; + blue += construct.colours.blue; + green += construct.colours.green; + }); + const teamColours = { red, blue, green }; + + const colourReqs = fullInfo.values.bonuses || []; + + const thresholds = colourReqs.map((bonus, i) => { + const colours = ['red', 'green', 'blue']; + const colourGoals = colours.map(c => { + const colourReq = bonus.req[c]; + if (colourReqs === 0) return false; + + const start = i === 0 + ? 0 + : colourReqs[i - 1].req[c]; + + const dots = range(start, colourReq).map(j => { + const unmet = teamColours[c] < j + 1; + + const reqClass = unmet + ? 'unmet' + : ''; + + return ( +
+ {shapes.square([c])} +
+ ); + }); + + return ( +
+ {dots} +
+ ); + }); + + const reqsMet = colours.every(c => teamColours[c] >= bonus.req[c]); + + const reqClass = reqsMet + ? '' + : 'unmet'; + + return ( +
+
+ {colourGoals} +
+
+ + {bonus.bonus} +
+
+
+ ); + }); + + return ( +
+

{info}

+
{fullInfo.description}
+
+ {thresholds} +
+
+ ); + } + + return ( +
+

{fullInfo.item}

+
{fullInfo.description}
+
+ ); + } + + function Combos() { + if (!player) return false; + + // show recipe for what's in combiner + if (combiner.some(u => u !== null)) { + const filteredCombos = itemInfo.combos + .filter(combo => combiner.every(u => u === null + || combo.components.includes(player.vbox.bound[u]))); + if (filteredCombos.length > 6) return false; + return ( + + + {filteredCombos.map((c, i) => + + + {c.components.map((u, j) => )} + + )} + +
{convertItem(c.item)}{convertItem(u)}
+ ); + } + + if (!info) return false; + const vboxCombos = itemInfo.combos.filter(c => c.components.includes(info)); + if (vboxCombos.length > 6) return false; + return ( + + + {vboxCombos.map((c, i) => + + + {c.components.map((u, j) => )} + + )} + +
{convertItem(c.item)}{convertItem(u)}
+ ); + } + + const scoreboard = instance.phase === 'Lobby' || info + ? null + : ; + + return ( +
+ {scoreboard} + + +
+ ); +} + +module.exports = InfoComponent; diff --git a/client/src/socket.jsx b/client/src/socket.jsx index 78ebd771..58a04f86 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -177,7 +177,7 @@ function createSocket(events) { let pongTimeout; function onPong() { events.setPing(Date.now() - ping); - pongTimeout = setTimeout(sendPing, 1000); + // pongTimeout = setTimeout(sendPing, 1000); } // -------------