diff --git a/client/cryps.css b/client/cryps.css index 08d4e7d8..9743f89e 100644 --- a/client/cryps.css +++ b/client/cryps.css @@ -131,7 +131,6 @@ button.action { } - svg { flex: 1; fill: none; @@ -162,6 +161,23 @@ table td { text-transform: uppercase; } +table td svg { + stroke-width: 2px; + height: 96%; + vertical-align: text-bottom; +} + +table .highlight { + background: whitesmoke; + color: black; + font-weight: bold; +} + +button[disabled] { + color: #333; + border-color: #333; +} + /* COLOURS */ diff --git a/client/instance.css b/client/instance.css index 9db6bbeb..978ce740 100644 --- a/client/instance.css +++ b/client/instance.css @@ -7,70 +7,53 @@ grid-template-columns: repeat(12, 1fr); grid-template-rows: repeat(11, 1fr); grid-template-areas: - "n v v v v v v v x x x x" - "n v v v v v v v x x x x" - "n v v v v v v v x x x x" - "n v v v v v v v x x x x" - "g g g g g g g g x x x x" - "g g g g g g g g x x x x" - "f f f f f f f f x x x x" - "f f f f f f f f x x x x" - "f f f f f f f f x x x x" - "f f f f f f f f x x x x" - "f f f f f f f f x x x x"; + "n v v v v v v v v i i i" + "n v v v v v v v v i i i" + "n v v v v v v v v i i i" + "n v v v v v v v v i i i" + "n e e e e e e e e e e e" + "n e e e e e e e e e e e" + "c c c c c c c c c c c c" + "c c c c c c c c c c c c" + "c c c c c c c c c c c c" + "c c c c c c c c c c c c" + "c c c c c c c c c c c c"; } .instance-hdr { grid-area: n; display: flex; - flex-flow: row; + flex-flow: column; flex: 0 0 100%; + padding-top: 50px; + padding-right: 20px; } .instance-info { - grid-area: x; + grid-area: i; justify-self: start; - flex: 0 0 50%; + padding-left: 20px; } - -.instance-cryp-list { - grid-area: f; - flex: 1 1 auto; - display: flex; - flex-flow: row; - padding: 0 2em 0 2em; - justify-content: center; - min-width: 300px; - - overflow: hidden; -} - - .instance .spacer { flex-grow: 1 } .vbox { grid-area: v; - display: grid; - grid-template-columns: repeat(11, 1fr); - grid-template-rows: repeat(2, 1fr); - grid-template-areas: - "vb vb vb vb vb . i i i i i" - "vb vb vb vb vb . i i i i i"; + display: flex; + justify-content: flex-end; } .vbox-box { - grid-area: vb; justify-self: end; max-width: 450px; display: flex; flex-flow: row wrap; + padding-right: 50px; } .vbox-inventory { - grid-area: i; justify-self: start; max-width: 450px; display: flex; @@ -121,16 +104,7 @@ margin: 0; } -table .highlight { - background: whitesmoke; - color: black; - font-weight: bold; -} - -button[disabled] { - color: #333; - border-color: #333; -} +/* VBOX */ .vbox-btn:active, .vbox-btn:hover, .vbox-btn:focus { color: black; @@ -183,70 +157,246 @@ button[disabled] { color: black; } -table td svg { - stroke-width: 2px; - height: 96%; - vertical-align: text-bottom; -} - .spacer { flex: 1 0 25%; } /* CRYP BOX */ -.instance-cryp { - flex: 1 1 auto; +.instance-cryp-list { + grid-area: c; + flex: 1 1 auto; display: flex; - flex-flow: column; - border: 1px solid whitesmoke; + flex-flow: row; + padding: 0 2em 0 2em; + align-content: flex-start; + justify-content: center; + min-width: 300px; + + overflow: hidden; +} + +.instance-cryp { + display: grid; + grid-template-columns: repeat(5, 1fr); + grid-template-rows: repeat(5, 1fr); + grid-template-areas: + "sp sp sp sp sp" + "av av av sk sk" + "av av av sk sk" + "av av av sk sk" + "st st st st st"; + max-height: 450px; + max-width: 450px; margin-left: 1em; - max-width: 350px; + border: 1px solid whitesmoke; transition-property: all; transition-duration: 0.5s; transition-delay: 0; transition-timing-function: ease; } -.instance-cryp-top { +.instance-cryp .avatar { + grid-area: av; display: flex; flex: 1 1 auto; - width: 100%; - justify-content: center; - align-items: stretch; } -.instance-cryp figure { +.instance-cryp .avatar figure { margin: 0; - flex: 0 0 50%; + height: 80%; text-align: center; box-sizing: border-box; +} + +.instance-cryp .avatar figcaption { + font-size: 90%; +} + +.instance-cryp .skills { + grid-area: sk; display: flex; flex-flow: column; - justify-content: flex-end; } -.instance-cryp .stats { - flex: 0 0 20%; +.instance-cryp .skills button { + height: 100%; width: 100%; - display: flex; - border-top: 1px solid whitesmoke; } -.stats figure { - flex: 1 1 0; +.instance-cryp .specs { + grid-area: sp; + display: flex; + flex: 1; + justify-content: center; + border-bottom: 1px solid whitesmoke; +} + +.instance-cryp .specs figure { + flex: 1; border: 0; align-items: center; padding: 0.5em 0 0 0; + text-align: center; +} + +.instance-cryp .specs figcaption { + font-size: 75%; +} + +.instance-cryp .stats { + grid-area: st; + display: grid; + grid-template-rows: 1fr 3fr; + grid-template-columns: 3fr 1fr 3fr; + grid-template-areas: + "dl sl ll" + "di si li"; + border-top: 1px solid whitesmoke; +} + +.instance-cryp .stats figure { + flex: 1; + border: 0; + align-items: center; + padding: 0.5em 0 0 0; + text-align: center; } .instance-cryp .stats figcaption { font-size: 75%; } -.instance-cryp .skills { +.instance-cryp .stats .damage-label { + grid-area: dl; display: flex; - flex-flow: row wrap; - flex: 1 1 50%; + justify-content: center; +} + +.instance-cryp .stats .damage-icons { + grid-area: di; + display: flex; + flex-flow: row; + flex: 1; + justify-content: center; +} + +.instance-cryp .stats .speed-label { + grid-area: sl; + display: flex; + justify-content: center; + +} + +.instance-cryp .stats .speed-icons { + grid-area: si; + display: flex; + flex-flow: row; + flex: 1; + justify-content: center; +} + +.instance-cryp .stats .life-label { + grid-area: ll; + display: flex; + justify-content: center; +} + +.instance-cryp .stats .life-icons { + grid-area: li; + display: flex; + flex-flow: row; + flex: 1; + justify-content: center; +} + +/* Equipment */ +.instance-equip { + grid-area: e; + display: flex; + justify-content: center; +} + +.instance-equip .items { + display: flex; + justify-content: center; + flex: 1 1 100%; +} + +.instance-equip .label { + display: flex; + justify-content: center; + font-size: 20pt; + padding: 15px; + +} +.instance-equip .skills { + display: flex; + flex-direction: column; +} + +.instance-equip .skills button { + flex: 1 1 100%; + color: whitesmoke; + font-size: 16pt; + padding: 10px; + border-width: 0px; + border-bottom-width: 1px; + border-left-width: 1px; + border-right-width: 1px; + border-top-width: 1px; height: 100%; -} \ No newline at end of file + +} + +button.equip { + animation: equip-skill 1s infinite ease-in-out alternate; +} + +@keyframes equip-skill { + 0% { + background-color: black; + box-shadow: inset 0 0 0 0 whitesmoke; + } + + 100% { + background-color: #181818; + box-shadow: inset 0.5em 0 0 0 whitesmoke; + } +} + + +.instance-equip .specs { + display: flex; + padding-left: 50px; + flex-direction: column; +} + +.instance-equip .specs figure { + flex: 1; + border: 0; + padding: 0.5em 1em 0 0; + text-align: center; +} + +.equip-spec { + animation: equip-spec 1s infinite ease-in-out alternate; +} + +@keyframes equip-spec { + 0% { + color: #333; + stroke: #333; + } + + 100% { + color: #7a7a7a; + stroke: #7a7a7a; + + } +} + + +.instance-equip .specs figcaption { + font-size: 75%; +} diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index 317fccb8..3b5b07ba 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -55,10 +55,12 @@ function Info(args) { } if (type === 'skill') { + const skillInfo = SKILLS[value.skill]; + const description = skillInfo ? skillInfo.description : '?????'; return (
{value.skill}
-
{SKILLS[value.skill].description}
+
{description}
@@ -165,11 +167,11 @@ function Info(args) { if (activeCryp) return false; if (!player) return false; - if (combiner[0] !== null) { + if (!(combiner.every(u => u === null))) { const filteredCombos = vboxInfo.combos .filter(combo => combiner.every(u => u === null || combo.units.includes(player.vbox.bound[u]))); - + if (filteredCombos.length > 6) return false; return ( @@ -183,11 +185,12 @@ function Info(args) {
); } - + const vboxCombos = vboxInfo.combos.filter(c => c.units.includes(info[1])); + if (vboxCombos.length > 6) return false; return ( - {vboxInfo.combos.filter(c => c.units.includes(info[1])).map((c, i) => + {vboxCombos.map((c, i) => {c.units.map((u, j) => )} @@ -206,12 +209,12 @@ function Info(args) { return (
- -
); } +// not required anymore +// Takes up too much space maybe a context switch module.exports = Info; diff --git a/client/src/components/instance.component.jsx b/client/src/components/instance.component.jsx index d4e75669..d6fdf09c 100644 --- a/client/src/components/instance.component.jsx +++ b/client/src/components/instance.component.jsx @@ -3,6 +3,7 @@ const preact = require('preact'); const VboxContainer = require('./vbox.container'); const InfoContainer = require('./info.container'); const InstanceCrypsContainer = require('./instance.cryps'); +const EquipmentContainer = require('./instance.equip'); function InstanceComponent(args) { const { @@ -88,10 +89,11 @@ function InstanceComponent(args) {
 
{actionBtn} + {timer} - {timer} + ); diff --git a/client/src/components/instance.cryps.jsx b/client/src/components/instance.cryps.jsx index 8038d0be..473cad75 100644 --- a/client/src/components/instance.cryps.jsx +++ b/client/src/components/instance.cryps.jsx @@ -3,12 +3,12 @@ const preact = require('preact'); const range = require('lodash/range'); const shapes = require('./shapes'); -const { SPECS, crypAvatar } = require('../utils'); +const { SPECS, STATS, crypAvatar } = require('../utils'); const actions = require('../actions'); const addState = connect( function receiveState(state) { - const { ws, instance, player, account, vboxHidden, vboxInfo } = state; + const { ws, instance, player, account, vboxHidden, vboxInfo, activeVar } = state; function sendInstanceReady() { return ws.sendInstanceReady(instance.id); @@ -18,7 +18,7 @@ const addState = connect( return ws.sendVboxApply(instance.id, crypId, i); } - return { instance, player, account, sendInstanceReady, sendVboxApply, vboxHidden, vboxInfo }; + return { instance, player, account, sendInstanceReady, sendVboxApply, vboxHidden, vboxInfo, activeVar }; }, function receiveDispatch(dispatch) { @@ -49,11 +49,14 @@ const addState = connect( function Cryp(props) { const { + activeVar, cryp, + player, + sendVboxApply, setInfo, setActiveCryp, - vboxInfo, setVboxHighlight, + vboxInfo, } = props; function setHighlight(type) { @@ -62,6 +65,17 @@ function Cryp(props) { return false; } + function onClick(e) { + e.stopPropagation(); + e.preventDefault(); + if (activeVar !== null) return sendVboxApply(cryp.id, activeVar); + return setActiveCryp(cryp); + } + + const { vbox } = player; + const skillList = vboxInfo.vars.filter(v => v.skill).map(v => v.v); + const specList = vboxInfo.vars.filter(v => v.spec).map(v => v.v); + const skills = range(0, 3).map(i => { const skill = cryp.skills[i]; const s = skill @@ -69,36 +83,43 @@ function Cryp(props) { : (+); function skillClick(e) { + if (!skill && activeVar !== null) return sendVboxApply(cryp.id, activeVar); if (!skill) setHighlight('skill'); else setInfo('skill', { skill: skill.skill, cryp }); e.stopPropagation(); return setActiveCryp(cryp); } - const classes = `right ${skill ? '' : 'action'}`; - return ; + const action = skill ? '' : 'action'; + const equip = skillList.includes(vbox.bound[activeVar]) && !skill ? 'equip' : ''; + const classes = `right ${action} ${equip}`; + return ( + + ); }); - function onClick(e) { - e.stopPropagation(); - e.preventDefault(); - return setActiveCryp(cryp); - } - const specs = range(0, 6).map(i => { const s = cryp.specs[i]; function blankSpecClick(e) { e.stopPropagation(); - setActiveCryp(cryp); + if (activeVar !== null) return sendVboxApply(cryp.id, activeVar); setHighlight('spec'); + return setActiveCryp(cryp); } if (!s) { + const equip = specList.includes(vbox.bound[activeVar]) ? 'equip-spec' : 'gray'; return ( +<<<<<<< HEAD
{shapes.diamond('stat-icon gray')}
+
+======= +
+ {shapes.diamond(`stat-icon ${equip}`)} +
 
+>>>>>>> 2318ff3974d80a7c29246cdc8a3eb1653ea45b91
); } @@ -117,6 +138,27 @@ function Cryp(props) { ); }); + const damage = Object.values(STATS).slice(0, 3).map(s => ( +
+ {s.svg(`stat-icon ${s.colour}`)} +
{cryp[s.stat].value}
+
+ )); + + const speed = Object.values(STATS).slice(3, 4).map(s => ( +
+ {s.svg(`stat-icon ${s.colour}`)} +
{cryp[s.stat].value}
+
+ )); + + const life = Object.values(STATS).slice(4, 8).map(s => ( +
+ {s.svg(`stat-icon ${s.colour}`)} +
{cryp[s.stat].value}
+
+ )); + // const cTotal = cryp.colours.red + cryp.colours.blue + cryp.colours.green; // const colours = mapValues(cryp.colours, c => { // if (cTotal === 0) return 245; @@ -130,20 +172,39 @@ function Cryp(props) { // return 4; // }; // const border = { border: `${thickness(cTotal)}px solid rgba(${colours.red}, ${colours.green}, ${colours.blue}, ${alpha})` }; - return (
-
+
{crypAvatar(cryp.name)}
{cryp.name}
-
- {skills} -
+
+
+ {skills} +
+
+ {specs}
- {specs} +
+ Damage +
+
+ {damage} +
+
+ Speed +
+
+ {speed} +
+
+ Life +
+
+ {life} +
); @@ -151,9 +212,9 @@ function Cryp(props) { function InstanceCryps(props) { const { + activeVar, player, instance, - // clearInfo, setInfo, setActiveCryp, @@ -168,7 +229,7 @@ function InstanceCryps(props) { if (instance.phase === 'Lobby') return false; const cryps = player.cryps.map((c, i) => Cryp({ - cryp: c, sendVboxApply, setInfo, setActiveCryp, vboxInfo, setVboxHighlight, + activeVar, cryp: c, player, sendVboxApply, setInfo, setActiveCryp, vboxInfo, setVboxHighlight, })); const classes = `instance-cryp-list ${vboxHidden ? '' : 'hidden'}`; diff --git a/client/src/components/instance.equip.jsx b/client/src/components/instance.equip.jsx new file mode 100644 index 00000000..53ee434a --- /dev/null +++ b/client/src/components/instance.equip.jsx @@ -0,0 +1,102 @@ +const { connect } = require('preact-redux'); +const preact = require('preact'); +const range = require('lodash/range'); + +const actions = require('../actions'); +const { convertVar, SPECS } = require('./../utils'); + +const addState = connect( + function receiveState(state) { + const { player, vboxInfo } = state; + + return { player, vboxInfo }; + }, + + function receiveDispatch(dispatch) { + function setInfo(item, value) { + dispatch(actions.setInfo([item, value])); + } + + function clearInfo() { + return dispatch(actions.setInfo([])); + } + + function setActiveVar(v) { + return dispatch(actions.setActiveVar(v)); + } + + return { setInfo, setActiveVar, clearInfo }; + } + +); + +function Equipment(props) { + const { + player, + vboxInfo, + setInfo, + setActiveVar, + } = props; + + const { vbox } = player; + + function boundClick(e, i) { + const value = vbox.bound[i]; + setInfo('item', value); + setActiveVar(i); + return false; + } + + // const classes = `right ${skill ? '' : 'action'}`; + const skillList = vboxInfo.vars.filter(v => v.skill).map(v => v.v); + const specList = vboxInfo.vars.filter(v => v.spec).map(v => v.v); + + const skills = range(0, 9).map(i => { + const item = convertVar(vbox.bound[i]); + if (skillList.includes(item)) { + return ( + + ); + } return false; + }); + + const specs = range(0, 9).map(i => { + const item = convertVar(vbox.bound[i]); + if (specList.includes(item)) { + return ( +
boundClick(e, i)}> + {SPECS[item].svg(`stat-icon ${SPECS[item].colour}`)} +
{SPECS[item].caption}
+
+ ); + } return false; + }); + + const skillLabel = skills.every(i => i === false) ? '' : 'Skills'; + const specLabel = specs.every(i => i === false) ? '' : 'Specs'; + + return ( +
+
+
+ {skillLabel} +
+
+ {skills} +
+
+
+
+ {specLabel} +
+
+ {specs} +
+
+
+ ); +} + +module.exports = addState(Equipment); diff --git a/client/src/utils.jsx b/client/src/utils.jsx index 70ce7a55..8cc4bb5b 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -65,10 +65,10 @@ function crypAvatar(name) { const NULL_UUID = '00000000-0000-0000-0000-000000000000'; const STATS = { - speed: { stat: 'speed', colour: 'white', svg: shapes.triangle }, redDamage: { stat: 'red_damage', colour: 'red', svg: shapes.circle }, greenDamage: { stat: 'green_damage', colour: 'green', svg: shapes.circle }, blueDamage: { stat: 'blue_damage', colour: 'blue', svg: shapes.circle }, + speed: { stat: 'speed', colour: 'white', svg: shapes.triangle }, redLife: { stat: 'red_life', colour: 'red', svg: shapes.square }, greenLife: { stat: 'green_life', colour: 'green', svg: shapes.square }, blueLife: { stat: 'blue_life', colour: 'blue', svg: shapes.square }, diff --git a/server/src/instance.rs b/server/src/instance.rs index d02e75fa..c5390115 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -275,7 +275,7 @@ impl Instance { fn next_round(&mut self) -> &mut Instance { self.phase = InstancePhase::InProgress; self.phase_end = Utc::now() - .checked_add_signed(Duration::seconds(150)) + .checked_add_signed(Duration::seconds(15000)) .expect("could not set phase end"); diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 46efd03c..660902a7 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -272,6 +272,7 @@ impl From for Var { Skill::Curse => Var::Curse, Skill::Clutch => Var::Clutch, Skill::Decay => Var::Decay, + Skill::Debuff => Var::Debuff, Skill::Haste => Var::Haste, Skill::Hostility => Var::Hostility, Skill::Heal => Var::Heal, @@ -551,7 +552,7 @@ impl Vbox { // actually move self.bound.push(self.free[i].remove(j)); - self.bound.sort_unstable(); + // self.bound.sort_unstable(); Ok(self) }
{convertVar(c.var)}{convertVar(u)}