From e53983db98e70d15aece4f56055842d2cf083a45 Mon Sep 17 00:00:00 2001 From: Mashy Date: Wed, 20 Nov 2019 21:47:19 +1000 Subject: [PATCH 01/97] rearrange vbox wip --- client/assets/styles/vbox.less | 81 ++++++++++-------- client/src/components/vbox.component.jsx | 103 +++++++++++++---------- 2 files changed, 105 insertions(+), 79 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index ea0d9fd7..c928028b 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -1,6 +1,50 @@ .vbox { - margin-bottom: 2em; + + align-content: space-between; + grid-area: vbox; + display: grid; + grid-template-rows: min-content 3.5em min-content 1em min-content 3.5em min-content; + grid-template-columns: 7em 1em 25em; + grid-template-areas: + "shop-hdr . shop" + ". . shop" + "combiner . shop" + "combiner . ." + "combiner . stash" + ". . stash" + "stash-hdr . stash"; + + margin-bottom: 1em; line-height: 0; + + .shop { + grid-area: shop; + } + + .shop-hdr { + grid-area: shop-hdr; + display: flex; + flex-direction: column; + } + + .combiner { + grid-area: combiner; + display: flex; + flex-direction: column; + + } + + .stash { + grid-area: stash; + display: flex; + flex-direction: column; + + } + + .stash-hdr { + grid-area: stash-hdr; + } + .vbox-hdr { margin-bottom: 1em; height: 2em; @@ -104,22 +148,6 @@ } } -/* VBOX */ -.vbox { - align-content: space-between; - grid-area: vbox; - display: grid; - grid-template-rows: min-content min-content min-content; - grid-template-columns: 1fr min-content 1fr; - grid-template-areas: - "vbox varrow inventory" - "vbox varrow combiner"; -} - -.vbox-inventory { - grid-area: inventory; -} - .vbox-combiner { grid-area: combiner; display: flex; @@ -127,18 +155,6 @@ justify-content: flex-end; } -.vbox-arrow, .vbox-arrow-mobile { - display: flex; - justify-content:center; - align-content:center; - flex-direction:column; - - margin: 1em 0.25em 0 0.25em; - grid-area: varrow; - font-size: 2em; - color: @gray-hint; -} - .vbox-combiner button { flex: 0; } @@ -156,9 +172,4 @@ font-size: 2em; line-height: 1em; animation: bits 1s ease-out; -} - -.arrow { - grid-area: arrow; - color: @gray-hint; -} +} \ No newline at end of file diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 9263662d..eedb6527 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -232,15 +232,8 @@ class Vbox extends preact.Component { function vboxElement() { return ( -
e.stopPropagation()}> -
-

e.target.scrollIntoView(true)} - onMouseOver={e => hoverInfo(e, 'vbox')}> VBOX -

-
hoverInfo(e, 'bits')} >{vbox.bits}b
-
{range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))}
@@ -248,6 +241,21 @@ class Vbox extends preact.Component { {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))}
+ + + ); + } + + function vboxHdr() { + return ( +
+

e.target.scrollIntoView(true)} + onMouseOver={e => hoverInfo(e, 'vbox')}> VBOX +

+
hoverInfo(e, 'bits')}> +

{vbox.bits}b

+
); } - // // INVENTORY // - function reclaimClick(e) { - e.stopPropagation(); - return setReclaiming(!reclaiming); - } function inventoryBtn(v, i) { const inventoryHighlight = vboxSelecting || itemUnequip.length; @@ -353,12 +357,12 @@ class Vbox extends preact.Component { let bits = 0; shopSelect.forEach(item => bits += item[0] + 1); text = bits - ? `Buy ${comboItem} - ${bits}b` - : `Combine - ${comboItem}`; + ?

Buy
{comboItem}
{bits}b

+ :

Combine
{comboItem}

; if (vbox.bits >= bits) mouseEvent = sendVboxCombine; } else if (stashSelect.length === 0 && shopSelect.length === 1) { const item = shopSelect[0]; - text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`; + text =

Buy
{vbox.free[item[0]][item[1]]}
{item[0] + 1}b

; mouseEvent = vboxBuySelected; } else { for (let i = 0; i < 3; i++) { @@ -370,13 +374,15 @@ class Vbox extends preact.Component { } } return ( - +
+ +
); } @@ -389,34 +395,42 @@ class Vbox extends preact.Component { return (
e.stopPropagation()} onDragOver={ev => ev.preventDefault()} onDrop={inventoryClick} > -
-

e.target.scrollIntoView(true)} - onMouseOver={e => hoverInfo(e, 'inventory')}> INVENTORY -

- -
-
- {range(0, 9).map(i => inventoryBtn(vbox.bound[i], i))} + {range(0, 6).map(i => inventoryBtn(vbox.bound[i], i))}
- {combinerBtn()}
); } + function inventoryHdr() { + return ( +
+

e.target.scrollIntoView(true)} + onMouseOver={e => hoverInfo(e, 'inventory')}> INVENTORY +

+ +
+ ); + } + + // // EVERYTHING // @@ -429,12 +443,13 @@ class Vbox extends preact.Component { return setInfo(newInfo); } - const classes = 'vbox'; return ( -
+
+ {vboxHdr()} {vboxElement()} -
+ {inventoryHdr()} {inventoryElement()} + {combinerBtn()}
); } From 3dddf4b1a8984f70ec07f6db1fb830a0f40befc9 Mon Sep 17 00:00:00 2001 From: Mashy Date: Wed, 20 Nov 2019 23:07:44 +1000 Subject: [PATCH 02/97] wip --- WORKLOG.md | 2 + client/assets/styles/instance.less | 2 +- client/assets/styles/vbox.less | 43 +++++++--- client/src/components/vbox.component.jsx | 105 ++++++++++++----------- 4 files changed, 89 insertions(+), 63 deletions(-) diff --git a/WORKLOG.md b/WORKLOG.md index 9ea59bde..24084a60 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -1,6 +1,8 @@ # WORK WORK ## NOW +* add combine between all of shop and stash, stash size -> 4 + *PRODUCTION* * can't reset password without knowing password =\ diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index e54bf31e..04e4f1c6 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -1,7 +1,7 @@ .instance { overflow: hidden; display: grid; - grid-template-columns: 1fr minmax(min-content, 1fr); + grid-template-columns: min-content minmax(min-content, 1fr); grid-template-rows: min-content 1fr; grid-template-areas: diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index c928028b..f3a51bc0 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -3,46 +3,61 @@ align-content: space-between; grid-area: vbox; display: grid; - grid-template-rows: min-content 3.5em min-content 1em min-content 3.5em min-content; - grid-template-columns: 7em 1em 25em; + grid-template-rows: 9em 3em 2em min-content; + grid-template-columns: 7em 25em; grid-template-areas: - "shop-hdr . shop" - ". . shop" - "combiner . shop" - "combiner . ." - "combiner . stash" - ". . stash" - "stash-hdr . stash"; + "shop-hdr shop" + "combiner shop" + "combiner stash" + "stash-hdr stash"; + border-top: 0.1em solid @gray-exists; + border-right: 0.1em solid @gray-exists; + border-bottom: 0.1em solid @gray-exists; margin-bottom: 1em; line-height: 0; + .items { + margin-left: 1em; + margin-bottom: 1em; + margin-top: 0.5em; + margin-right: 1em; + } + .shop { grid-area: shop; + border-bottom: 0.1em solid @gray-exists; } .shop-hdr { grid-area: shop-hdr; display: flex; flex-direction: column; + border-bottom: 0.1em solid @gray-exists; + border-left: 0.1em solid @gray-exists; } .combiner { grid-area: combiner; display: flex; flex-direction: column; + border-right: 0.1em solid @gray-exists; } .stash { grid-area: stash; - display: flex; - flex-direction: column; - } .stash-hdr { grid-area: stash-hdr; + display: flex; + flex-direction: column; + justify-content: flex-end; + border-left: 0.1em solid @gray-exists; + border-top: 0.1em solid @gray-exists; + + } .vbox-hdr { @@ -109,7 +124,7 @@ } button { - height: 4em; + height: 3.25em; margin: 0; width: 100%; @@ -138,7 +153,7 @@ // figures don't scale well figure { svg { - height: 2em; + height: 1.5em; stroke-width: 0.5em; } diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index eedb6527..a2333fef 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -234,14 +234,15 @@ class Vbox extends preact.Component { return (
e.stopPropagation()}> -
- {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} +
+
+ {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} +
+
+ {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} + {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))} +
-
- {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} - {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))} -
-
); } @@ -249,24 +250,26 @@ class Vbox extends preact.Component { function vboxHdr() { return (
-

e.target.scrollIntoView(true)} - onMouseOver={e => hoverInfo(e, 'vbox')}> VBOX -

-
hoverInfo(e, 'bits')}> -

{vbox.bits}b

+
+

e.target.scrollIntoView(true)} + onMouseOver={e => hoverInfo(e, 'vbox')}> VBOX +

+
hoverInfo(e, 'bits')}> +

{vbox.bits}b

+
+
-
); } @@ -375,13 +378,15 @@ class Vbox extends preact.Component { } return (
- +
+ +
); } @@ -401,8 +406,10 @@ class Vbox extends preact.Component { onDragOver={ev => ev.preventDefault()} onDrop={inventoryClick} > -
- {range(0, 6).map(i => inventoryBtn(vbox.bound[i], i))} +
+
+ {range(0, 6).map(i => inventoryBtn(vbox.bound[i], i))} +
); @@ -411,21 +418,23 @@ class Vbox extends preact.Component { function inventoryHdr() { return (
-

e.target.scrollIntoView(true)} - onMouseOver={e => hoverInfo(e, 'inventory')}> INVENTORY -

- +
+

e.target.scrollIntoView(true)} + onMouseOver={e => hoverInfo(e, 'inventory')}> INVENTORY +

+ +
); } From 7dc4a3f4f4f640c6c8b0fed64136282d6fa1b4d7 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 21 Nov 2019 10:42:15 +1000 Subject: [PATCH 03/97] vbox rearrange, rework reclaim --- client/assets/styles/vbox.less | 69 +++++++++++++++--------- client/src/components/info.component.jsx | 6 +-- client/src/components/vbox.component.jsx | 35 ++++++------ 3 files changed, 64 insertions(+), 46 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index f3a51bc0..851a185b 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -3,22 +3,21 @@ align-content: space-between; grid-area: vbox; display: grid; - grid-template-rows: 9em 3em 2em min-content; - grid-template-columns: 7em 25em; + grid-template-rows: 9.5em 2.5em 4.5em min-content; + grid-template-columns: 7em 21em; grid-template-areas: - "shop-hdr shop" - "combiner shop" - "combiner stash" - "stash-hdr stash"; + "shop-hdr shop" + "stash-hdr shop" + "stash-hdr combiner" + "stash stash"; border-top: 0.1em solid @gray-exists; - border-right: 0.1em solid @gray-exists; border-bottom: 0.1em solid @gray-exists; margin-bottom: 1em; line-height: 0; .items { - margin-left: 1em; + margin-left: 0.5em; margin-bottom: 1em; margin-top: 0.5em; margin-right: 1em; @@ -27,37 +26,63 @@ .shop { grid-area: shop; border-bottom: 0.1em solid @gray-exists; + border-right: 0.1em solid @gray-exists; } .shop-hdr { grid-area: shop-hdr; - display: flex; - flex-direction: column; border-bottom: 0.1em solid @gray-exists; border-left: 0.1em solid @gray-exists; + text-align: center; + button { + margin-top: 0.5em; + line-height: 1.6; + height: 4em; + letter-spacing: 0.1em; + background-color: #421010; + } } .combiner { grid-area: combiner; + border-bottom: 0.1em solid @gray-exists; + border-right: 0.1em solid @gray-exists; display: flex; flex-direction: column; - border-right: 0.1em solid @gray-exists; - + button { + height: 3em; + letter-spacing: 0.1em; + background-color: #342100; + &[disabled] { + color: #342100; + }; + } } .stash { grid-area: stash; + .items { + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-gap: 0.5em 1em; + align-items: center; + } + border-right: 0.1em solid @gray-exists; + border-left: 0.1em solid @gray-exists; } .stash-hdr { grid-area: stash-hdr; - display: flex; - flex-direction: column; - justify-content: flex-end; border-left: 0.1em solid @gray-exists; - border-top: 0.1em solid @gray-exists; - - + border-right: 0.1em solid @gray-exists; + text-align: center; + button { + margin-top: 0.5em; + line-height: 1.6; + height: 4em; + letter-spacing: 0.1em; + background-color: #342100; + } } .vbox-hdr { @@ -93,14 +118,6 @@ color: white; } - &.reclaim { - height: auto; - - &:hover { - color: @red; - }; - } - &[disabled] { background: black; border-width: 1px; diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index 71360599..6045c049 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -111,7 +111,7 @@ class InfoComponent extends preact.Component { return (
-

{infoName} {fullInfo.cost}b

+

{infoName}

{header} {itemSourceInfo} {cooldown} @@ -121,10 +121,10 @@ class InfoComponent extends preact.Component {
); } - const cost = fullInfo.cost ? `- ${fullInfo.cost}b` : false; + return (
-

{fullInfo.item} {cost}

+

{fullInfo.item}

{itemDescription()}
); diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index a2333fef..003aa379 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -253,10 +253,10 @@ class Vbox extends preact.Component {

e.target.scrollIntoView(true)} - onMouseOver={e => hoverInfo(e, 'vbox')}> VBOX + onMouseOver={e => hoverInfo(e, 'vbox')}> STORE

hoverInfo(e, 'bits')}> -

{vbox.bits}b

+

{vbox.bits}b

); } function inventoryHdr() { + const refund = shopSelect.length === 0 && stashSelect.length === 1 + ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost + : 0; + const tutorialDisabled = tutorial && tutorial < 8 && instance.time_control === 'Practice' && instance.rounds.length === 1; + return (

e.target.scrollIntoView(true)} - onMouseOver={e => hoverInfo(e, 'inventory')}> INVENTORY + onMouseOver={e => hoverInfo(e, 'inventory')}> STASH

); } - // // EVERYTHING // From 26c1c49c4e55e3adb0d11ac9b82a483556cdd119 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 21 Nov 2019 10:57:46 +1000 Subject: [PATCH 04/97] reduce stash size --- server/src/vbox.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 8df14c6d..a419a6f1 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -100,7 +100,7 @@ impl Vbox { } pub fn accept(&mut self, i: usize, j: usize, construct_id: Option) -> Result<&mut Vbox, Error> { - if self.bound.len() >= 9 && !construct_id.is_some() { + if self.bound.len() >= 4 && !construct_id.is_some() { return Err(err_msg("too many items bound")); } @@ -171,7 +171,7 @@ impl Vbox { self.bound.push(combo.item); // self.bound.sort_unstable(); - if self.bound.len() >= 10 { + if self.bound.len() >= 5 { return Err(err_msg("too many items bound")); } Ok(self) From 917858174ceddeb6df5bdddea420902a2d03ee30 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 21 Nov 2019 11:10:34 +1000 Subject: [PATCH 05/97] delete "reclaim" & "vboxHighlight" state variables --- client/src/actions.jsx | 2 -- client/src/components/account.status.jsx | 2 -- client/src/components/header.jsx | 2 -- client/src/components/instance.component.jsx | 2 -- client/src/components/instance.constructs.jsx | 2 -- client/src/components/nav.jsx | 2 -- client/src/components/vbox.component.jsx | 17 ++--------------- client/src/events.jsx | 2 -- client/src/keyboard.jsx | 2 -- client/src/reducers.jsx | 1 - client/src/tutorial.utils.jsx | 3 +-- 11 files changed, 3 insertions(+), 34 deletions(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 87d0cf51..0c1456af 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -35,7 +35,6 @@ export const setMtxActive = value => ({ type: 'SET_MTX_ACTIVE', value }); export const setNav = value => ({ type: 'SET_NAV', value }); export const setPing = value => ({ type: 'SET_PING', value }); export const setPlayer = value => ({ type: 'SET_PLAYER', value }); -export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value }); export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value }); export const setShop = value => ({ type: 'SET_SHOP', value }); export const setSubscription = value => ({ type: 'SET_SUBSCRIPTION', value }); @@ -48,7 +47,6 @@ export const setTeamSelect = value => ({ type: 'SET_TEAM_SELECT', value: Array.f export const setTutorial = value => ({ type: 'SET_TUTORIAL', value }); export const setTutorialGame = value => ({ type: 'SET_TUTORIAL_GAME', value }); -export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value }); export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value }); export const setWs = value => ({ type: 'SET_WS', value }); diff --git a/client/src/components/account.status.jsx b/client/src/components/account.status.jsx index 99e5014e..1353deff 100644 --- a/client/src/components/account.status.jsx +++ b/client/src/components/account.status.jsx @@ -33,11 +33,9 @@ const addState = connect( function accountPage() { dispatch(actions.setGame(null)); dispatch(actions.setInstance(null)); - dispatch(actions.setReclaiming(false)); dispatch(actions.setActiveSkill(null)); dispatch(actions.setInfo(null)); dispatch(actions.setItemUnequip([])); - dispatch(actions.setVboxHighlight([])); return dispatch(actions.setNav('account')); } diff --git a/client/src/components/header.jsx b/client/src/components/header.jsx index b591afe0..734b1761 100644 --- a/client/src/components/header.jsx +++ b/client/src/components/header.jsx @@ -32,11 +32,9 @@ const addState = connect( function setNav(place) { dispatch(actions.setGame(null)); dispatch(actions.setInstance(null)); - dispatch(actions.setReclaiming(false)); dispatch(actions.setActiveSkill(null)); dispatch(actions.setInfo(null)); dispatch(actions.setItemUnequip([])); - dispatch(actions.setVboxHighlight([])); dispatch(actions.setMtxActive(null)); return dispatch(actions.setNav(place)); } diff --git a/client/src/components/instance.component.jsx b/client/src/components/instance.component.jsx index 8b6c2377..4955469e 100644 --- a/client/src/components/instance.component.jsx +++ b/client/src/components/instance.component.jsx @@ -27,9 +27,7 @@ const addState = connect( function clearItems() { - dispatch(actions.setReclaiming(false)); dispatch(actions.setItemUnequip([])); - dispatch(actions.setVboxHighlight([])); dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] })); return true; } diff --git a/client/src/components/instance.constructs.jsx b/client/src/components/instance.constructs.jsx index 59e77b10..e29a7ad7 100644 --- a/client/src/components/instance.constructs.jsx +++ b/client/src/components/instance.constructs.jsx @@ -258,7 +258,6 @@ class InstanceConstructs extends preact.Component { sendVboxApply, sendVboxAcceptEquip, sendVboxUnequipApply, - setVboxHighlight, setItemUnequip, } = props; @@ -281,7 +280,6 @@ class InstanceConstructs extends preact.Component { sendVboxUnequipApply, setInfo, itemInfo, - setVboxHighlight, vboxSelected, tutorial, }); diff --git a/client/src/components/nav.jsx b/client/src/components/nav.jsx index 0c845c8f..505c41c3 100644 --- a/client/src/components/nav.jsx +++ b/client/src/components/nav.jsx @@ -33,11 +33,9 @@ const addState = connect( function setNav(place) { dispatch(actions.setGame(null)); dispatch(actions.setInstance(null)); - dispatch(actions.setReclaiming(false)); dispatch(actions.setActiveSkill(null)); dispatch(actions.setInfo(null)); dispatch(actions.setItemUnequip([])); - dispatch(actions.setVboxHighlight([])); return dispatch(actions.setNav(place)); } diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 003aa379..42cfa679 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -16,7 +16,6 @@ const addState = connect( ws, instance, player, - reclaiming, vboxSelected, itemInfo, itemUnequip, @@ -47,7 +46,6 @@ const addState = connect( return { instance, player, - reclaiming, sendVboxAccept, sendVboxCombine, sendVboxDiscard, @@ -61,12 +59,6 @@ const addState = connect( }, function receiveDispatch(dispatch) { - function setReclaiming(v) { - dispatch(actions.setItemUnequip([])); - dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] })); - return dispatch(actions.setReclaiming(v)); - } - function setInfo(item) { return dispatch(actions.setInfo(item)); } @@ -78,7 +70,6 @@ const addState = connect( } return { - setReclaiming, setInfo, setVboxSelected, }; @@ -119,7 +110,6 @@ class Vbox extends preact.Component { shouldComponentUpdate(newProps) { // Single variable props if (newProps.itemUnequip !== this.props.itemUnequip) return true; - if (newProps.reclaiming !== this.props.reclaiming) return true; if (newProps.tutorial !== this.props.tutorial) return true; if (newProps.vboxSelected !== this.props.vboxSelected) return true; if (newProps.player !== this.props.player) return true; @@ -132,7 +122,6 @@ class Vbox extends preact.Component { // Changing state variables itemUnequip, player, - reclaiming, tutorial, vboxSelected, instance, @@ -147,7 +136,6 @@ class Vbox extends preact.Component { sendVboxReclaim, setVboxSelected, setInfo, - setReclaiming, } = args; if (!player) return false; @@ -418,7 +406,7 @@ class Vbox extends preact.Component { const tutorialDisabled = tutorial && tutorial < 8 && instance.time_control === 'Practice' && instance.rounds.length === 1; return ( -
+

e.target.scrollIntoView(true)} @@ -426,8 +414,7 @@ class Vbox extends preact.Component {

+
+
+ ); +} + +module.exports = combinerBtn; diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 4c09de46..99161682 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -1,14 +1,13 @@ const preact = require('preact'); const { connect } = require('preact-redux'); -const range = require('lodash/range'); const countBy = require('lodash/countBy'); -const without = require('lodash/without'); const forEach = require('lodash/forEach'); -const { removeTier } = require('../utils'); -const shapes = require('./shapes'); const actions = require('../actions'); -const buttons = require('./buttons'); + +const InventoryElement = require('./vbox.inventory'); +const StoreElement = require('./vbox.store'); +const CombinerElement = require('./vbox.combiner'); const addState = connect( function receiveState(state) { @@ -175,66 +174,6 @@ class Vbox extends preact.Component { return true; } - function availableBtn(v, group, index) { - if (!v) return ; - const selected = shopSelect.length && shopSelect.some(vs => vs[0] === group && vs[1] === index); - - const comboHighlight = vboxHighlight && vboxHighlight.includes(v) ? 'combo-border' : ''; - - function onClick(e) { - e.stopPropagation(); - if (!comboHighlight) setInfo(vbox.free[group][index]); - if (shopSelect.length && shopSelect.some(vs => vs[0] === group && vs[1] === index)) { - return setVboxSelected({ shopSelect: shopSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect }); - } - - if (!shopSelect.length && !stashSelect.length) return setVboxSelected({ shopSelect: [[group, index]], stashSelect }); - if (comboHighlight !== 'combo-border') { - return setVboxSelected({ shopSelect: [[group, index]], stashSelect: [] }); - } - return setVboxSelected({ shopSelect: [...shopSelect, [group, index]], stashSelect }); - } - - - const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`; - - const vboxObject = shapes[v] ? shapes[v]() : v; - const disabled = vbox.bits <= group; - return ( - - ); - } - - - function vboxElement() { - return ( -
e.stopPropagation()}> -
-
- {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} -
-
- {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} - {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))} -
-
-
- ); - } - function vboxHdr() { return (
@@ -250,7 +189,8 @@ class Vbox extends preact.Component { class='vbox-btn' onMouseOver={e => vboxHover(e, 'refill')} disabled={vbox.bits < 2 - || (tutorial && tutorial < 7 && instance.time_control === 'Practice' && instance.rounds.length === 1) + || (tutorial && tutorial < 7 + && instance.time_control === 'Practice' && instance.rounds.length === 1) } onClick={e => e.stopPropagation()} onMouseDown={() => sendVboxDiscard()}> @@ -261,143 +201,6 @@ class Vbox extends preact.Component {
); } - // - // INVENTORY - // - - function inventoryBtn(v, i) { - const inventoryHighlight = vboxSelecting || itemUnequip.length; - - if (!v && v !== 0) { - const emptyInvClick = () => { - if (vboxSelecting) return vboxBuySelected(); - return false; - }; - return ; - } - - const comboHighlight = vboxHighlight && vboxHighlight.includes(v) ? 'combo-border' : ''; - - function onClick(type) { - const combinerContainsIndex = stashSelect.indexOf(i) > -1; - // removing - if (combinerContainsIndex) { - if (type === 'click') { - return combinerChange(without(stashSelect, i)); - } - return true; - } - - if (!comboHighlight) { - setInfo(vbox.bound[i]); - return setVboxSelected({ shopSelect: [], stashSelect: [i] }); - } - - stashSelect.push(i); - // if (stashSelect.length === 3) setInfo(comboItem.item); - return combinerChange(stashSelect); - } - - const highlighted = stashSelect.indexOf(i) > -1; - const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : ''; - const classes = `${highlighted ? 'highlight' : border} ${comboHighlight}`; - - const invObject = shapes[v] ? shapes[v]() : v; - - return ( - - ); - } - - function combinerBtn() { - let text = ''; - let mouseEvent = false; - const combineLength = stashSelect.length + shopSelect.length; - if (vboxHighlight && vboxHighlight.length === 0) { - // The selected items can't be combined with additional items therefore valid combo - const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = shopSelect.map(j => vbox.free[j[0]][j[1]]); - const selectedItems = stashItems.concat(shopItems); - const combinerCount = countBy(selectedItems, co => co); - - const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { - if (!combo.components.includes(c)) return false; - const comboCount = countBy(combo.components, co => co); - if (combinerCount[c] > comboCount[c]) return false; - return true; - })); - let comboItem = comboItemObj ? comboItemObj.item : 'refine'; - setInfo(comboItem); - comboItem = comboItem.replace('Plus', '+'); - let bits = 0; - shopSelect.forEach(item => bits += item[0] + 1); - text = bits - ? `Buy ${comboItem} - ${bits}b` - : `Combine - ${comboItem}`; - if (vbox.bits >= bits) mouseEvent = sendVboxCombine; - } else if (stashSelect.length === 0 && shopSelect.length === 1) { - const item = shopSelect[0]; - text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`; - mouseEvent = vboxBuySelected; - } else { - for (let i = 0; i < 3; i++) { - if (combineLength > i) { - text += '■ '; - } else { - text += '▫ '; - } - } - } - return ( -
-
- -
-
- ); - } - - function inventoryElement() { - function inventoryClick(e) { - e.stopPropagation(); - if (itemUnequip.length) return sendItemUnequip(itemUnequip); - return true; - } - - return ( -
e.stopPropagation()} - onDragOver={ev => ev.preventDefault()} - onDrop={inventoryClick} - > -
- {range(0, 4).map(i => inventoryBtn(vbox.bound[i], i))} -
-
- ); - } function inventoryHdr() { return ( @@ -414,7 +217,8 @@ class Vbox extends preact.Component { const refund = shopSelect.length === 0 && stashSelect.length === 1 ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost : 0; - const tutorialDisabled = tutorial && tutorial < 8 && instance.time_control === 'Practice' && instance.rounds.length === 1; + const tutorialDisabled = tutorial && tutorial < 8 + && instance.time_control === 'Practice' && instance.rounds.length === 1; return (
@@ -434,17 +238,45 @@ class Vbox extends preact.Component { ); } - // // EVERYTHING - // return (
{vboxHdr()} - {vboxElement()} {inventoryHdr()} - {inventoryElement()} - {combinerBtn()} {refundBtn()} + + +
); } diff --git a/client/src/components/vbox.inventory.jsx b/client/src/components/vbox.inventory.jsx new file mode 100644 index 00000000..f4f80e06 --- /dev/null +++ b/client/src/components/vbox.inventory.jsx @@ -0,0 +1,108 @@ +const preact = require('preact'); +const range = require('lodash/range'); +const without = require('lodash/without'); + +const shapes = require('./shapes'); +const buttons = require('./buttons'); +const { removeTier } = require('../utils'); + +function inventoryElement(props) { + const { + combinerChange, + itemUnequip, + vbox, + vboxBuySelected, + vboxHighlight, + vboxHover, + vboxSelecting, + stashSelect, + + sendItemUnequip, + setInfo, + setVboxSelected, + + } = props; + function inventoryClick(e) { + e.stopPropagation(); + if (itemUnequip.length) return sendItemUnequip(itemUnequip); + return true; + } + + function inventoryBtn(v, i) { + const inventoryHighlight = vboxSelecting || itemUnequip.length; + + if (!v && v !== 0) { + const emptyInvClick = () => { + if (vboxSelecting) return vboxBuySelected(); + return false; + }; + return ; + } + + const comboHighlight = vboxHighlight && vboxHighlight.includes(v) ? 'combo-border' : ''; + + function onClick(type) { + const combinerContainsIndex = stashSelect.indexOf(i) > -1; + // removing + if (combinerContainsIndex) { + if (type === 'click') { + return combinerChange(without(stashSelect, i)); + } + return true; + } + + if (!comboHighlight) { + setInfo(vbox.bound[i]); + return setVboxSelected({ shopSelect: [], stashSelect: [i] }); + } + + stashSelect.push(i); + // if (stashSelect.length === 3) setInfo(comboItem.item); + return combinerChange(stashSelect); + } + + const highlighted = stashSelect.indexOf(i) > -1; + const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : ''; + const classes = `${highlighted ? 'highlight' : border} ${comboHighlight}`; + + const invObject = shapes[v] ? shapes[v]() : v; + + return ( + + ); + } + + return ( +
e.stopPropagation()} + onDragOver={ev => ev.preventDefault()} + onDrop={inventoryClick} + > +
+ {range(0, 4).map(i => inventoryBtn(vbox.bound[i], i))} +
+
+ ); +} + +module.exports = inventoryElement; diff --git a/client/src/components/vbox.store.jsx b/client/src/components/vbox.store.jsx new file mode 100644 index 00000000..410cf491 --- /dev/null +++ b/client/src/components/vbox.store.jsx @@ -0,0 +1,81 @@ +const preact = require('preact'); +const range = require('lodash/range'); + +const shapes = require('./shapes'); + + +function storeElement(props) { + const { + clearVboxSelected, + setInfo, + setVboxSelected, + shopSelect, + stashSelect, + vbox, + vboxHighlight, + vboxHover, + } = props; + + function availableBtn(v, group, index) { + if (!v) return ; + const selected = shopSelect.length && shopSelect.some(vs => vs[0] === group && vs[1] === index); + + const comboHighlight = vboxHighlight && vboxHighlight.includes(v) ? 'combo-border' : ''; + + function onClick(e) { + e.stopPropagation(); + if (!comboHighlight) setInfo(vbox.free[group][index]); + if (shopSelect.length && shopSelect.some(vs => vs[0] === group && vs[1] === index)) { + return setVboxSelected( + { shopSelect: shopSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect } + ); + } + + if (!shopSelect.length && !stashSelect.length) { + return setVboxSelected({ shopSelect: [[group, index]], stashSelect }); + } + if (comboHighlight !== 'combo-border') { + return setVboxSelected({ shopSelect: [[group, index]], stashSelect: [] }); + } + return setVboxSelected({ shopSelect: [...shopSelect, [group, index]], stashSelect }); + } + + + const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`; + + const vboxObject = shapes[v] ? shapes[v]() : v; + const disabled = vbox.bits <= group; + return ( + + ); + } + + return ( +
e.stopPropagation()}> +
+
+ {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} +
+
+ {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} + {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))} +
+
+
+ ); +} + +module.exports = storeElement; From 54743c67babcbf0bacbac8b20719b88728d8aa50 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 21 Nov 2019 15:57:25 +1000 Subject: [PATCH 13/97] styling --- client/assets/styles/vbox.less | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 857ce142..e24aba7e 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -9,7 +9,6 @@ "stash-hdr shop" "stash stash" "refund combiner"; - border-top: 0.1em solid @gray-exists; margin-bottom: 1em; line-height: 0; @@ -24,12 +23,14 @@ grid-area: shop; border-bottom: 0.1em solid @gray-exists; border-right: 0.1em solid @gray-exists; + border-top: 0.1em solid @gray-exists; } .shop-hdr { grid-area: shop-hdr; border-bottom: 0.1em solid @gray-exists; border-left: 0.1em solid @gray-exists; + border-top: 0.1em solid @gray-exists; text-align: center; button { margin-top: 0.5em; @@ -37,6 +38,10 @@ height: 4em; letter-spacing: 0.1em; background-color: #421010; + &:hover { + background-color: @red; + + } } } @@ -55,9 +60,9 @@ button { height: 3em; letter-spacing: 0.1em; - background-color: #342100; + background-color: #996100; &[disabled] { - color: #342100; + color: #996100; }; } } @@ -86,7 +91,7 @@ line-height: 1.4; height: 3em; letter-spacing: 0.1em; - background-color: #342100; + background-color: #996100; } border-left: 0.1em solid @gray-exists; border-bottom: 0.1em solid @gray-exists; From 05112fbf7e02ba01a802dcd58146b79f878a44ca Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 21 Nov 2019 16:31:19 +1000 Subject: [PATCH 14/97] remove instance mobile style file --- client/assets/styles/instance.mobile.less | 29 ----------------------- client/assets/styles/styles.less | 1 - client/assets/styles/styles.mobile.less | 9 ++++--- 3 files changed, 6 insertions(+), 33 deletions(-) delete mode 100644 client/assets/styles/instance.mobile.less diff --git a/client/assets/styles/instance.mobile.less b/client/assets/styles/instance.mobile.less deleted file mode 100644 index 53585439..00000000 --- a/client/assets/styles/instance.mobile.less +++ /dev/null @@ -1,29 +0,0 @@ -// tablet / ipad -@media (max-width: 1100px) { - .instance { - grid-template-columns: 1fr; - grid-template-rows: min-content 1fr; - grid-template-areas: - "vbox" - "constructs"; - - .info { - display: none; - } - } -} - -@media (max-width: 800px) { - .instance { - font-size: 5.5pt; - grid-template-columns: 1fr; - grid-template-rows: min-content 1fr; - grid-template-areas: - "vbox" - "constructs"; - - .info { - display: none; - } - } -} \ No newline at end of file diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index abdb979b..de7f9dea 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -9,7 +9,6 @@ @import 'game.less'; @import 'player.less'; @import 'styles.mobile.less'; -@import 'instance.mobile.less'; html body { margin: 0; diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index b97257c1..80ba1518 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -1,20 +1,23 @@ -@media (max-width: 1000px) { +@media (max-width: 800px) { body { overflow-y: initial; } #mnml { - font-size: 8pt; + font-size: 6pt; padding: 0.25em; .instance { + font-size: 6pt; grid-template-columns: 1fr; grid-template-rows: min-content 1fr; grid-template-areas: "vbox" "constructs"; - + .info { + display: none; + } svg { stroke-width: 1.25em; } From 8e83d0aa0b408ef1241314be482b0fce10efae04 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 21 Nov 2019 16:55:04 +1000 Subject: [PATCH 15/97] instance cleanup --- client/assets/styles/instance.less | 265 +++++++----------------- client/assets/styles/styles.mobile.less | 5 +- 2 files changed, 76 insertions(+), 194 deletions(-) diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 04e4f1c6..33142408 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -1,3 +1,7 @@ +.instance.lobby { + align-content: center; +} + .instance { overflow: hidden; display: grid; @@ -7,122 +11,89 @@ grid-template-areas: "vbox info" "constructs constructs"; -} -@media (max-width: 1920px) { - .instance .info table td svg { - // height: 50%; - stroke-width: 8px; - } + .info { + h2 { + text-transform: uppercase; + } + svg { + display: inline; + height: 1em; + } + figure { + display: inline; + height: 0.5em; + svg { + margin-right: 0.5em; + } + } + figcaption { + font-size: 1em; + display: inline-block; + vertical-align: middle; + } - .instance svg { - height: 1.5em; - } -} + margin: 0 0 0 1em; + grid-area: info; -.instance .top { - grid-area: top; -} - -.instance.lobby { - align-content: center; -} - -.scoreboard { - flex: 1; -} - -.instance .info { - margin: 0 0 0 1em; - grid-area: info; - - display: grid; - grid-template-rows: 13em min-content; - grid-template-areas: - "item" - "combos"; - - .combos { display: grid; - grid-template-columns: repeat(6, 1fr); - align-content: center; + grid-template-rows: 13em min-content; + grid-template-areas: + "item" + "combos"; - .table-button { + .combos { display: grid; - text-align: center; + grid-template-columns: repeat(6, 1fr); align-content: center; - border-bottom: 2px solid #222; - grid-template-areas: - "item" - "ingr"; - - cursor: pointer; - &:hover { - color: whitesmoke; - background-color: @gray; - } - - .item { - border-top: 2px solid #222; + .table-button { + display: grid; + text-align: center; + align-content: center; border-bottom: 2px solid #222; - flex: 1; - grid-area: item; - font-weight: bold; - } - div { - border-right: 2px solid #222; - svg { - vertical-align: middle; + grid-template-areas: + "item" + "ingr"; + + cursor: pointer; + &:hover { + color: whitesmoke; + background-color: @gray; + } + + .item { + border-top: 2px solid #222; + border-bottom: 2px solid #222; + flex: 1; + grid-area: item; + font-weight: bold; } - } - &:first-child { div { - border-left: 2px solid #222; + border-right: 2px solid #222; + svg { + vertical-align: middle; + } + } + + &:first-child { + div { + border-left: 2px solid #222; + } } } } } -} -.instance .info h2 { - text-transform: uppercase; -} - -.instance .info svg { - display: inline; - height: 1em; -} - -.instance .info figure { - display: inline; - height: 0.5em; - - svg { - margin-right: 0.5em; + .constructs { + grid-area: constructs; } } -.instance .info figcaption { - font-size: 1em; - display: inline-block; - vertical-align: middle; -} -.instance .constructs { - grid-area: constructs; -} - -.instance .equip { - grid-area: equip; -} - -.instance .equip .skills { - border-right-width: 0; -} @keyframes action { 0% { @@ -135,10 +106,6 @@ /* CONSTRUCT LIST */ -.construct-list { - grid-area: constructs; - display: flex; -} .instance-construct { flex: 1; @@ -154,14 +121,16 @@ /*padding: 0.5em;*/ border: 2px solid #222; border-left-width: 0; -} - -.instance-construct:first-child { - margin-left: 0; - border-left-width: 1px; + &:first-child { + margin-left: 0; + border-left-width: 1px; + } } .construct-list { + grid-area: constructs; + display: flex; + button { &.highlight { color: black; @@ -264,95 +233,10 @@ } } -/* Equipment */ -.equip { - display: flex; - margin: 1.5em 0; - text-align: center; -} - -.equip h3 { - margin-bottom: 0.5em; - text-transform: uppercase; - font-weight: bold; - letter-spacing: 0.1em; -} - -.equip .specs { - flex: 1; - border: 2px solid #222; -} - -.equip .items { - display: flex; - flex: 1 0 100%; - justify-content: space-around; -} - .label { flex: 1 0 100%; } -// .equipping { -// position: relative; -// } - -// .equipping::before { -// content: ''; -// position: absolute; -// top: 2px; -// left: 50%; -// width: 100%; -// height: 2px; -// transform-origin: center; -// background-color: whitesmoke; -// animation: equipping-skill 2s infinite ease-out alternate; -// opacity: 0; -// } - -// .equipping::after { -// content: ''; -// position: absolute; -// bottom: 2px; -// left: 50%; -// width: 100%; -// height: 2px; -// transform-origin: center; -// background-color: whitesmoke; -// animation: equipping-skill 2s infinite ease-out alternate; -// opacity: 0; -// animation-delay: 0.75s -// } - -// @keyframes equipping-skill { -// from { -// transform: translate(-50%, 0) scaleX(0); -// } - -// to { -// transform: translate(-50%, 0) scaleX(0.75); -// opacity: 1; -// } -// } - -// .equip-spec { -// position: relative; -// stroke: #333; -// } - -// .equip-spec::after { -// content: ''; -// position: absolute; -// bottom: 2px; -// left: 50%; -// width: 100%; -// height: 2px; -// transform-origin: center; -// background-color: whitesmoke; -// animation: equipping-skill 2s infinite ease-out alternate; -// opacity: 0; -// } - .equipping, .receiving { animation: eq 0.75s cubic-bezier(0, 0, 1, 1) 0s infinite alternate; } @@ -484,9 +368,4 @@ to { color: @yellow; } -} - -/* Mobile Nav*/ -.instance-nav { display: none; } - -.vbox-arrow-mobile { display: none } +} \ No newline at end of file diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index 80ba1518..e20f2d4f 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -8,7 +8,7 @@ padding: 0.25em; .instance { - font-size: 6pt; + font-size: 7.5pt; grid-template-columns: 1fr; grid-template-rows: min-content 1fr; @@ -21,6 +21,9 @@ svg { stroke-width: 1.25em; } + .avatar { + display: none; + } } .game { From a3376fb8d23278036229757d6de555fe310584ee Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 21 Nov 2019 18:05:46 +1000 Subject: [PATCH 16/97] fix mobile game phase --- client/assets/styles/styles.mobile.less | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index e20f2d4f..ff8adf1a 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -27,6 +27,12 @@ } .game { + .stats { + font-size: 8pt; + svg { + stroke-width: 1.5em; + } + } .team, #targeting, .resolving-skill { width: calc(90% - 3em); } From 4d3a837d477809840b432a7ed019e44d3494d779 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 00:17:50 +1000 Subject: [PATCH 17/97] misc styling --- client/assets/styles/controls.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/assets/styles/controls.less b/client/assets/styles/controls.less index 0bdb4b59..9fb1cd13 100644 --- a/client/assets/styles/controls.less +++ b/client/assets/styles/controls.less @@ -60,7 +60,7 @@ aside { width: 0.25em; max-width: 0.25em; - margin: 0 1em 0 0; + margin: 0 0.5em 0 0; border: none; } From 0722b194b04e2302b50a82fb20045089bc0937f0 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 00:18:17 +1000 Subject: [PATCH 18/97] misc styling (actual commit) --- client/assets/styles/game.less | 13 +++--------- client/assets/styles/skeleton.css | 1 - client/assets/styles/styles.less | 3 ++- client/assets/styles/styles.mobile.less | 18 ++++++++++------ client/assets/styles/vbox.less | 26 ------------------------ client/src/components/vbox.inventory.jsx | 1 + 6 files changed, 18 insertions(+), 44 deletions(-) diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index 4ddacc63..92ec48ae 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -150,15 +150,10 @@ width: 100%; height: 2em; margin-right: 1em; - span { - background-color: black; - } + background-color: black; } button.active { - background: #2c2c2c; - span { - background-color: #2c2c2c; - } + background-color: #2c2c2c; } } @@ -266,9 +261,7 @@ padding-right: 1em; text-align: center; z-index: 2; - span { - background-color: black; - } + background-color: black; svg { display: inline; height: 1em; diff --git a/client/assets/styles/skeleton.css b/client/assets/styles/skeleton.css index 13bb3549..037e1747 100644 --- a/client/assets/styles/skeleton.css +++ b/client/assets/styles/skeleton.css @@ -176,7 +176,6 @@ input[type="button"] { /*padding: 0 2em;*/ color: #555; text-align: center; - font-size: 11px; font-weight: 600; line-height: 38px; letter-spacing: .1rem; diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index de7f9dea..202674b2 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -22,6 +22,7 @@ html body { -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; + -webkit-tap-highlight-color: transparent; overflow-x: hidden; overflow-y: hidden; @@ -128,7 +129,7 @@ button, input { border-color: @gray-exists; letter-spacing: 0.25em; box-sizing: border-box; - font-size: 100%; + font-size: 1em; flex: 1; border-radius: 0.5em; line-height: 2em; diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index ff8adf1a..a8c8ac96 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -1,10 +1,11 @@ @media (max-width: 800px) { body { overflow-y: initial; + } #mnml { - font-size: 6pt; + font-size: 8pt; padding: 0.25em; .instance { @@ -27,8 +28,8 @@ } .game { + font-size: 7.5pt; .stats { - font-size: 8pt; svg { stroke-width: 1.5em; } @@ -57,17 +58,22 @@ } .skills { - button[disabled] { - display: none; + display: grid; + grid-template-rows: 1fr; + grid-template-columns: 1fr 1fr 1fr; + button { + font-size: 0.9em; + letter-spacing: 0.05em; } + + } .effects { - font-size: 1em; + font-size: 1.1em; } .skill-description { - font-size: 0.8em; svg { height: 1em; } diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index e24aba7e..115decff 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -190,30 +190,4 @@ line-height: initial; } } -} - -.vbox-combiner { - grid-area: combiner; - display: flex; - flex-flow: column; - justify-content: flex-end; -} - -.vbox-combiner button { - flex: 0; -} - - -.vbox-hdr { - display: flex; -} - -.vbox-hdr h3 { - flex: 1; -} - -.vbox-hdr .bits { - font-size: 2em; - line-height: 1em; - animation: bits 1s ease-out; } \ No newline at end of file diff --git a/client/src/components/vbox.inventory.jsx b/client/src/components/vbox.inventory.jsx index f4f80e06..8aa22a14 100644 --- a/client/src/components/vbox.inventory.jsx +++ b/client/src/components/vbox.inventory.jsx @@ -25,6 +25,7 @@ function inventoryElement(props) { function inventoryClick(e) { e.stopPropagation(); if (itemUnequip.length) return sendItemUnequip(itemUnequip); + if (vboxSelecting) return vboxBuySelected(); return true; } From 28585487c6f43e63412a18a609c1b564cce6261a Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 00:23:53 +1000 Subject: [PATCH 19/97] game phase cooldown new line, mobile styling --- client/src/components/skill.btn.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/components/skill.btn.jsx b/client/src/components/skill.btn.jsx index 6f96e410..d7be22be 100644 --- a/client/src/components/skill.btn.jsx +++ b/client/src/components/skill.btn.jsx @@ -69,7 +69,7 @@ function Skill(props) { // return false; // } const cdText = construct.skills[i].cd > 0 - ? `- ${s.cd}T` + ? `${s.cd}T` : ''; const highlight = activeSkill @@ -91,7 +91,7 @@ function Skill(props) { onMouseOut={e => hoverInfo(e, null)} type="submit" onClick={onClick}> - {s.skill} {cdText} + {s.skill}
{cdText}
); } From c650b74ec918b1ace1080ad78c3898bddc6cb83f Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 00:39:22 +1000 Subject: [PATCH 20/97] skill button size --- client/assets/styles/game.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index 92ec48ae..9b19db2c 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -148,7 +148,8 @@ z-index: 2; button { width: 100%; - height: 2em; + height: 3em; + line-height: 1; margin-right: 1em; background-color: black; } From 9cd656a99f23786e9d7a9ab200c0f3ca36a13ea0 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 00:39:35 +1000 Subject: [PATCH 21/97] skill button size --- client/assets/styles/styles.mobile.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index a8c8ac96..6e1b8cba 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -62,8 +62,8 @@ grid-template-rows: 1fr; grid-template-columns: 1fr 1fr 1fr; button { - font-size: 0.9em; - letter-spacing: 0.05em; + font-size: 1em; + letter-spacing: 0.1em; } From 843c1c6bbe8551c7096c966b33afdcf79930341f Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 01:17:45 +1000 Subject: [PATCH 22/97] combo preview wip --- client/assets/styles/instance.less | 79 +++++++++++++----------- client/src/components/info.component.jsx | 5 +- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 33142408..cb7e062c 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -32,55 +32,64 @@ display: inline-block; vertical-align: middle; } - - margin: 0 0 0 1em; + margin-left: 1em; grid-area: info; - display: grid; - grid-template-rows: 13em min-content; + grid-template-rows: 1fr; + grid-template-columns: 20em 1fr; grid-template-areas: - "item" - "combos"; + "combos item"; .combos { + + margin-right: 1em; display: grid; - grid-template-columns: repeat(6, 1fr); - align-content: center; + grid-area: combos; + grid-template-rows: min-content min-content; + grid-template-areas: + "comboHeader" + "comboList"; + .combo-header { + font-size: 1.25em; + } - .table-button { + .combo-list { display: grid; - text-align: center; - align-content: center; - border-bottom: 2px solid #222; + grid-template-rows: min-content min-content min-content; + grid-template-columns: 1fr 1fr; + grid-gap: 1em; + .table-button { + display: grid; + text-align: center; + align-content: center; - grid-template-areas: - "item" - "ingr"; + grid-template-areas: + "item" + "ingr"; - cursor: pointer; - &:hover { - color: whitesmoke; - background-color: @gray; - } - - .item { - border-top: 2px solid #222; - border-bottom: 2px solid #222; - flex: 1; - grid-area: item; - font-weight: bold; - } - - div { - border-right: 2px solid #222; - svg { - vertical-align: middle; + cursor: pointer; + &:hover { + color: whitesmoke; + background-color: @gray; + } + + .item { + border-top: 2px solid #222; + border-bottom: 2px solid #222; + flex: 1; + grid-area: item; + font-weight: bold; } - } - &:first-child { div { border-left: 2px solid #222; + border-right: 2px solid #222; + svg { + vertical-align: middle; + } + &:last-child { + border-bottom: 2px solid #222; + } } } } diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index 6045c049..c711429a 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -167,7 +167,10 @@ class InfoComponent extends preact.Component { }); return (
- {comboTable} +
COMBOS
+
+ {comboTable} +
); }; From b5ade7f012526574d4ba2f3b203686a5a2e3d713 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 09:56:29 +1000 Subject: [PATCH 23/97] combo preview styling --- client/assets/styles/instance.less | 26 +++++++++++++++-------- client/assets/styles/styles.mobile.less | 10 +++------ client/src/components/info.component.jsx | 20 +++++++++-------- client/src/components/info.thresholds.jsx | 11 ++++++++-- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index cb7e062c..d9bf96c8 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -35,34 +35,36 @@ margin-left: 1em; grid-area: info; display: grid; - grid-template-rows: 1fr; - grid-template-columns: 20em 1fr; + grid-template-columns: 1fr min-content; grid-template-areas: - "combos item"; + "item combos"; + .info-item { + grid-area: item; + } .combos { - - margin-right: 1em; display: grid; grid-area: combos; + margin-left: 0.5em; grid-template-rows: min-content min-content; grid-template-areas: "comboHeader" "comboList"; .combo-header { - font-size: 1.25em; + text-align: center; } .combo-list { display: grid; grid-template-rows: min-content min-content min-content; - grid-template-columns: 1fr 1fr; - grid-gap: 1em; + grid-template-columns: min-content min-content; + grid-gap: 0.5em; + margin-top: 0.5em; + .table-button { display: grid; text-align: center; align-content: center; - grid-template-areas: "item" "ingr"; @@ -79,11 +81,17 @@ flex: 1; grid-area: item; font-weight: bold; + div { + width: 5em; + } } + div { border-left: 2px solid #222; border-right: 2px solid #222; + height: 1.75em; + width: 7.5em; svg { vertical-align: middle; } diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index 6e1b8cba..2eba09ac 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -10,14 +10,10 @@ .instance { font-size: 7.5pt; - grid-template-columns: 1fr; - grid-template-rows: min-content 1fr; - - grid-template-areas: - "vbox" - "constructs"; .info { - display: none; + .combos { + display: none; + } } svg { stroke-width: 1.25em; diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index c711429a..f60b658e 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -132,7 +132,7 @@ class InfoComponent extends preact.Component { const Combos = () => { if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; - const generalNotes = ( +/* const generalNotes = (

General

@@ -140,12 +140,12 @@ class InfoComponent extends preact.Component { Click the READY button to start the GAME PHASE.

- ); - if (!player) return generalNotes; - if (!info) return generalNotes; + );*/ + if (!player) return false; + if (!info) return false; const vboxCombos = itemInfo.combos.filter(c => c.components.includes(info)); - if (vboxCombos.length > 6 || vboxCombos.length === 0) return generalNotes; + if (vboxCombos.length > 6 || vboxCombos.length === 0) return false; const comboTable = vboxCombos.map((c, i) => { const mouseOver = e => { @@ -157,7 +157,7 @@ class InfoComponent extends preact.Component {
{convertItem(c.components[2])}
] : c.components.map((u, j) =>
{convertItem(u)}
); return ( -
setInfo(c.item)}> +
{convertItem(c.item)}
@@ -165,12 +165,14 @@ class InfoComponent extends preact.Component {
); }); + const comboList = comboTable.length > 0 ?
{comboTable}
: false; return (
-
COMBOS
-
- {comboTable} +
+

COMBOS

+ Combine colours and items.
+ {comboList}
); }; diff --git a/client/src/components/info.thresholds.jsx b/client/src/components/info.thresholds.jsx index 7136a855..930882bd 100644 --- a/client/src/components/info.thresholds.jsx +++ b/client/src/components/info.thresholds.jsx @@ -87,9 +87,16 @@ function specThresholds(player, fullInfo, info) { ); }); return ( -
- {thresholds} +
+
+ {thresholds[0]} + {thresholds[1]} +
+
+ {thresholds[2]} +
+ ); } From 945f0828c1e52da952813838158d89d90e605ed9 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 09:59:35 +1000 Subject: [PATCH 24/97] combo mouseover event --- client/src/components/info.component.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index f60b658e..eec7b710 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -178,8 +178,10 @@ class InfoComponent extends preact.Component { }; return ( -
this.setState({ comboItem: null })}> - +
+
this.setState({ comboItem: null })}> + +
); From a353dcca957baa9b5e6bb8a967bdec6898723ba6 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 10:06:39 +1000 Subject: [PATCH 25/97] inventory -> stash --- client/src/components/demo.jsx | 8 ++++---- client/src/components/vbox.component.jsx | 10 +++++----- .../{vbox.inventory.jsx => vbox.stash.jsx} | 20 +++++++++---------- client/src/constants.jsx | 6 +++--- client/src/tutorial.utils.jsx | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) rename client/src/components/{vbox.inventory.jsx => vbox.stash.jsx} (85%) diff --git a/client/src/components/demo.jsx b/client/src/components/demo.jsx index 494015ef..e6bee9eb 100644 --- a/client/src/components/demo.jsx +++ b/client/src/components/demo.jsx @@ -46,7 +46,7 @@ function Demo(args) { const { combiner, items, equipping, equipped, players, combo } = demo; const vboxDemo = () => { - function inventoryBtn(i, j) { + function stashBtn(i, j) { if (!i) return ; const highlighted = combiner.indexOf(j) > -1; const classes = `${highlighted ? 'highlight' : ''}`; @@ -82,7 +82,7 @@ function Demo(args) { ); } - function inventoryElement() { + function stashElement() { return (
@@ -96,7 +96,7 @@ function Demo(args) {
 
- {items.map((i, j) => inventoryBtn(i, j))} + {items.map((i, j) => stashBtn(i, j))}
{combinerBtn()}
@@ -106,7 +106,7 @@ function Demo(args) { return (
- {inventoryElement()} + {stashElement()}
); }; diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 99161682..639b6e11 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -5,7 +5,7 @@ const forEach = require('lodash/forEach'); const actions = require('../actions'); -const InventoryElement = require('./vbox.inventory'); +const StashElement = require('./vbox.stash'); const StoreElement = require('./vbox.store'); const CombinerElement = require('./vbox.combiner'); @@ -202,12 +202,12 @@ class Vbox extends preact.Component { ); } - function inventoryHdr() { + function stashHdr() { return (

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'inventory')}> STASH + onMouseOver={e => vboxHover(e, 'stash')}> STASH

@@ -242,7 +242,7 @@ class Vbox extends preact.Component { return (
{vboxHdr()} - {inventoryHdr()} + {stashHdr()} {refundBtn()} - { @@ -40,8 +40,8 @@ function inventoryElement(props) { return ; + disabled={!stashHighlight} + class={stashHighlight ? 'receiving' : 'empty'} > ; } const comboHighlight = vboxHighlight && vboxHighlight.includes(v) ? 'combo-border' : ''; @@ -94,16 +94,16 @@ function inventoryElement(props) { return (
e.stopPropagation()} onDragOver={ev => ev.preventDefault()} - onDrop={inventoryClick} + onDrop={stashClick} >
- {range(0, 4).map(i => inventoryBtn(vbox.bound[i], i))} + {range(0, 4).map(i => stashBtn(vbox.bound[i], i))}
); } -module.exports = inventoryElement; +module.exports = stashElement; diff --git a/client/src/constants.jsx b/client/src/constants.jsx index 5a7a24a3..c0fb5541 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -29,8 +29,8 @@ module.exports = { description:

ITEMS that are available to buy.
The VBOX is refilled every round.
Click REFILL at the bottom to purchase a refill.

, }, - inventory: { - item: 'INVENTORY', + stash: { + item: 'STASH', description:

Holds ITEMS
ITEMS carry over each round.

, }, bits: { @@ -60,7 +60,7 @@ module.exports = { }, constructSkills: { item: 'SKILLS', - description: 'Skills are used by constructs in the game phase.\nBase skills can be bought from the VBOX.\nEquip skills from the inventory. Double-click to unequip.', + description: 'Skills are used by constructs in the game phase.\nBase skills can be bought from the VBOX.\nEquip skills from the stash. Double-click to unequip.', }, constructSpecs: { item: 'SPECS', diff --git a/client/src/tutorial.utils.jsx b/client/src/tutorial.utils.jsx index 3534cc36..23436be6 100644 --- a/client/src/tutorial.utils.jsx +++ b/client/src/tutorial.utils.jsx @@ -138,7 +138,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) {

Tutorial

The first construct on your team is {constructOne}.

Skill items can be equipped to your constructs to be used in the combat phase.

-

Click the newly combined skill item in the top right of the inventory.
+

Click the newly combined skill from the stash.
Once selected click the construct SKILL slot to equip the skill.

); @@ -161,7 +161,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) {

Tutorial

Equipping specialisation items will increase the stats of your constructs.

These can also be combined with colours for further specialisation.

-

Click the specialisation item in the top right of the inventory.
+

Click the specialisation item from the stash.
Once selected click the construct SPEC slot to equip the specialisation.

); From fba4627bf149ecfe65a05e2d8ee2658674c7c7fd Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 10:14:36 +1000 Subject: [PATCH 26/97] fixed combo list width --- client/assets/styles/instance.less | 1 + 1 file changed, 1 insertion(+) diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index d9bf96c8..26bee42c 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -60,6 +60,7 @@ grid-template-columns: min-content min-content; grid-gap: 0.5em; margin-top: 0.5em; + width: 15.5em; .table-button { display: grid; From 69be938e76e82f2cd22b078a086aeb141d95678d Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 10:34:50 +1000 Subject: [PATCH 27/97] shop / vbox -> store --- client/assets/styles/vbox.less | 12 +++---- client/src/components/instance.component.jsx | 2 +- client/src/components/instance.constructs.jsx | 10 +++--- client/src/components/vbox.combiner.jsx | 12 +++---- client/src/components/vbox.component.jsx | 36 +++++++++---------- client/src/components/vbox.stash.jsx | 2 +- client/src/components/vbox.store.jsx | 18 +++++----- client/src/constants.jsx | 14 +++----- client/src/events.jsx | 2 +- client/src/keyboard.jsx | 2 +- client/src/reducers.jsx | 2 +- 11 files changed, 54 insertions(+), 58 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 115decff..411dae51 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -5,8 +5,8 @@ grid-template-rows: 9.5em 2.5em 4.5em min-content; grid-template-columns: 8em 24em; grid-template-areas: - "shop-hdr shop" - "stash-hdr shop" + "store-hdr store" + "stash-hdr store" "stash stash" "refund combiner"; margin-bottom: 1em; @@ -19,15 +19,15 @@ margin-right: 0.5em; } - .shop { - grid-area: shop; + .store { + grid-area: store; border-bottom: 0.1em solid @gray-exists; border-right: 0.1em solid @gray-exists; border-top: 0.1em solid @gray-exists; } - .shop-hdr { - grid-area: shop-hdr; + .store-hdr { + grid-area: store-hdr; border-bottom: 0.1em solid @gray-exists; border-left: 0.1em solid @gray-exists; border-top: 0.1em solid @gray-exists; diff --git a/client/src/components/instance.component.jsx b/client/src/components/instance.component.jsx index 4955469e..a8abcac0 100644 --- a/client/src/components/instance.component.jsx +++ b/client/src/components/instance.component.jsx @@ -28,7 +28,7 @@ const addState = connect( function clearItems() { dispatch(actions.setItemUnequip([])); - dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] })); + dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })); return true; } diff --git a/client/src/components/instance.constructs.jsx b/client/src/components/instance.constructs.jsx index e29a7ad7..88589efe 100644 --- a/client/src/components/instance.constructs.jsx +++ b/client/src/components/instance.constructs.jsx @@ -25,7 +25,7 @@ const addState = connect( } = state; function sendVboxAcceptEquip(constructId) { - return ws.sendVboxAcceptEquip(instance.id, vboxSelected.shopSelect[0][0], vboxSelected.shopSelect[0][1], constructId); + return ws.sendVboxAcceptEquip(instance.id, vboxSelected.storeSelect[0][0], vboxSelected.storeSelect[0][1], constructId); } function sendVboxApply(constructId, i) { @@ -60,7 +60,7 @@ const addState = connect( } function setItemUnequip(v) { - dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] })); + dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })); return dispatch(actions.setItemUnequip(v)); } @@ -91,7 +91,7 @@ function Construct(props) { const { vbox } = player; - const itemEquip = vboxSelected.shopSelect.length === 0 && vboxSelected.stashSelect.length === 1 + const itemEquip = vboxSelected.storeSelect.length === 0 && vboxSelected.stashSelect.length === 1 ? vboxSelected.stashSelect[0] : -1; @@ -106,7 +106,7 @@ function Construct(props) { e.preventDefault(); if (duplicateSkill || tutorialDisableEquip) return true; if (itemEquip !== -1) return sendVboxApply(construct.id, itemEquip); - if (vboxSelected.shopSelect.length === 1) return sendVboxAcceptEquip(construct.id); + if (vboxSelected.storeSelect.length === 1) return sendVboxAcceptEquip(construct.id); if (itemUnequip.length && itemUnequip[0] !== construct.id) return sendVboxUnequipApply(construct.id); setItemUnequip([]); return true; @@ -114,7 +114,7 @@ function Construct(props) { function hoverInfo(e, info) { e.stopPropagation(); if (!info) return false; - if (vboxSelected.shopSelect.length || vboxSelected.stashSelect.length) return false; + if (vboxSelected.storeSelect.length || vboxSelected.stashSelect.length) return false; return setInfo(info); } diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index dddfce06..4b8ab14e 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -7,18 +7,18 @@ function combinerBtn(props) { sendVboxCombine, setInfo, stashSelect, - shopSelect, + storeSelect, vbox, vboxBuySelected, vboxHighlight, } = props; let text = ''; let mouseEvent = false; - const combineLength = stashSelect.length + shopSelect.length; + const combineLength = stashSelect.length + storeSelect.length; if (vboxHighlight && vboxHighlight.length === 0) { // The selected items can't be combined with additional items therefore valid combo const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = shopSelect.map(j => vbox.free[j[0]][j[1]]); + const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); const selectedItems = stashItems.concat(shopItems); const combinerCount = countBy(selectedItems, co => co); @@ -32,13 +32,13 @@ function combinerBtn(props) { setInfo(comboItem); comboItem = comboItem.replace('Plus', '+'); let bits = 0; - shopSelect.forEach(item => bits += item[0] + 1); + storeSelect.forEach(item => bits += item[0] + 1); text = bits ? `Buy ${comboItem} - ${bits}b` : `Combine - ${comboItem}`; if (vbox.bits >= bits) mouseEvent = sendVboxCombine; - } else if (stashSelect.length === 0 && shopSelect.length === 1) { - const item = shopSelect[0]; + } else if (stashSelect.length === 0 && storeSelect.length === 1) { + const item = storeSelect[0]; text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`; mouseEvent = vboxBuySelected; } else { diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 639b6e11..819c43b5 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -31,7 +31,7 @@ const addState = connect( } function sendVboxCombine() { - return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.shopSelect); + return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); } function sendVboxReclaim(i) { @@ -75,13 +75,13 @@ const addState = connect( } ); -function validVboxSelect(vbox, itemInfo, shopSelect, stashSelect) { - if (shopSelect.length === 0 && stashSelect.length === 0) return false; +function validVboxSelect(vbox, itemInfo, storeSelect, stashSelect) { + if (storeSelect.length === 0 && stashSelect.length === 0) return false; const validSelects = []; const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = shopSelect.map(j => vbox.free[j[0]][j[1]]); + const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); const selectedItems = stashItems.concat(shopItems); const itemCount = countBy(selectedItems, co => co); @@ -139,21 +139,21 @@ class Vbox extends preact.Component { if (!player) return false; const { vbox } = player; - const { shopSelect, stashSelect } = vboxSelected; - const vboxSelecting = shopSelect.length === 1 && stashSelect.length === 0; + const { storeSelect, stashSelect } = vboxSelected; + const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0; function combinerChange(newStashSelect) { - return setVboxSelected({ shopSelect, stashSelect: newStashSelect }); + return setVboxSelected({ storeSelect, stashSelect: newStashSelect }); } - const vboxHighlight = validVboxSelect(vbox, itemInfo, shopSelect, stashSelect); + const vboxHighlight = validVboxSelect(vbox, itemInfo, storeSelect, stashSelect); // // VBOX // function vboxHover(e, v) { if (v) { e.stopPropagation(); - if (shopSelect.find(c => c[0])) return true; // There is a base skill or spec selected in the vbox + if (storeSelect.find(c => c[0])) return true; // There is a base skill or spec selected in the vbox if (stashSelect.length !== 0) { const base = stashSelect.find(c => !['Red', 'Blue', 'Green'].includes(vbox.bound[c])); if (base || base === 0) return true; @@ -164,23 +164,23 @@ class Vbox extends preact.Component { } function clearVboxSelected() { - setVboxSelected({ shopSelect: [], stashSelect: [] }); + setVboxSelected({ storeSelect: [], stashSelect: [] }); } function vboxBuySelected() { if (!vboxSelecting) return false; document.activeElement.blur(); - sendVboxAccept(shopSelect[0][0], shopSelect[0][1]); + sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); return true; } - function vboxHdr() { + function storeHdr() { return ( -
+

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'vbox')}> STORE + onMouseOver={e => vboxHover(e, 'store')}> STORE

vboxHover(e, 'bits')}>

{vbox.bits}b

@@ -214,7 +214,7 @@ class Vbox extends preact.Component { ); } function refundBtn() { - const refund = shopSelect.length === 0 && stashSelect.length === 1 + const refund = storeSelect.length === 0 && stashSelect.length === 1 ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost : 0; const tutorialDisabled = tutorial && tutorial < 8 @@ -241,14 +241,14 @@ class Vbox extends preact.Component { // EVERYTHING return (
- {vboxHdr()} + {storeHdr()} {stashHdr()} {refundBtn()}  ; - const selected = shopSelect.length && shopSelect.some(vs => vs[0] === group && vs[1] === index); + const selected = storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index); const comboHighlight = vboxHighlight && vboxHighlight.includes(v) ? 'combo-border' : ''; function onClick(e) { e.stopPropagation(); if (!comboHighlight) setInfo(vbox.free[group][index]); - if (shopSelect.length && shopSelect.some(vs => vs[0] === group && vs[1] === index)) { + if (storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index)) { return setVboxSelected( - { shopSelect: shopSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect } + { storeSelect: storeSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect } ); } - if (!shopSelect.length && !stashSelect.length) { - return setVboxSelected({ shopSelect: [[group, index]], stashSelect }); + if (!storeSelect.length && !stashSelect.length) { + return setVboxSelected({ storeSelect: [[group, index]], stashSelect }); } if (comboHighlight !== 'combo-border') { - return setVboxSelected({ shopSelect: [[group, index]], stashSelect: [] }); + return setVboxSelected({ storeSelect: [[group, index]], stashSelect: [] }); } - return setVboxSelected({ shopSelect: [...shopSelect, [group, index]], stashSelect }); + return setVboxSelected({ storeSelect: [...storeSelect, [group, index]], stashSelect }); } @@ -63,7 +63,7 @@ function storeElement(props) { } return ( -
e.stopPropagation()}>
diff --git a/client/src/constants.jsx b/client/src/constants.jsx index c0fb5541..f16b7f3b 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -24,10 +24,10 @@ module.exports = { }, INFO: { - vbox: { - item: 'VBOX', - description:

ITEMS that are available to buy.
- The VBOX is refilled every round.
Click REFILL at the bottom to purchase a refill.

, + store: { + item: 'STORE', + description:

Contains items that are available to buy.
+ The store is refilled every round.
Click REFILL to purchase a refill for 2 bits.

, }, stash: { item: 'STASH', @@ -35,11 +35,7 @@ module.exports = { }, bits: { item: 'BITS', - description:

The VBOX currency.
- Colours - 1b
- Skills - 2b
- Specs - 3b
- At the beginning of each round you receive 30 bits.

, + description:

Currency to buy items.
At the beginning of each round you receive 30 bits.

, }, ready: { item: 'READY', diff --git a/client/src/events.jsx b/client/src/events.jsx index 0f1beaad..f852313c 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -182,7 +182,7 @@ function registerEvents(store) { store.dispatch(actions.setActiveSkill(null)); store.dispatch(actions.setInfo(null)); store.dispatch(actions.setItemUnequip([])); - store.dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] })); + store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })); } function setAccountInstances(v) { diff --git a/client/src/keyboard.jsx b/client/src/keyboard.jsx index e12c6366..43d7343b 100644 --- a/client/src/keyboard.jsx +++ b/client/src/keyboard.jsx @@ -9,7 +9,7 @@ function setupKeys(store) { key('esc', () => store.dispatch(actions.setActiveSkill(null))); key('esc', () => store.dispatch(actions.setInfo(null))); key('esc', () => store.dispatch(actions.setItemUnequip([]))); - key('esc', () => store.dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] }))); + key('esc', () => store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] }))); key('esc', () => store.dispatch(actions.setMtxActive(null))); } diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index 1afff50b..3dcb0670 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -56,7 +56,7 @@ module.exports = { tutorial: createReducer(1, 'SET_TUTORIAL'), tutorialGame: createReducer(1, 'SET_TUTORIAL_GAME'), - vboxSelected: createReducer({ shopSelect: [], stashSelect: [] }, 'SET_VBOX_SELECTED'), + vboxSelected: createReducer({ storeSelect: [], stashSelect: [] }, 'SET_VBOX_SELECTED'), ws: createReducer(null, 'SET_WS'), }; From 672644514dd6efc8ed1e85a8e7bf6257a3e14756 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 10:35:17 +1000 Subject: [PATCH 28/97] 1150px text size breakpoint --- client/assets/styles/styles.less | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index 202674b2..e4e9264a 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -258,6 +258,17 @@ figure.gray { } } +@media (max-width: 1150px) { + #mnml { + font-size: 60%; + } + + svg { + height: 1em; + } +} + + .mobile-title { display: none; } From d4f2f9623f3e23b7aa661e9fccbaa77f4cc0adcb Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 22 Nov 2019 12:47:46 +1100 Subject: [PATCH 29/97] wi --- WORKLOG.md | 20 +++++- client/assets/styles/instance.less | 2 +- client/assets/styles/styles.less | 2 +- client/assets/styles/vbox.less | 80 ++++++++++++------------ client/src/components/vbox.combiner.jsx | 16 +++-- client/src/components/vbox.component.jsx | 70 ++++++++++----------- client/src/components/vbox.stash.jsx | 4 +- client/src/components/vbox.store.jsx | 14 ++--- 8 files changed, 107 insertions(+), 101 deletions(-) diff --git a/WORKLOG.md b/WORKLOG.md index f6df3063..daaaefb6 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -12,6 +12,22 @@ _ntr_ * animation effects * vbox combine / buy / equip etc * background music +* effects rework + +Siphon = +[ + DamageBlue(50%), + Apply( + Siphon(2T) + - Siphoning(2T) + ), +] + +Hexagon Set +- Pick Colour +- Random Walk +- Draw hex +- Increase intensity for each visit _mashy_ * buy from preview if you have the required bases in vbox / inventory @@ -53,9 +69,9 @@ _tba_ - Strike + SpeedRR -> StrikeSpeed (strike has Y% more speed) - Strike + LifeRR -> StrikeLife (Strike recharges X% of damage as red life) - - Can also work as module style passive keystones + - Can also work as module style passive keystones * troll life -> dmg -> Invert life spec? - * prince of peace + * prince of peace * bonus healing / no damage -> Heal power spec? * fuck magic -> Some sort of reflect spec? * empower on ko -> Amplify + Power spec diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 26bee42c..76e68884 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -5,7 +5,7 @@ .instance { overflow: hidden; display: grid; - grid-template-columns: min-content minmax(min-content, 1fr); + grid-template-columns: 3fr minmax(min-content, 6fr); grid-template-rows: min-content 1fr; grid-template-areas: diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index e4e9264a..72ab973c 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -125,7 +125,7 @@ button, input { font-family: 'Jura'; color: whitesmoke; height: auto; - border-width: 0.1em; + border-width: 0.2em; border-color: @gray-exists; letter-spacing: 0.25em; box-sizing: border-box; diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 411dae51..c4d5c6cd 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -2,40 +2,38 @@ align-content: space-between; grid-area: vbox; display: grid; - grid-template-rows: 9.5em 2.5em 4.5em min-content; - grid-template-columns: 8em 24em; + grid-template-rows: 1fr min-content; + grid-template-columns: 1fr 3fr; grid-template-areas: "store-hdr store" - "stash-hdr store" - "stash stash" - "refund combiner"; + "stash-hdr stash" + "refund combiner"; margin-bottom: 1em; line-height: 0; - .vbox-padding { - margin-left: 0.5em; - margin-bottom: 0.5em; - margin-top: 0.5em; - margin-right: 0.5em; + // immediate children + > div { + padding: 0.5em; } .store { grid-area: store; - border-bottom: 0.1em solid @gray-exists; - border-right: 0.1em solid @gray-exists; - border-top: 0.1em solid @gray-exists; + border-right: 0.2em solid @gray-exists; + border-top: 0.2em solid @gray-exists; } .store-hdr { grid-area: store-hdr; - border-bottom: 0.1em solid @gray-exists; - border-left: 0.1em solid @gray-exists; - border-top: 0.1em solid @gray-exists; + display: flex; + flex-flow: column; + text-align: center; + border-left: 0.2em solid @gray-exists; + border-top: 0.2em solid @gray-exists; + button { - margin-top: 0.5em; + margin: 1em 0 0 0; line-height: 1.6; - height: 4em; letter-spacing: 0.1em; background-color: #421010; &:hover { @@ -47,18 +45,17 @@ .combiner { grid-area: combiner; - border-top: 0.1em solid @gray-exists; - border-left: 0.1em solid @gray-exists; display: flex; flex-direction: column; - + + padding: 0.5em 0 0 0; + .vbox-padding { margin-right: 0em; margin-bottom: 0em; } button { - height: 3em; letter-spacing: 0.1em; background-color: #996100; &[disabled] { @@ -66,35 +63,42 @@ }; } } - + .stash { grid-area: stash; - .vbox-padding { - display: grid; - grid-template-columns: repeat(4, 1fr); - grid-gap: 0.5em 1em; - align-items: center; - } - border-right: 0.1em solid @gray-exists; - border-left: 0.1em solid @gray-exists; + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-gap: 0.5em 1em; + + align-items: center; + padding: 0.5em; + border: 0.2em solid @gray-exists; + border-left: 0; } .stash-hdr { + display: flex; + flex-flow: column; + justify-content: center; + grid-area: stash-hdr; - border-left: 0.1em solid @gray-exists; - border-right: 0.1em solid @gray-exists; text-align: center; + border: 0.2em solid @gray-exists; + border-right: 0; } .refund { + padding: 0.5em 0.5em 0 0; + button { line-height: 1.4; - height: 3em; letter-spacing: 0.1em; background-color: #996100; } - border-left: 0.1em solid @gray-exists; - border-bottom: 0.1em solid @gray-exists; + + .vbox-padding { + padding-left: 0; + } } .vbox-hdr { @@ -115,14 +119,12 @@ grid-template-columns: repeat(3, 1fr); grid-gap: 0.5em 1em; align-items: center; - margin-bottom: 0.5em; } .vbox-btn { width: 100%; margin: 0; background-color: @gray-box; - height: 3em; line-height: 1em; border-width: 0; @@ -153,7 +155,7 @@ } button { - height: 3.25em; + height: 4.5em; margin: 0; width: 100%; diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index 4b8ab14e..e1514e1f 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -52,15 +52,13 @@ function combinerBtn(props) { } return (
-
- -
+
); } diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 819c43b5..e5286807 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -177,27 +177,25 @@ class Vbox extends preact.Component { function storeHdr() { return (
-
-

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'store')}> STORE -

-
vboxHover(e, 'bits')}> -

{vbox.bits}b

-
- +

e.target.scrollIntoView(true)} + onMouseOver={e => vboxHover(e, 'store')}> STORE +

+
vboxHover(e, 'bits')}> +

{vbox.bits}b

+
); } @@ -205,11 +203,9 @@ class Vbox extends preact.Component { function stashHdr() { return (
-
-

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'stash')}> STASH -

-
+

e.target.scrollIntoView(true)} + onMouseOver={e => vboxHover(e, 'stash')}> STASH +

); } @@ -221,19 +217,17 @@ class Vbox extends preact.Component { && instance.time_control === 'Practice' && instance.rounds.length === 1; return (
-
- -
+
); } diff --git a/client/src/components/vbox.stash.jsx b/client/src/components/vbox.stash.jsx index 2aad03f0..4ed23fd7 100644 --- a/client/src/components/vbox.stash.jsx +++ b/client/src/components/vbox.stash.jsx @@ -99,9 +99,7 @@ function stashElement(props) { onDragOver={ev => ev.preventDefault()} onDrop={stashClick} > -
- {range(0, 4).map(i => stashBtn(vbox.bound[i], i))} -
+ {range(0, 4).map(i => stashBtn(vbox.bound[i], i))}
); } diff --git a/client/src/components/vbox.store.jsx b/client/src/components/vbox.store.jsx index 64d4e5fc..20a5a402 100644 --- a/client/src/components/vbox.store.jsx +++ b/client/src/components/vbox.store.jsx @@ -65,14 +65,12 @@ function storeElement(props) { return (
e.stopPropagation()}> -
-
- {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} -
-
- {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} - {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))} -
+
+ {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} +
+
+ {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} + {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))}
); From 5f2ee673b258da1ef4101f4b42511ef26c661f1e Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 12:52:23 +1000 Subject: [PATCH 30/97] mobile avatar --- client/assets/styles/styles.mobile.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index 2eba09ac..4d790489 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -19,7 +19,7 @@ stroke-width: 1.25em; } .avatar { - display: none; + opacity: 0.1; } } From 8e73dcd92c8a5bda8f45ded9ffca07ea500519af Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 14:34:48 +1000 Subject: [PATCH 31/97] game bottom margin, targetting arrow start / end hotfix --- client/assets/styles/game.less | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index 9b19db2c..ea48cede 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -27,6 +27,7 @@ position: absolute; bottom: 0; + margin-bottom: 0.5em; height: 50%; .avatar { @@ -232,8 +233,8 @@ #targeting, .resolving-skill { position: absolute; - top: 35%; - height: 15%; + top: calc(35% + 0.5em); // calc for 0.5em top gap + height: calc(15% - 1em); // calc for 0.5em + 0.5em top / bottom gap width: calc(90% - 1.25em); z-index: 2; span { @@ -273,7 +274,7 @@ /* some stupid bug in chrome makes it fill the entire screen */ @media screen and (-webkit-min-device-pixel-ratio:0) { #targeting { - max-height: 10em; + // max-height: 10em; } } From af803efe4f7215eeee0bfd74910533d3d5307dd6 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 15:02:42 +1000 Subject: [PATCH 32/97] targetting arrows for mobile --- client/src/components/targeting.arrows.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/components/targeting.arrows.jsx b/client/src/components/targeting.arrows.jsx index f93966c5..a7a7e4b3 100644 --- a/client/src/components/targeting.arrows.jsx +++ b/client/src/components/targeting.arrows.jsx @@ -110,8 +110,11 @@ class TargetSvg extends Component { ? playerTeam.constructs.findIndex(c => c.id === cast.target_construct_id) : otherTeam.constructs.findIndex(c => c.id === cast.target_construct_id); + const skillNumber = window.innerWidth <= 800 // mobile styling trigger + ? playerTeam.constructs[source].skills.findIndex(s => s.skill === cast.skill) + : 0; const sourceY = height; - const sourceX = (source * width / 3) + width / 24; + const sourceX = (source * width / 3) + width / 18 + skillNumber * (width / 9); const targetX = (target * width / 3) + width / 6 + (defensive ? width / 64 : 0) + (source * width / 18); From b5ab43a18a818e1893ee82fe99212e5731268fea Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 22 Nov 2019 15:19:22 +1000 Subject: [PATCH 33/97] fix game phase for small phones --- client/assets/styles/styles.mobile.less | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index 4d790489..0914c4f2 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -1,7 +1,6 @@ @media (max-width: 800px) { body { overflow-y: initial; - } #mnml { @@ -138,7 +137,7 @@ } -// portrait menu +// portrait menu or small size vertical in landscape @media (max-width: 600px) { #mnml { grid-template-columns: 1fr; @@ -206,6 +205,14 @@ } } + .stats { + font-size: 6pt; + } + + .skill-description { + font-size: 6pt; + } + section { .list { grid-template-columns: 1fr; From 2d3c6cd18c316cb57de5422ad31dda4e9afdc142 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 22 Nov 2019 16:26:43 +1100 Subject: [PATCH 34/97] SIX size stash --- client/assets/styles/instance.less | 2 +- client/assets/styles/vbox.less | 25 +++++++++------ client/src/components/vbox.combiner.jsx | 2 +- client/src/components/vbox.component.jsx | 41 +++++++++++------------- client/src/components/vbox.stash.jsx | 2 +- server/src/vbox.rs | 6 ++-- 6 files changed, 41 insertions(+), 37 deletions(-) diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 76e68884..055ee56e 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -5,7 +5,7 @@ .instance { overflow: hidden; display: grid; - grid-template-columns: 3fr minmax(min-content, 6fr); + grid-template-columns: 1fr minmax(min-content, 1fr); grid-template-rows: min-content 1fr; grid-template-areas: diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index c4d5c6cd..8534d374 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -2,12 +2,11 @@ align-content: space-between; grid-area: vbox; display: grid; - grid-template-rows: 1fr min-content; - grid-template-columns: 1fr 3fr; + grid-template-rows: 3fr 2fr; + grid-template-columns: 1fr 4fr 1fr; grid-template-areas: - "store-hdr store" - "stash-hdr stash" - "refund combiner"; + "store-hdr store combiner" + "stash-hdr stash combiner"; margin-bottom: 1em; line-height: 0; @@ -48,7 +47,7 @@ display: flex; flex-direction: column; - padding: 0.5em 0 0 0; + padding: 0; .vbox-padding { margin-right: 0em; @@ -58,20 +57,24 @@ button { letter-spacing: 0.1em; background-color: #996100; + border-radius: 0; + border: 0; &[disabled] { - color: #996100; + border: 0.2em solid @gray-exists; + border-left: 0; }; + + transition-property: 0; } } .stash { grid-area: stash; display: grid; - grid-template-columns: repeat(4, 1fr); + grid-template-columns: repeat(3, 1fr); grid-gap: 0.5em 1em; align-items: center; - padding: 0.5em; border: 0.2em solid @gray-exists; border-left: 0; } @@ -85,6 +88,10 @@ text-align: center; border: 0.2em solid @gray-exists; border-right: 0; + + h3 { + margin-bottom: 2.5em; + } } .refund { diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index e1514e1f..48277f3e 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -34,7 +34,7 @@ function combinerBtn(props) { let bits = 0; storeSelect.forEach(item => bits += item[0] + 1); text = bits - ? `Buy ${comboItem} - ${bits}b` + ? `${comboItem} - ${bits}b` : `Combine - ${comboItem}`; if (vbox.bits >= bits) mouseEvent = sendVboxCombine; } else if (stashSelect.length === 0 && storeSelect.length === 1) { diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index e5286807..9d3f124c 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -201,33 +201,31 @@ class Vbox extends preact.Component { } function stashHdr() { - return ( -
-

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'stash')}> STASH -

-
- ); - } - function refundBtn() { const refund = storeSelect.length === 0 && stashSelect.length === 1 ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost : 0; const tutorialDisabled = tutorial && tutorial < 8 && instance.time_control === 'Practice' && instance.rounds.length === 1; + const refundBtn = ( + + ); + return ( -
- +
+

e.target.scrollIntoView(true)} + onMouseOver={e => vboxHover(e, 'stash')}> STASH +

+ {refundBtn}
); } @@ -237,7 +235,6 @@ class Vbox extends preact.Component {
{storeHdr()} {stashHdr()} - {refundBtn()} ev.preventDefault()} onDrop={stashClick} > - {range(0, 4).map(i => stashBtn(vbox.bound[i], i))} + {range(0, 6).map(i => stashBtn(vbox.bound[i], i))}
); } diff --git a/server/src/vbox.rs b/server/src/vbox.rs index a419a6f1..8f8f37a4 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -100,7 +100,7 @@ impl Vbox { } pub fn accept(&mut self, i: usize, j: usize, construct_id: Option) -> Result<&mut Vbox, Error> { - if self.bound.len() >= 4 && !construct_id.is_some() { + if self.bound.len() >= 6 && !construct_id.is_some() { return Err(err_msg("too many items bound")); } @@ -150,7 +150,7 @@ impl Vbox { for vi in vbox_indicies.iter() { inv_indices.push(self.bound.len()); self.accept(vi[0], vi[1], Some(Uuid::nil()))?; - } + } // have to sort the indices and keep track of the iteration // because when removing the elements the array shifts @@ -171,7 +171,7 @@ impl Vbox { self.bound.push(combo.item); // self.bound.sort_unstable(); - if self.bound.len() >= 5 { + if self.bound.len() >= 6 { return Err(err_msg("too many items bound")); } Ok(self) From 3a0692a2a5a9c6d8ba4282a14b1d55cb08bfc385 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 22 Nov 2019 16:36:11 +1100 Subject: [PATCH 35/97] resize stuff --- client/assets/styles/vbox.less | 20 ++++++++++++-------- client/src/components/vbox.combiner.jsx | 2 +- client/src/components/vbox.component.jsx | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 8534d374..a48ebad0 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -17,8 +17,8 @@ .store { grid-area: store; - border-right: 0.2em solid @gray-exists; - border-top: 0.2em solid @gray-exists; + border-right: 0.1em solid @gray; + border-top: 0.1em solid @gray; } .store-hdr { @@ -27,8 +27,12 @@ flex-flow: column; text-align: center; - border-left: 0.2em solid @gray-exists; - border-top: 0.2em solid @gray-exists; + border-left: 0.1em solid @gray; + border-top: 0.1em solid @gray; + + h1 { + margin-bottom: 0; + } button { margin: 1em 0 0 0; @@ -60,7 +64,7 @@ border-radius: 0; border: 0; &[disabled] { - border: 0.2em solid @gray-exists; + border: 0.1em solid @gray; border-left: 0; }; @@ -75,7 +79,7 @@ grid-gap: 0.5em 1em; align-items: center; - border: 0.2em solid @gray-exists; + border: 0.1em solid @gray; border-left: 0; } @@ -86,7 +90,7 @@ grid-area: stash-hdr; text-align: center; - border: 0.2em solid @gray-exists; + border: 0.1em solid @gray; border-right: 0; h3 { @@ -162,7 +166,7 @@ } button { - height: 4.5em; + height: 3.5em; margin: 0; width: 100%; diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index 48277f3e..e1514e1f 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -34,7 +34,7 @@ function combinerBtn(props) { let bits = 0; storeSelect.forEach(item => bits += item[0] + 1); text = bits - ? `${comboItem} - ${bits}b` + ? `Buy ${comboItem} - ${bits}b` : `Combine - ${comboItem}`; if (vbox.bits >= bits) mouseEvent = sendVboxCombine; } else if (stashSelect.length === 0 && storeSelect.length === 1) { diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 9d3f124c..e51b94be 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -182,7 +182,7 @@ class Vbox extends preact.Component { onMouseOver={e => vboxHover(e, 'store')}> STORE
vboxHover(e, 'bits')}> -

{vbox.bits}b

+

{vbox.bits}b

+
+ ); } - return ( -
- -
- ); } -module.exports = combinerBtn; +module.exports = addState(CombinerBtn); diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index e51b94be..756f17ee 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -5,9 +5,9 @@ const forEach = require('lodash/forEach'); const actions = require('../actions'); +const InfoContainer = require('./info.container'); const StashElement = require('./vbox.stash'); const StoreElement = require('./vbox.store'); -const CombinerElement = require('./vbox.combiner'); const addState = connect( function receiveState(state) { @@ -16,6 +16,7 @@ const addState = connect( instance, player, vboxSelected, + info, itemInfo, itemUnequip, tutorial, @@ -30,10 +31,6 @@ const addState = connect( return ws.sendVboxAccept(instance.id, group, index); } - function sendVboxCombine() { - return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); - } - function sendVboxReclaim(i) { return ws.sendVboxReclaim(instance.id, i); } @@ -44,9 +41,9 @@ const addState = connect( return { instance, + info, player, sendVboxAccept, - sendVboxCombine, sendVboxDiscard, sendVboxReclaim, vboxSelected, @@ -130,7 +127,6 @@ class Vbox extends preact.Component { // Function Calls sendItemUnequip, sendVboxAccept, - sendVboxCombine, sendVboxDiscard, sendVboxReclaim, setVboxSelected, @@ -235,6 +231,10 @@ class Vbox extends preact.Component {
{storeHdr()} {stashHdr()} + -
); } From 9b6bf4442e036ef585f8029d764d86d4ebd345fb Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 23 Nov 2019 17:20:43 +1000 Subject: [PATCH 41/97] default button styling 60% width --- client/assets/styles/vbox.less | 10 ++-------- client/src/components/info.thresholds.jsx | 6 +----- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 05dd9867..ec739a11 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -212,6 +212,8 @@ .combiner { grid-area: combiner; + display: flex; + width: 60%; button { margin-top: 1em; line-height: 1.3; @@ -219,15 +221,7 @@ letter-spacing: 0.1em; - background-color: @yellow; - color: black; - border-radius: 0; border: 0; - &[disabled] { - border: 0.1em solid @gray; - border-left: 0; - color: @gray-exists; - }; transition-property: 0; } } diff --git a/client/src/components/info.thresholds.jsx b/client/src/components/info.thresholds.jsx index 930882bd..6785380e 100644 --- a/client/src/components/info.thresholds.jsx +++ b/client/src/components/info.thresholds.jsx @@ -89,11 +89,7 @@ function specThresholds(player, fullInfo, info) { return (
- {thresholds[0]} - {thresholds[1]} -
-
- {thresholds[2]} + {thresholds}
From b9e4eca8cfc38597c785a7ca5a8314b570620ebb Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 23 Nov 2019 19:53:06 +1000 Subject: [PATCH 42/97] vbox info always what selected prio full combo > bases > colour --- client/assets/styles/vbox.less | 7 +- client/src/components/info.component.jsx | 195 ------------- client/src/components/info.container.jsx | 43 --- client/src/components/instance.component.jsx | 4 - client/src/components/vbox.combiner.jsx | 39 +-- client/src/components/vbox.component.jsx | 8 +- client/src/components/vbox.info.jsx | 261 ++++++++++++++++++ ...hresholds.jsx => vbox.info.thresholds.jsx} | 0 8 files changed, 270 insertions(+), 287 deletions(-) delete mode 100644 client/src/components/info.component.jsx delete mode 100644 client/src/components/info.container.jsx create mode 100644 client/src/components/vbox.info.jsx rename client/src/components/{info.thresholds.jsx => vbox.info.thresholds.jsx} (100%) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index ec739a11..859919d8 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -218,11 +218,10 @@ margin-top: 1em; line-height: 1.3; font-size: 1.25em; - - letter-spacing: 0.1em; - border: 0; - transition-property: 0; + &:hover { + border: 2px solid @gray-hover; + } } } diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx deleted file mode 100644 index 4b59e4d3..00000000 --- a/client/src/components/info.component.jsx +++ /dev/null @@ -1,195 +0,0 @@ -const preact = require('preact'); -const reactStringReplace = require('react-string-replace'); - -const specThresholds = require('./info.thresholds'); -const { INFO } = require('./../constants'); -const { convertItem, removeTier } = require('../utils'); -const { tutorialStage } = require('../tutorial.utils'); -const shapes = require('./shapes'); - -const Combiner = require('./vbox.combiner'); - - -class InfoComponent extends preact.Component { - shouldComponentUpdate(newProps, newState) { - if (newProps.vboxHighlight !== this.props.vboxHighlight) return true; - if (newProps.tutorial !== this.props.tutorial) return true; - // We don't care about info during tutorial - if (newProps.tutorial && this.props.instance.time_control === 'Practice' - && this.props.instance.rounds.length === 1) return false; - if (newProps.info !== this.props.info) return true; - if (newState.comboItem !== this.state.comboItem) return true; - - return false; - } - - componentDidUpdate(prevProps) { - // Catch case where mouse events don't properly clear state and info changed - if (prevProps.info !== this.props.info && this.state.comboItem) this.setState({ comboItem: null }); - } - - render(args) { - const { - // Variables that will change - info, - tutorial, - vboxHighlight, - - // Static - player, // Only used for colour calcs which will be update if info changes - ws, - itemInfo, - instance, // Only used for instance id - // functions - setTutorialNull, - } = args; - const { comboItem } = this.state; - function Info() { - if (tutorial) { - const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance); - if (tutorialStageInfo) return tutorialStageInfo; - } - if (!info) return false; - if (info.includes('constructName')) { - return ( -
-

{info.replace('constructName ', '')}

-

This is the name of your construct.
- Names are randomly generated and are purely cosmetic.
- You can change change your construct name in the RESHAPE tab outside of games. -

-
- ); - } - - if (info.includes('constructAvatar')) { - return ( -
-

{info.replace('constructAvatar ', '')}

-

This is your construct avatar.
- Avatars are randomly generated and are purely cosmetic.
- You can change your construct avatar in the RESHAPE tab outside of games. -

-
- ); - } - const fullInfo = comboItem - ? itemInfo.items.find(i => i.item === comboItem) || INFO[comboItem] - : itemInfo.items.find(i => i.item === info) || INFO[info]; - if (!fullInfo) return false; - const isSkill = fullInfo.skill; - const isSpec = fullInfo.spec; - - const itemDescription = () => { - const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/; - const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]()); - return
{reactStringReplace(infoDescription, '\n', () =>
)}
; - }; - - if (isSkill || isSpec) { - let infoName = fullInfo.item; - while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+'); - - const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item)); - - let itemSourceInfo = itemSource.length && !isSpec - ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` - : false; - - let header = null; - if (!itemSource.length) header = isSkill ?

SKILL

:

SPEC

; - if (itemSourceInfo) { - while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+'); - const itemRegEx = /(Red|Blue|Green)/; - itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); - } - - const cooldown = isSkill && fullInfo.cooldown ?
{fullInfo.cooldown} Turn delay
: null; - - const speed = isSkill - ?
Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
- : null; - - const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null; - - return ( -
-

{infoName}

- {header} - {itemSourceInfo} - {cooldown} - {itemDescription()} - {speed} - {thresholds} -
- ); - } - - return ( -
-

{fullInfo.item}

- {itemDescription()} -
- ); - } - - const Combos = () => { - if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; -/* const generalNotes = ( -
-

General

-

- You can preview combos by clicking the combined item when it appears in this section.
- Click the READY button to start the GAME PHASE. -

-
- );*/ - if (!player) return false; - if (!info) return false; - - const vboxCombos = itemInfo.combos.filter(c => c.components.includes(info)); - if (vboxCombos.length > 6 || vboxCombos.length === 0) return false; - - const comboTable = vboxCombos.map((c, i) => { - const mouseOver = e => { - e.stopPropagation(); - this.setState({ comboItem: c.item }); - }; - const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) - ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, -
{convertItem(c.components[2])}
] - : c.components.map((u, j) =>
{convertItem(u)}
); - return ( -
-
- {convertItem(c.item)} -
- {componentTable} -
- ); - }); - const comboList = comboTable.length > 0 ?
{comboTable}
: false; - return ( -
-
-

COMBOS

- Combine colours and items. -
- {comboList} -
- ); - }; - - return ( -
-
this.setState({ comboItem: null })}> - - -
- -
- ); - } -} - -module.exports = InfoComponent; diff --git a/client/src/components/info.container.jsx b/client/src/components/info.container.jsx deleted file mode 100644 index 8a8dbb6f..00000000 --- a/client/src/components/info.container.jsx +++ /dev/null @@ -1,43 +0,0 @@ -const { connect } = require('preact-redux'); - -const actions = require('../actions'); -const Info = require('./info.component'); - -const addState = connect( - function receiveState(state) { - const { - ws, - info, - itemInfo, - instance, - player, - account, - tutorial, - } = state; - - return { - ws, - info, - itemInfo, - instance, - player, - account, - tutorial, - }; - }, - - function receiveDispatch(dispatch) { - function setTutorialNull() { - dispatch(actions.setTutorial(null)); - } - - function setInfo(info) { - dispatch(actions.setInfo(info)); - } - return { setTutorialNull, setInfo }; - } - - -); - -module.exports = addState(Info); diff --git a/client/src/components/instance.component.jsx b/client/src/components/instance.component.jsx index d0d34345..c59b5833 100644 --- a/client/src/components/instance.component.jsx +++ b/client/src/components/instance.component.jsx @@ -55,10 +55,6 @@ function Instance(args) { clearItems(); } - function onTouchMove(e) { - e.preventDefault(); - } - return (
diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index 1ffd6797..261fb7a2 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -1,6 +1,5 @@ const preact = require('preact'); const { connect } = require('preact-redux'); -const countBy = require('lodash/countBy'); const actions = require('../actions'); @@ -27,19 +26,9 @@ const addState = connect( return { vbox, vboxSelected, - itemInfo, sendVboxAccept, sendVboxCombine, }; - }, - function receiveDispatch(dispatch) { - function setInfo(item) { - return dispatch(actions.setInfo(item)); - } - - return { - setInfo, - }; } ); @@ -47,22 +36,18 @@ class CombinerBtn extends preact.Component { shouldComponentUpdate(newProps) { // Single variable props if (newProps.vbox !== this.props.vbox) return true; - if (newProps.vboxHighlight !== this.props.vboxHighlight) return true; if (newProps.vboxSelected !== this.props.vboxSelected) return true; return false; } render(props) { const { - vboxHighlight, - vbox, vboxSelected, - itemInfo, sendVboxAccept, sendVboxCombine, + combinerCombo, - setInfo, } = props; const { stashSelect, storeSelect } = vboxSelected; @@ -73,31 +58,15 @@ class CombinerBtn extends preact.Component { sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); return true; } - let text = ''; let mouseEvent = false; - const combineLength = stashSelect.length + storeSelect.length; - if (vboxHighlight && vboxHighlight.length === 0) { - // The selected items can't be combined with additional items therefore valid combo - const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); - const selectedItems = stashItems.concat(shopItems); - const combinerCount = countBy(selectedItems, co => co); - - const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { - if (!combo.components.includes(c)) return false; - const comboCount = countBy(combo.components, co => co); - if (combinerCount[c] > comboCount[c]) return false; - return true; - })); - let comboItem = comboItemObj ? comboItemObj.item : 'refine'; - setInfo(comboItem); - comboItem = comboItem.replace('Plus', '+'); + if (combinerCombo) { + const comboItem = combinerCombo.replace('Plus', '+'); let bits = 0; storeSelect.forEach(item => bits += item[0] + 1); text = bits ? `Buy ${comboItem} ${bits}b` - : `Combine${comboItem}`; + : `Combine ${comboItem}`; if (vbox.bits >= bits) mouseEvent = sendVboxCombine; } else if (stashSelect.length === 0 && storeSelect.length === 1) { const item = storeSelect[0]; diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 756f17ee..1476ffb7 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -5,7 +5,7 @@ const forEach = require('lodash/forEach'); const actions = require('../actions'); -const InfoContainer = require('./info.container'); +const InfoContainer = require('./vbox.info'); const StashElement = require('./vbox.stash'); const StoreElement = require('./vbox.store'); @@ -149,11 +149,7 @@ class Vbox extends preact.Component { function vboxHover(e, v) { if (v) { e.stopPropagation(); - if (storeSelect.find(c => c[0])) return true; // There is a base skill or spec selected in the vbox - if (stashSelect.length !== 0) { - const base = stashSelect.find(c => !['Red', 'Blue', 'Green'].includes(vbox.bound[c])); - if (base || base === 0) return true; - } + if (stashSelect.length !== 0 || storeSelect.length !== 0) return true; setInfo(v); } return true; diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx new file mode 100644 index 00000000..3a553c0d --- /dev/null +++ b/client/src/components/vbox.info.jsx @@ -0,0 +1,261 @@ +const preact = require('preact'); +const { connect } = require('preact-redux'); +const reactStringReplace = require('react-string-replace'); +const countBy = require('lodash/countBy'); + +const specThresholds = require('./vbox.info.thresholds'); +const { INFO } = require('./../constants'); +const { convertItem, removeTier } = require('../utils'); +const { tutorialStage } = require('../tutorial.utils'); +const shapes = require('./shapes'); +const Combiner = require('./vbox.combiner'); + +const actions = require('../actions'); + +const addState = connect( + function receiveState(state) { + const { + ws, + info, + itemInfo, + instance, + player, + account, + tutorial, + vboxSelected, + } = state; + + return { + ws, + info, + itemInfo, + instance, + player, + account, + tutorial, + vboxSelected, + }; + }, + + function receiveDispatch(dispatch) { + function setTutorialNull() { + dispatch(actions.setTutorial(null)); + } + + function setInfo(info) { + dispatch(actions.setInfo(info)); + } + return { setTutorialNull, setInfo }; + } +); + +class InfoComponent extends preact.Component { + shouldComponentUpdate(newProps, newState) { + if (newProps.vboxSelected !== this.props.vboxSelected) return true; + if (newProps.vboxHighlight !== this.props.vboxHighlight) return true; + if (newProps.tutorial !== this.props.tutorial) return true; + // We don't care about info during tutorial + if (newProps.tutorial && this.props.instance.time_control === 'Practice' + && this.props.instance.rounds.length === 1) return false; + if (newProps.info !== this.props.info) return true; + if (newState.comboItem !== this.state.comboItem) return true; + + return false; + } + + componentDidUpdate(prevProps) { + // Catch case where mouse events don't properly clear state and info changed + if (prevProps.info !== this.props.info && this.state.comboItem) this.setState({ comboItem: null }); + } + + render(args) { + const { + // Variables that will change + info, + tutorial, + vboxHighlight, + vboxSelected, + // Static + player, // Only used for colour calcs which will be update if info changes + ws, + itemInfo, + instance, // Only used for instance id + // functions + setTutorialNull, + } = args; + const { comboItem } = this.state; + + const { vbox } = player; + const { stashSelect, storeSelect } = vboxSelected; + + const vboxCombo = () => { + if (!(vboxHighlight && vboxHighlight.length === 0)) return false; + // The selected items can't be combined with additional items therefore valid combo + const stashItems = stashSelect.map(j => vbox.bound[j]); + const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); + const selectedItems = stashItems.concat(shopItems); + const combinerCount = countBy(selectedItems, co => co); + + const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { + if (!combo.components.includes(c)) return false; + const comboCount = countBy(combo.components, co => co); + if (combinerCount[c] > comboCount[c]) return false; + return true; + })); + return comboItemObj.item; + }; + + const combinerCombo = vboxCombo(); + const checkVboxInfo = () => { + if (combinerCombo) return combinerCombo; + const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i]))); + if (stashBase > -1) return vbox.bound[stashBase]; + const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]]))); + if (storeBase) return vbox.free[storeBase[0]][storeBase[1]]; + if (stashSelect.length > 0) return vbox.bound[stashSelect[0]]; + if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]]; + return false; + }; + + const vboxInfo = (stashSelect.length > 0 || storeSelect.length > 0) ? checkVboxInfo() : false; + + function Info() { + if (tutorial) { + const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance); + if (tutorialStageInfo) return tutorialStageInfo; + } + + function genItemInfo(item) { + const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item]; + const isSkill = fullInfo.skill; + const isSpec = fullInfo.spec; + const itemDescription = () => { + const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/; + const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]()); + return
{reactStringReplace(infoDescription, '\n', () =>
)}
; + }; + if (isSkill || isSpec) { + let infoName = fullInfo.item; + while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+'); + + const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item)); + + let itemSourceInfo = itemSource.length && !isSpec + ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` + : false; + + let header = null; + if (!itemSource.length) header = isSkill ?

SKILL

:

SPEC

; + if (itemSourceInfo) { + while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+'); + const itemRegEx = /(Red|Blue|Green)/; + itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); + } + + const cooldown = isSkill && fullInfo.cooldown ?
{fullInfo.cooldown} Turn delay
: null; + + const speed = isSkill + ?
Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
+ : null; + + const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null; + + return ( +
+

{infoName}

+ {header} + {itemSourceInfo} + {cooldown} + {itemDescription()} + {speed} + {thresholds} +
+ ); + } + return ( +
+

{fullInfo.item}

+ {itemDescription()} +
+ ); + } + if (vboxInfo) return genItemInfo(vboxInfo); + if (!info) return false; + if (info.includes('constructName')) { + return ( +
+

{info.replace('constructName ', '')}

+

This is the name of your construct.
+ Names are randomly generated and are purely cosmetic.
+ You can change change your construct name in the RESHAPE tab outside of games. +

+
+ ); + } + + if (info.includes('constructAvatar')) { + return ( +
+

{info.replace('constructAvatar ', '')}

+

This is your construct avatar.
+ Avatars are randomly generated and are purely cosmetic.
+ You can change your construct avatar in the RESHAPE tab outside of games. +

+
+ ); + } + const stateFullInfo = comboItem || info; + if (!stateFullInfo) return false; + return genItemInfo(stateFullInfo); + } + + const Combos = () => { + if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; + if (!info && !vboxInfo) return false; + const comboInfo = vboxInfo || info; + const vboxCombos = itemInfo.combos.filter(c => c.components.includes(comboInfo)); + if (vboxCombos.length > 6 || vboxCombos.length === 0) return false; + + const comboTable = vboxCombos.map((c, i) => { + const mouseOver = e => { + e.stopPropagation(); + this.setState({ comboItem: c.item }); + }; + const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) + ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, +
{convertItem(c.components[2])}
] + : c.components.map((u, j) =>
{convertItem(u)}
); + return ( +
+
+ {convertItem(c.item)} +
+ {componentTable} +
+ ); + }); + const comboList = comboTable.length > 0 ?
{comboTable}
: false; + return ( +
+
+

COMBOS

+ Combine colours and items. +
+ {comboList} +
+ ); + }; + + return ( +
+
this.setState({ comboItem: null })}> + + +
+ +
+ ); + } +} + +module.exports = addState(InfoComponent); diff --git a/client/src/components/info.thresholds.jsx b/client/src/components/vbox.info.thresholds.jsx similarity index 100% rename from client/src/components/info.thresholds.jsx rename to client/src/components/vbox.info.thresholds.jsx From 8641e74f9be0e5604b392d9187f9266936a4530a Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 23 Nov 2019 20:24:15 +1000 Subject: [PATCH 43/97] fix combo preview --- client/assets/styles/vbox.less | 24 ++++++------------------ client/src/components/vbox.component.jsx | 8 ++++---- client/src/components/vbox.info.jsx | 8 ++++---- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 859919d8..0e4ca057 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -31,11 +31,10 @@ border-top: 0.1em solid @gray; h1 { - margin-bottom: 0; + margin-bottom: 0.5em; } button { - margin: 1em 0 0 0; line-height: 1.6; letter-spacing: 0.1em; background-color: #421010; @@ -58,32 +57,21 @@ } .stash-hdr { + grid-area: stash-hdr; display: flex; flex-flow: column; - justify-content: center; - - grid-area: stash-hdr; + text-align: center; border: 0.1em solid @gray; border-right: 0; - h3 { - margin-bottom: 2.5em; + h2 { + margin-bottom: 0.5em; } - } - - .refund { - padding: 0.5em 0.5em 0 0; button { - line-height: 1.4; + line-height: 1.6; letter-spacing: 0.1em; - color: black; - background-color: @yellow; - } - - .vbox-padding { - padding-left: 0; } } diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 1476ffb7..b4c2f42b 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -169,10 +169,10 @@ class Vbox extends preact.Component { function storeHdr() { return (
-

e.target.scrollIntoView(true)} onMouseOver={e => vboxHover(e, 'store')}> STORE -

+
vboxHover(e, 'bits')}>

{vbox.bits}b

@@ -214,9 +214,9 @@ class Vbox extends preact.Component { return (
-

e.target.scrollIntoView(true)} +

e.target.scrollIntoView(true)} onMouseOver={e => vboxHover(e, 'stash')}> STASH -

+ {refundBtn}
); diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index 3a553c0d..b83dfd3c 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -179,7 +179,8 @@ class InfoComponent extends preact.Component {
); } - if (vboxInfo) return genItemInfo(vboxInfo); + const stateFullInfo = comboItem || vboxInfo; + if (stateFullInfo) return genItemInfo(stateFullInfo); if (!info) return false; if (info.includes('constructName')) { return ( @@ -204,9 +205,8 @@ class InfoComponent extends preact.Component {
); } - const stateFullInfo = comboItem || info; - if (!stateFullInfo) return false; - return genItemInfo(stateFullInfo); + + return genItemInfo(info); } const Combos = () => { From f0ea19940f4b08a51c5a77fd2ac39b8f71318e7c Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 23 Nov 2019 20:26:45 +1000 Subject: [PATCH 44/97] stash length fix (buy 3 item full combo from vbox) --- server/src/vbox.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 8f8f37a4..07708056 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -171,7 +171,7 @@ impl Vbox { self.bound.push(combo.item); // self.bound.sort_unstable(); - if self.bound.len() >= 6 { + if self.bound.len() >= 7 { return Err(err_msg("too many items bound")); } Ok(self) From 754f3e0025c3eb3fbac5a20312e8624b6189a3df Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 23 Nov 2019 20:27:11 +1000 Subject: [PATCH 45/97] length clarify --- server/src/vbox.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/vbox.rs b/server/src/vbox.rs index 07708056..faf93fdc 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -171,7 +171,7 @@ impl Vbox { self.bound.push(combo.item); // self.bound.sort_unstable(); - if self.bound.len() >= 7 { + if self.bound.len() > 6 { return Err(err_msg("too many items bound")); } Ok(self) From 16af4da2494a453ba2851b4947ac63671bd86a93 Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 23 Nov 2019 21:05:17 +1000 Subject: [PATCH 46/97] move combiner into info (clear buy/combine) on combo hover --- client/src/components/vbox.combiner.jsx | 92 ------------------------- client/src/components/vbox.info.jsx | 54 ++++++++++++++- 2 files changed, 52 insertions(+), 94 deletions(-) delete mode 100644 client/src/components/vbox.combiner.jsx diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx deleted file mode 100644 index 261fb7a2..00000000 --- a/client/src/components/vbox.combiner.jsx +++ /dev/null @@ -1,92 +0,0 @@ -const preact = require('preact'); -const { connect } = require('preact-redux'); - -const actions = require('../actions'); - -const addState = connect( - function receiveState(state) { - const { - ws, - instance, - vboxSelected, - itemInfo, - player, - } = state; - - const { vbox } = player; - function sendVboxAccept(group, index) { - document.activeElement.blur(); - return ws.sendVboxAccept(instance.id, group, index); - } - - function sendVboxCombine() { - return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); - } - - return { - vbox, - vboxSelected, - sendVboxAccept, - sendVboxCombine, - }; - } -); - -class CombinerBtn extends preact.Component { - shouldComponentUpdate(newProps) { - // Single variable props - if (newProps.vbox !== this.props.vbox) return true; - if (newProps.vboxSelected !== this.props.vboxSelected) return true; - return false; - } - - render(props) { - const { - vbox, - vboxSelected, - sendVboxAccept, - sendVboxCombine, - combinerCombo, - - } = props; - - const { stashSelect, storeSelect } = vboxSelected; - - function vboxBuySelected() { - if (!(storeSelect.length === 1 && stashSelect.length === 0)) return false; - document.activeElement.blur(); - sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); - return true; - } - let text = ''; - let mouseEvent = false; - if (combinerCombo) { - const comboItem = combinerCombo.replace('Plus', '+'); - let bits = 0; - storeSelect.forEach(item => bits += item[0] + 1); - text = bits - ? `Buy ${comboItem} ${bits}b` - : `Combine ${comboItem}`; - if (vbox.bits >= bits) mouseEvent = sendVboxCombine; - } else if (stashSelect.length === 0 && storeSelect.length === 1) { - const item = storeSelect[0]; - text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`; - mouseEvent = vboxBuySelected; - } else { - return false; - } - return ( -
- -
- ); - } -} - -module.exports = addState(CombinerBtn); diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index b83dfd3c..63bf5552 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -8,7 +8,6 @@ const { INFO } = require('./../constants'); const { convertItem, removeTier } = require('../utils'); const { tutorialStage } = require('../tutorial.utils'); const shapes = require('./shapes'); -const Combiner = require('./vbox.combiner'); const actions = require('../actions'); @@ -25,6 +24,15 @@ const addState = connect( vboxSelected, } = state; + function sendVboxAccept(group, index) { + document.activeElement.blur(); + return ws.sendVboxAccept(instance.id, group, index); + } + + function sendVboxCombine() { + return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); + } + return { ws, info, @@ -34,6 +42,8 @@ const addState = connect( account, tutorial, vboxSelected, + sendVboxAccept, + sendVboxCombine, }; }, @@ -81,6 +91,8 @@ class InfoComponent extends preact.Component { itemInfo, instance, // Only used for instance id // functions + sendVboxAccept, + sendVboxCombine, setTutorialNull, } = args; const { comboItem } = this.state; @@ -246,11 +258,49 @@ class InfoComponent extends preact.Component { ); }; + const Combiner = () => { + if (comboItem) return false; + function vboxBuySelected() { + if (!(storeSelect.length === 1 && stashSelect.length === 0)) return false; + document.activeElement.blur(); + sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); + return true; + } + let text = ''; + let mouseEvent = false; + if (combinerCombo) { + const combinerComboText = combinerCombo.replace('Plus', '+'); + let bits = 0; + storeSelect.forEach(item => bits += item[0] + 1); + text = bits + ? `Buy ${combinerComboText} ${bits}b` + : `Combine ${combinerComboText}`; + if (vbox.bits >= bits) mouseEvent = sendVboxCombine; + } else if (stashSelect.length === 0 && storeSelect.length === 1) { + const item = storeSelect[0]; + text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`; + mouseEvent = vboxBuySelected; + } else { + return false; + } + return ( +
+ +
+ ); + }; + return (
this.setState({ comboItem: null })}> - +
From e702e3fdd1173104dfa47cd0d33e840286332f1d Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 23 Nov 2019 21:17:56 +1000 Subject: [PATCH 47/97] vbox border width --- client/assets/styles/vbox.less | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 0e4ca057..aefd4f28 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -17,8 +17,8 @@ .store { grid-area: store; - border-right: 0.1em solid @gray; - border-top: 0.1em solid @gray; + border-right: 0.15em solid @gray; + border-top: 0.15em solid @gray; } .store-hdr { @@ -27,8 +27,8 @@ flex-flow: column; text-align: center; - border-left: 0.1em solid @gray; - border-top: 0.1em solid @gray; + border-left: 0.15em solid @gray; + border-top: 0.15em solid @gray; h1 { margin-bottom: 0.5em; @@ -36,7 +36,7 @@ button { line-height: 1.6; - letter-spacing: 0.1em; + letter-spacing: 0.15em; background-color: #421010; &:hover { background-color: @red; @@ -52,7 +52,7 @@ grid-gap: 0.5em 1em; align-items: center; - border: 0.1em solid @gray; + border: 0.15em solid @gray; border-left: 0; } @@ -62,7 +62,7 @@ flex-flow: column; text-align: center; - border: 0.1em solid @gray; + border: 0.15em solid @gray; border-right: 0; h2 { @@ -71,7 +71,7 @@ button { line-height: 1.6; - letter-spacing: 0.1em; + letter-spacing: 0.15em; } } From 024637c65d470df4d4b6be492a01a89a39d83521 Mon Sep 17 00:00:00 2001 From: Mashy Date: Sun, 24 Nov 2019 10:49:57 +1000 Subject: [PATCH 48/97] disable store drag --- client/src/components/vbox.store.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/src/components/vbox.store.jsx b/client/src/components/vbox.store.jsx index 20a5a402..cc2e286b 100644 --- a/client/src/components/vbox.store.jsx +++ b/client/src/components/vbox.store.jsx @@ -46,8 +46,7 @@ function storeElement(props) { const vboxObject = shapes[v] ? shapes[v]() : v; const disabled = vbox.bits <= group; return ( -
); } From 734132974bf245bf72f0c3fff0919b35a40769bb Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 24 Nov 2019 22:17:06 +1100 Subject: [PATCH 61/97] info back --- client/assets/styles/vbox.less | 20 +- client/src/components/vbox.combos.jsx | 144 +++++++++ client/src/components/vbox.component.jsx | 6 +- client/src/components/vbox.info.jsx | 359 ++++++++--------------- 4 files changed, 275 insertions(+), 254 deletions(-) create mode 100644 client/src/components/vbox.combos.jsx diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 582899a0..963e16b4 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -3,12 +3,11 @@ grid-area: vbox; display: grid; grid-template-rows: 3fr 2fr; - grid-template-columns: 1fr 4fr 6fr min-content; // =\ + grid-template-columns: 1fr 4fr 6fr 17em; // =\ grid-template-areas: "store-hdr store info combos" "stash-hdr stash combiner combos"; margin-bottom: 1em; - line-height: 0; // immediate children > div { @@ -198,23 +197,6 @@ margin-left: 1em; grid-area: info; - display: grid; - grid-template-columns: 1fr min-content; - grid-template-areas: - "details combos"; - - .info-details { - grid-area: details; - display: grid; - grid-template-rows: 1fr min-content; - grid-template-areas: - "item" - "combiner"; - - .info-item { - grid-area: item; - } - } } .combiner { diff --git a/client/src/components/vbox.combos.jsx b/client/src/components/vbox.combos.jsx new file mode 100644 index 00000000..c822af1c --- /dev/null +++ b/client/src/components/vbox.combos.jsx @@ -0,0 +1,144 @@ +const preact = require('preact'); +const { connect } = require('preact-redux'); +const reactStringReplace = require('react-string-replace'); +const countBy = require('lodash/countBy'); + +const specThresholds = require('./vbox.info.thresholds'); +const { INFO } = require('./../constants'); +const { convertItem, removeTier } = require('../utils'); +const { tutorialStage } = require('../tutorial.utils'); +const shapes = require('./shapes'); + +const actions = require('../actions'); + +const addState = connect( + function receiveState(state) { + const { + ws, + info, + itemInfo, + itemUnequip, + instance, + player, + account, + tutorial, + vboxSelected, + } = state; + + function sendVboxAccept(group, index) { + document.activeElement.blur(); + return ws.sendVboxAccept(instance.id, group, index); + } + + function sendVboxCombine() { + return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); + } + + return { + ws, + info, + itemInfo, + itemUnequip, + instance, + player, + account, + tutorial, + vboxSelected, + sendVboxAccept, + sendVboxCombine, + }; + } +); + +function Combos(args) { + const { + // Variables that will change + info, + itemUnequip, + tutorial, + vboxHighlight, + vboxSelected, + // Static + player, // Only used for colour calcs which will be update if info changes + ws, + itemInfo, + instance, // Only used for instance id + // functions + sendVboxAccept, + sendVboxCombine, + setTutorialNull, + } = args; + const { comboItem } = this.state; + + const { vbox } = player; + const { stashSelect, storeSelect } = vboxSelected; + + const vboxCombo = () => { + if (!(vboxHighlight && vboxHighlight.length === 0)) return false; + // The selected items can't be combined with additional items therefore valid combo + const stashItems = stashSelect.map(j => vbox.bound[j]); + const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); + const selectedItems = stashItems.concat(shopItems); + const combinerCount = countBy(selectedItems, co => co); + + const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { + if (!combo.components.includes(c)) return false; + const comboCount = countBy(combo.components, co => co); + if (combinerCount[c] > comboCount[c]) return false; + return true; + })); + return comboItemObj.item; + }; + + const combinerCombo = vboxCombo(); + const checkVboxInfo = () => { + if (combinerCombo) return combinerCombo; + const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i]))); + if (stashBase > -1) return vbox.bound[stashBase]; + const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]]))); + if (storeBase) return vbox.free[storeBase[0]][storeBase[1]]; + if (stashSelect.length > 0) return vbox.bound[stashSelect[0]]; + if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]]; + return false; + }; + let vboxInfo = false; + if (itemUnequip.length) [, vboxInfo] = itemUnequip; + else if (stashSelect.length > 0 || storeSelect.length > 0) vboxInfo = checkVboxInfo(); + + if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; + if (!info && !vboxInfo) return false; + const comboInfo = vboxInfo || info; + const vboxCombos = itemInfo.combos.filter(c => c.components.includes(comboInfo)); + if (vboxCombos.length > 6 || vboxCombos.length === 0) return false; + + const comboTable = vboxCombos.map((c, i) => { + const mouseOver = e => { + e.stopPropagation(); + this.setState({ comboItem: c.item }); + }; + const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) + ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, +
{convertItem(c.components[2])}
] + : c.components.map((u, j) =>
{convertItem(u)}
); + return ( +
+
+ {convertItem(c.item)} +
+ {componentTable} +
+ ); + }); + const comboList = comboTable.length > 0 ?
{comboTable}
: false; + return ( +
+
+

COMBOS

+ Combine colours and items. +
+ {comboList} +
+ ); +} + +module.exports = addState(Combos); diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index bf5391aa..2f808f08 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -252,7 +252,10 @@ class Vbox extends preact.Component { setInfo = {setInfo} setVboxSelected = {setVboxSelected} /> -
+ -
); } diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index f8ea6157..3936260d 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -61,255 +61,148 @@ const addState = connect( } ); -class InfoComponent extends preact.Component { - shouldComponentUpdate(newProps, newState) { - if (newProps.info !== this.props.info) return true; - if (newProps.itemUnequip !== this.props.itemUnequip) return true; - if (newProps.tutorial !== this.props.tutorial) return true; - if (newProps.vboxHighlight !== this.props.vboxHighlight) return true; - if (newProps.vboxSelected !== this.props.vboxSelected) return true; - if (newState.comboItem !== this.state.comboItem) return true; +function Info(args) { + const { + // Variables that will change + info, + itemUnequip, + tutorial, + vboxHighlight, + vboxSelected, + // Static + player, // Only used for colour calcs which will be update if info changes + ws, + itemInfo, + instance, // Only used for instance id + // functions + sendVboxAccept, + sendVboxCombine, + setTutorialNull, + } = args; + const { comboItem } = this.state; + const { vbox } = player; + const { stashSelect, storeSelect } = vboxSelected; + + const vboxCombo = () => { + if (!(vboxHighlight && vboxHighlight.length === 0)) return false; + // The selected items can't be combined with additional items therefore valid combo + const stashItems = stashSelect.map(j => vbox.bound[j]); + const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); + const selectedItems = stashItems.concat(shopItems); + const combinerCount = countBy(selectedItems, co => co); + + const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { + if (!combo.components.includes(c)) return false; + const comboCount = countBy(combo.components, co => co); + if (combinerCount[c] > comboCount[c]) return false; + return true; + })); + return comboItemObj.item; + }; + + const combinerCombo = vboxCombo(); + const checkVboxInfo = () => { + if (combinerCombo) return combinerCombo; + const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i]))); + if (stashBase > -1) return vbox.bound[stashBase]; + const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]]))); + if (storeBase) return vbox.free[storeBase[0]][storeBase[1]]; + if (stashSelect.length > 0) return vbox.bound[stashSelect[0]]; + if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]]; return false; + }; + let vboxInfo = false; + if (itemUnequip.length) [, vboxInfo] = itemUnequip; + else if (stashSelect.length > 0 || storeSelect.length > 0) vboxInfo = checkVboxInfo(); + + if (tutorial) { + const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance); + if (tutorialStageInfo) return tutorialStageInfo; } - componentDidUpdate(prevProps) { - // Catch case where mouse events don't properly clear state and info changed - if (prevProps.info !== this.props.info && this.state.comboItem) this.setState({ comboItem: null }); - } - - render(args) { - const { - // Variables that will change - info, - itemUnequip, - tutorial, - vboxHighlight, - vboxSelected, - // Static - player, // Only used for colour calcs which will be update if info changes - ws, - itemInfo, - instance, // Only used for instance id - // functions - sendVboxAccept, - sendVboxCombine, - setTutorialNull, - } = args; - const { comboItem } = this.state; - - const { vbox } = player; - const { stashSelect, storeSelect } = vboxSelected; - - const vboxCombo = () => { - if (!(vboxHighlight && vboxHighlight.length === 0)) return false; - // The selected items can't be combined with additional items therefore valid combo - const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); - const selectedItems = stashItems.concat(shopItems); - const combinerCount = countBy(selectedItems, co => co); - - const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { - if (!combo.components.includes(c)) return false; - const comboCount = countBy(combo.components, co => co); - if (combinerCount[c] > comboCount[c]) return false; - return true; - })); - return comboItemObj.item; + function genItemInfo(item) { + const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item]; + const isSkill = fullInfo.skill; + const isSpec = fullInfo.spec; + const itemDescription = () => { + const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/; + const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]()); + return
{reactStringReplace(infoDescription, '\n', () =>
)}
; }; + if (isSkill || isSpec) { + let infoName = fullInfo.item; + while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+'); - const combinerCombo = vboxCombo(); - const checkVboxInfo = () => { - if (combinerCombo) return combinerCombo; - const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i]))); - if (stashBase > -1) return vbox.bound[stashBase]; - const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]]))); - if (storeBase) return vbox.free[storeBase[0]][storeBase[1]]; - if (stashSelect.length > 0) return vbox.bound[stashSelect[0]]; - if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]]; - return false; - }; - let vboxInfo = false; - if (itemUnequip.length) [, vboxInfo] = itemUnequip; - else if (stashSelect.length > 0 || storeSelect.length > 0) vboxInfo = checkVboxInfo(); + const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item)); - function Info() { - if (tutorial) { - const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance); - if (tutorialStageInfo) return tutorialStageInfo; + let itemSourceInfo = itemSource.length && !isSpec + ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` + : false; + + let header = null; + if (!itemSource.length) header = isSkill ?

SKILL

:

SPEC

; + if (itemSourceInfo) { + while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+'); + const itemRegEx = /(Red|Blue|Green)/; + itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); } - function genItemInfo(item) { - const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item]; - const isSkill = fullInfo.skill; - const isSpec = fullInfo.spec; - const itemDescription = () => { - const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/; - const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]()); - return
{reactStringReplace(infoDescription, '\n', () =>
)}
; - }; - if (isSkill || isSpec) { - let infoName = fullInfo.item; - while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+'); + const cooldown = isSkill && fullInfo.cooldown ?
{fullInfo.cooldown} Turn delay
: null; - const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item)); + const speed = isSkill + ?
Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
+ : null; - let itemSourceInfo = itemSource.length && !isSpec - ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` - : false; + const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null; - let header = null; - if (!itemSource.length) header = isSkill ?

SKILL

:

SPEC

; - if (itemSourceInfo) { - while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+'); - const itemRegEx = /(Red|Blue|Green)/; - itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); - } - - const cooldown = isSkill && fullInfo.cooldown ?
{fullInfo.cooldown} Turn delay
: null; - - const speed = isSkill - ?
Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
- : null; - - const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null; - - return ( -
-

{infoName}

- {header} - {itemSourceInfo} - {cooldown} - {itemDescription()} - {speed} - {thresholds} -
- ); - } - return ( -
-

{fullInfo.item}

- {itemDescription()} -
- ); - } - const stateFullInfo = comboItem || vboxInfo; - if (stateFullInfo) return genItemInfo(stateFullInfo); - if (!info) return false; - if (info.includes('constructName')) { - return ( -
-

{info.replace('constructName ', '')}

-

This is the name of your construct.
- Names are randomly generated and are purely cosmetic.
- You can change change your construct name in the RESHAPE tab outside of games. -

-
- ); - } - - if (info.includes('constructAvatar')) { - return ( -
-

{info.replace('constructAvatar ', '')}

-

This is your construct avatar.
- Avatars are randomly generated and are purely cosmetic.
- You can change your construct avatar in the RESHAPE tab outside of games. -

-
- ); - } - - return genItemInfo(info); + return ( +
+

{infoName}

+ {header} + {itemSourceInfo} + {cooldown} + {itemDescription()} + {speed} + {thresholds} +
+ ); } - - const Combos = () => { - if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; - if (!info && !vboxInfo) return false; - const comboInfo = vboxInfo || info; - const vboxCombos = itemInfo.combos.filter(c => c.components.includes(comboInfo)); - if (vboxCombos.length > 6 || vboxCombos.length === 0) return false; - - const comboTable = vboxCombos.map((c, i) => { - const mouseOver = e => { - e.stopPropagation(); - this.setState({ comboItem: c.item }); - }; - const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) - ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, -
{convertItem(c.components[2])}
] - : c.components.map((u, j) =>
{convertItem(u)}
); - return ( -
-
- {convertItem(c.item)} -
- {componentTable} -
- ); - }); - const comboList = comboTable.length > 0 ?
{comboTable}
: false; - return ( -
-
-

COMBOS

- Combine colours and items. -
- {comboList} -
- ); - }; - - const Combiner = () => { - if (comboItem) return false; - function vboxBuySelected() { - if (!(storeSelect.length === 1 && stashSelect.length === 0)) return false; - document.activeElement.blur(); - sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); - return true; - } - let text = ''; - let mouseEvent = false; - if (combinerCombo) { - const combinerComboText = combinerCombo.replace('Plus', '+'); - let bits = 0; - storeSelect.forEach(item => bits += item[0] + 1); - text = bits - ? `Buy ${combinerComboText} ${bits}b` - : `Combine ${combinerComboText}`; - if (vbox.bits >= bits) mouseEvent = sendVboxCombine; - } else if (stashSelect.length === 0 && storeSelect.length === 1) { - const item = storeSelect[0]; - text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`; - mouseEvent = vboxBuySelected; - } else { - return false; - } - return ( -
- -
- ); - }; - return ( -
-
this.setState({ comboItem: null })}> -
- - -
-
- +
+

{fullInfo.item}

+ {itemDescription()}
); } + const stateFullInfo = comboItem || vboxInfo; + if (stateFullInfo) return genItemInfo(stateFullInfo); + if (!info) return false; + if (info.includes('constructName')) { + return ( +
+

{info.replace('constructName ', '')}

+

This is the name of your construct.
+ Names are randomly generated and are purely cosmetic.
+ You can change change your construct name in the RESHAPE tab outside of games. +

+
+ ); + } + + if (info.includes('constructAvatar')) { + return ( +
+

{info.replace('constructAvatar ', '')}

+

This is your construct avatar.
+ Avatars are randomly generated and are purely cosmetic.
+ You can change your construct avatar in the RESHAPE tab outside of games. +

+
+ ); + } + + return genItemInfo(info); } -module.exports = addState(InfoComponent); +module.exports = addState(Info); From bbdc89ed7ffc898f66bc6ecf0de94221e0071128 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 24 Nov 2019 22:19:39 +1100 Subject: [PATCH 62/97] remove fns --- client/src/components/vbox.info.jsx | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index 3936260d..452f268d 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -25,15 +25,6 @@ const addState = connect( vboxSelected, } = state; - function sendVboxAccept(group, index) { - document.activeElement.blur(); - return ws.sendVboxAccept(instance.id, group, index); - } - - function sendVboxCombine() { - return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); - } - return { ws, info, @@ -44,8 +35,6 @@ const addState = connect( account, tutorial, vboxSelected, - sendVboxAccept, - sendVboxCombine, }; }, @@ -75,8 +64,6 @@ function Info(args) { itemInfo, instance, // Only used for instance id // functions - sendVboxAccept, - sendVboxCombine, setTutorialNull, } = args; const { comboItem } = this.state; From 046c065bbdf4cb34084f9b9a9f1ddff86e883da0 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 24 Nov 2019 22:23:22 +1100 Subject: [PATCH 63/97] big btn --- client/assets/styles/vbox.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 963e16b4..890c1431 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -201,7 +201,8 @@ .combiner { grid-area: combiner; - align-self: flex-end; + // align-self: flex-end; + height: 100%; margin: 0 0.5em; line-height: 1.3; font-size: 1.25em; From 8b7003fb324de98015479e93190422909be1a8bb Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 24 Nov 2019 22:41:14 +1100 Subject: [PATCH 64/97] mobile styles --- client/assets/styles/player.less | 1 + client/assets/styles/styles.mobile.less | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/client/assets/styles/player.less b/client/assets/styles/player.less index d731e418..bdcf2477 100644 --- a/client/assets/styles/player.less +++ b/client/assets/styles/player.less @@ -42,6 +42,7 @@ .msg { grid-area: msg; + text-transform: uppercase; color: @white; } diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index dffb0b82..fa246be1 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -42,6 +42,18 @@ padding: 0.25em; } + .info { + display: none; + } + + .combos { + display: none; + } + + .combiner { + margin: 0; + } + .stash { border: 0; border-top: 0.1em solid @gray; From 4df4f3a785ffb55eda7cb77c035ef47b530fef43 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 24 Nov 2019 23:08:35 +1100 Subject: [PATCH 65/97] fix remaining px borders --- client/assets/styles/account.less | 2 +- client/assets/styles/controls.less | 6 +- client/assets/styles/instance.less | 2 +- client/assets/styles/menu.less | 2 +- client/assets/styles/styles.mobile.less | 179 ++++++++++++------------ client/assets/styles/vbox.less | 16 +-- 6 files changed, 102 insertions(+), 105 deletions(-) diff --git a/client/assets/styles/account.less b/client/assets/styles/account.less index a52e6e5b..c920c8dc 100644 --- a/client/assets/styles/account.less +++ b/client/assets/styles/account.less @@ -44,7 +44,7 @@ } &[disabled] { - border: 1px solid @yellow; + border: 0.1em solid @yellow; color: @yellow; background: black; } diff --git a/client/assets/styles/controls.less b/client/assets/styles/controls.less index 9fb1cd13..a5938475 100644 --- a/client/assets/styles/controls.less +++ b/client/assets/styles/controls.less @@ -150,13 +150,13 @@ aside { &:hover { color: @red; border-color: @red; - border: 2px solid @red; + border: 0.1em solid @red; }; &:active, &.confirming { background: @red; color: black; - border: 2px solid @red; + border: 0.1em solid @red; } } @@ -164,7 +164,7 @@ aside { &:active, &.confirming { background: @gray-hover; color: black; - border: 2px solid @gray-hover; + border: 0.1em solid @gray-hover; } } diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index fa1e1485..52ad8fea 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -40,7 +40,7 @@ "stats "; /*padding: 0.5em;*/ - border: 2px solid #222; + border: 0.1em solid #222; border-left-width: 0; &:first-child { margin-left: 0; diff --git a/client/assets/styles/menu.less b/client/assets/styles/menu.less index 1ce06f73..e197781e 100644 --- a/client/assets/styles/menu.less +++ b/client/assets/styles/menu.less @@ -74,7 +74,7 @@ button { flex: 1; border-top: 0; - border: 2px solid #222; + border: 0.1em solid #222; &:not(:last-child) { border-right: 0; } diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index fa246be1..9fa19971 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -20,99 +20,10 @@ } } - .info { - display: none; - .combos { - display: none; - } - } svg { stroke-width: 1.25em; } - .vbox { - grid-template-rows: min-content min-content 1fr; - grid-template-columns: min-content 1fr min-content 1fr; - grid-template-areas: - "store-hdr store-hdr stash-hdr stash-hdr" - "store store stash stash" - "store store combiner combiner"; - - > div { - padding: 0.25em; - } - - .info { - display: none; - } - - .combos { - display: none; - } - - .combiner { - margin: 0; - } - - .stash { - border: 0; - border-top: 0.1em solid @gray; - border-right: 0.1em solid @gray; - border-bottom: 0.1em solid @gray; - } - - .stash-hdr { - border: 0; - border-left: 0.1em solid @gray; - border-right: 0.1em solid @gray; - - display: grid; - grid-template-rows: min-content min-content; - grid-template-columns: 1fr 1fr; - - h3 { - margin: 0; - } - } - - .store { - border: 0; - border-top: 0.1em solid @gray; - border-bottom: 0.1em solid @gray; - border-right: 0.1em solid @gray; - } - - .store-hdr { - display: grid; - grid-template-columns: min-content min-content 1fr; - - > * { - margin-right: 1em; - } - - grid-template-areas: - "hdr bits btn"; - - h1 { - grid-area: hdr; - margin-bottom: 0.25em; - } - - .bits { - grid-area: bits; - } - - button { - grid-area: btn; - } - } - - .store-hdr, .stash-hdr { - button { - margin: 0; - } - } - } } .game { @@ -286,7 +197,7 @@ grid-template-columns: repeat(2, 1fr); button:not(:last-child) { - border: 2px solid #222; + border: 0.1em solid #222; } button.logo { @@ -324,4 +235,90 @@ grid-template-columns: 1fr; } } -} \ No newline at end of file +} + +@media (max-width: 600px) { + .vbox { + grid-template-rows: min-content min-content 1fr; + grid-template-columns: min-content 1fr min-content 1fr; + grid-template-areas: + "store-hdr store-hdr stash-hdr stash-hdr" + "store store stash stash" + "store store combiner combiner"; + + > div { + padding: 0.25em; + } + + .info { + display: none; + } + + .combos { + display: none; + } + + .combiner { + margin: 0; + } + + .stash { + border: 0; + border-top: 0.1em solid @gray; + border-right: 0.1em solid @gray; + border-bottom: 0.1em solid @gray; + } + + .stash-hdr { + border: 0; + border-left: 0.1em solid @gray; + border-right: 0.1em solid @gray; + + display: grid; + grid-template-rows: min-content min-content; + grid-template-columns: 1fr 1fr; + + h3 { + margin: 0; + } + } + + .store { + border: 0; + border-top: 0.1em solid @gray; + border-bottom: 0.1em solid @gray; + border-right: 0.1em solid @gray; + } + + .store-hdr { + display: grid; + grid-template-columns: min-content min-content 1fr; + + > * { + margin-right: 1em; + } + + grid-template-areas: + "hdr bits btn"; + + h1 { + grid-area: hdr; + margin-bottom: 0.25em; + } + + .bits { + grid-area: bits; + } + + button { + grid-area: btn; + } + } + + .store-hdr, .stash-hdr { + button { + margin: 0; + } + } + } +} diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 890c1431..88ec13fc 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -116,7 +116,7 @@ &, &:hover, &:active { background: @red; color: black; - border: 2px solid black; + border: 0.1em solid black; } } svg { @@ -207,9 +207,9 @@ line-height: 1.3; font-size: 1.25em; letter-spacing: 0.1em; - border: 2px solid @gray-exists; + border: 0.1em solid @gray-exists; &:hover { - border: 2px solid @gray-hover; + border: 0.1em solid @gray-hover; } } @@ -273,8 +273,8 @@ } .item { - border-top: 2px solid #222; - border-bottom: 2px solid #222; + border-top: 0.1em solid #222; + border-bottom: 0.1em solid #222; flex: 1; grid-area: item; font-weight: bold; @@ -285,15 +285,15 @@ div { - border-left: 2px solid #222; - border-right: 2px solid #222; + border-left: 0.1em solid #222; + border-right: 0.1em solid #222; height: 1.75em; width: 7.5em; svg { vertical-align: middle; } &:last-child { - border-bottom: 2px solid #222; + border-bottom: 0.1em solid #222; } } } From 8a2e8dbab1f2d1df75c8ca6e4c63611caa742a49 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 24 Nov 2019 23:34:43 +1100 Subject: [PATCH 66/97] that'll do --- client/assets/styles/styles.mobile.less | 2 +- client/assets/styles/vbox.less | 2 +- client/src/components/mnml.jsx | 2 +- client/src/components/vbox.combos.jsx | 3 --- client/src/components/vbox.info.thresholds.jsx | 1 + 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index 9fa19971..0c80a7bd 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -155,7 +155,7 @@ // portrait menu or small size vertical in landscape -@media (max-width: 550px) { +@media (max-width: 550px) and (max-height: 800px) { #mnml { grid-template-columns: 1fr; grid-template-rows: 1fr; diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 88ec13fc..5cd15f33 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -3,7 +3,7 @@ grid-area: vbox; display: grid; grid-template-rows: 3fr 2fr; - grid-template-columns: 1fr 4fr 6fr 17em; // =\ + grid-template-columns: 1fr 4fr 6fr minmax(min-content, 17em); // =\ grid-template-areas: "store-hdr store info combos" "stash-hdr stash combiner combos"; diff --git a/client/src/components/mnml.jsx b/client/src/components/mnml.jsx index 7a5e94e0..cb3c6991 100644 --- a/client/src/components/mnml.jsx +++ b/client/src/components/mnml.jsx @@ -15,7 +15,7 @@ function Mnml(args) { instance, } = args; - const rotateClass = (game || instance) && window.innerWidth < window.innerHeight + const rotateClass = (game || instance) && window.innerHeight < 600 && window.innerWidth < window.innerHeight ? 'show' : ''; diff --git a/client/src/components/vbox.combos.jsx b/client/src/components/vbox.combos.jsx index c822af1c..410252d0 100644 --- a/client/src/components/vbox.combos.jsx +++ b/client/src/components/vbox.combos.jsx @@ -3,10 +3,7 @@ const { connect } = require('preact-redux'); const reactStringReplace = require('react-string-replace'); const countBy = require('lodash/countBy'); -const specThresholds = require('./vbox.info.thresholds'); -const { INFO } = require('./../constants'); const { convertItem, removeTier } = require('../utils'); -const { tutorialStage } = require('../tutorial.utils'); const shapes = require('./shapes'); const actions = require('../actions'); diff --git a/client/src/components/vbox.info.thresholds.jsx b/client/src/components/vbox.info.thresholds.jsx index 6785380e..9f259f0e 100644 --- a/client/src/components/vbox.info.thresholds.jsx +++ b/client/src/components/vbox.info.thresholds.jsx @@ -3,6 +3,7 @@ const range = require('lodash/range'); const shapes = require('./shapes'); function specThresholds(player, fullInfo, info) { + if (!info) return false; let red = 0; let blue = 0; let green = 0; From ec10d7f890977b114c0264d80467eb28d17b44e5 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 24 Nov 2019 23:38:31 +1100 Subject: [PATCH 67/97] fix rotate size --- client/assets/styles/vbox.less | 4 ++-- client/src/components/mnml.jsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 5cd15f33..2e3bbde8 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -2,8 +2,8 @@ align-content: space-between; grid-area: vbox; display: grid; - grid-template-rows: 3fr 2fr; - grid-template-columns: 1fr 4fr 6fr minmax(min-content, 17em); // =\ + grid-template-rows: 3fr minmax(min-content, 2fr); + grid-template-columns: 1fr 4fr 6fr 17em; // =\ grid-template-areas: "store-hdr store info combos" "stash-hdr stash combiner combos"; diff --git a/client/src/components/mnml.jsx b/client/src/components/mnml.jsx index cb3c6991..d1a632ce 100644 --- a/client/src/components/mnml.jsx +++ b/client/src/components/mnml.jsx @@ -15,7 +15,7 @@ function Mnml(args) { instance, } = args; - const rotateClass = (game || instance) && window.innerHeight < 600 && window.innerWidth < window.innerHeight + const rotateClass = (game || instance) && window.innerHeight < 900 && window.innerWidth < window.innerHeight ? 'show' : ''; From 490216fb01cf72d063e21ec2e2f1fa3f25e96130 Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 25 Nov 2019 16:54:51 +1000 Subject: [PATCH 68/97] refactoring FeelsAmazingMan --- client/assets/styles/vbox.less | 4 +- client/src/actions.jsx | 3 + client/src/app.jsx | 1 - client/src/components/vbox.combiner.jsx | 116 ++++------------- client/src/components/vbox.combos.jsx | 106 ++------------- client/src/components/vbox.component.jsx | 127 +++++++----------- client/src/components/vbox.info.jsx | 158 ++--------------------- client/src/components/vbox.stash.jsx | 29 ++--- client/src/components/vbox.utils.jsx | 128 ++++++++++++++++++ client/src/events.jsx | 13 ++ client/src/reducers.jsx | 3 + client/src/socket.jsx | 7 + client/src/tutorial.utils.jsx | 8 +- 13 files changed, 272 insertions(+), 431 deletions(-) create mode 100644 client/src/components/vbox.utils.jsx diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 2e3bbde8..b6bff59f 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -3,7 +3,7 @@ grid-area: vbox; display: grid; grid-template-rows: 3fr minmax(min-content, 2fr); - grid-template-columns: 1fr 4fr 6fr 17em; // =\ + grid-template-columns: 1fr 4fr 6fr min-content; grid-template-areas: "store-hdr store info combos" "stash-hdr stash combiner combos"; @@ -217,7 +217,9 @@ display: grid; grid-area: combos; margin-left: 0.5em; + margin-right: 0.5em; grid-template-rows: min-content min-content; + width: 15.5em; grid-template-areas: "comboHeader" "comboList"; diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 0c1456af..ab644966 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -48,5 +48,8 @@ export const setTutorial = value => ({ type: 'SET_TUTORIAL', value }); export const setTutorialGame = value => ({ type: 'SET_TUTORIAL_GAME', value }); export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value }); +export const setVboxCombiner = value => ({ type: 'SET_VBOX_COMBINER', value }); +export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value }); +export const setVboxInfo = value => ({ type: 'SET_VBOX_INFO', value }); export const setWs = value => ({ type: 'SET_WS', value }); diff --git a/client/src/app.jsx b/client/src/app.jsx index 0d668980..1599c1ab 100644 --- a/client/src/app.jsx +++ b/client/src/app.jsx @@ -8,7 +8,6 @@ const { createStore, combineReducers } = require('redux'); const { StripeProvider } = require('react-stripe-elements'); const reducers = require('./reducers'); -const actions = require('./actions'); const setupKeys = require('./keyboard'); const createSocket = require('./socket'); const registerEvents = require('./events'); diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index 93051a33..9fef580e 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -1,104 +1,44 @@ const preact = require('preact'); -const { connect } = require('preact-redux'); -const countBy = require('lodash/countBy'); - -const addState = connect( - function receiveState(state) { - const { - ws, - itemInfo, - instance, - player, - vboxSelected, - } = state; - - function sendVboxAccept(group, index) { - document.activeElement.blur(); - return ws.sendVboxAccept(instance.id, group, index); - } - - function sendVboxCombine() { - return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); - } - - return { - itemInfo, - player, - vboxSelected, - sendVboxAccept, - sendVboxCombine, - }; - } -); function Combiner(args) { const { - // Variables that will change - vboxHighlight, + vbox, + vboxCombiner, vboxSelected, - // Static - player, - itemInfo, - // functions - sendVboxAccept, + vboxBuySelected, sendVboxCombine, } = args; - const { vbox } = player; const { stashSelect, storeSelect } = vboxSelected; - const vboxCombo = () => { - if (!(vboxHighlight && vboxHighlight.length === 0)) return false; - // The selected items can't be combined with additional items therefore valid combo - const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); - const selectedItems = stashItems.concat(shopItems); - const combinerCount = countBy(selectedItems, co => co); - - const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { - if (!combo.components.includes(c)) return false; - const comboCount = countBy(combo.components, co => co); - if (combinerCount[c] > comboCount[c]) return false; - return true; - })); - return comboItemObj.item; - }; - - const combinerCombo = vboxCombo(); - - function vboxBuySelected() { - if (!(storeSelect.length === 1 && stashSelect.length === 0)) return false; - document.activeElement.blur(); - sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); - return true; - } - let text = ''; - let mouseEvent = false; - if (combinerCombo) { - const combinerComboText = combinerCombo.replace('Plus', '+'); + if (vboxCombiner) { + const combinerComboText = vboxCombiner.replace('Plus', '+'); let bits = 0; storeSelect.forEach(item => bits += item[0] + 1); - text = bits - ? `Buy ${combinerComboText} ${bits}b` - : `Combine ${combinerComboText}`; - if (vbox.bits >= bits) mouseEvent = sendVboxCombine; - } else if (stashSelect.length === 0 && storeSelect.length === 1) { - const item = storeSelect[0]; - text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`; - mouseEvent = vboxBuySelected; - } else { - return false; + return ( + + ); } - return ( - - ); + if (stashSelect.length === 0 && storeSelect.length === 1) { + const item = storeSelect[0]; + return ( + + ); + } + + return false; } -module.exports = addState(Combiner); +module.exports = Combiner; diff --git a/client/src/components/vbox.combos.jsx b/client/src/components/vbox.combos.jsx index 410252d0..f988064c 100644 --- a/client/src/components/vbox.combos.jsx +++ b/client/src/components/vbox.combos.jsx @@ -1,112 +1,27 @@ const preact = require('preact'); const { connect } = require('preact-redux'); -const reactStringReplace = require('react-string-replace'); -const countBy = require('lodash/countBy'); -const { convertItem, removeTier } = require('../utils'); -const shapes = require('./shapes'); +const { convertItem } = require('../utils'); -const actions = require('../actions'); - -const addState = connect( - function receiveState(state) { - const { - ws, - info, - itemInfo, - itemUnequip, - instance, - player, - account, - tutorial, - vboxSelected, - } = state; - - function sendVboxAccept(group, index) { - document.activeElement.blur(); - return ws.sendVboxAccept(instance.id, group, index); - } - - function sendVboxCombine() { - return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); - } - - return { - ws, - info, - itemInfo, - itemUnequip, - instance, - player, - account, - tutorial, - vboxSelected, - sendVboxAccept, - sendVboxCombine, - }; - } -); +const addState = connect(({ info, itemInfo, instance, tutorial, vboxInfo }) => + ({ info, itemInfo, instance, tutorial, vboxInfo })); function Combos(args) { const { // Variables that will change info, - itemUnequip, tutorial, - vboxHighlight, - vboxSelected, + vboxInfo, // Static - player, // Only used for colour calcs which will be update if info changes - ws, itemInfo, - instance, // Only used for instance id + instance, // Only used for tutorial check // functions - sendVboxAccept, - sendVboxCombine, - setTutorialNull, } = args; - const { comboItem } = this.state; - - const { vbox } = player; - const { stashSelect, storeSelect } = vboxSelected; - - const vboxCombo = () => { - if (!(vboxHighlight && vboxHighlight.length === 0)) return false; - // The selected items can't be combined with additional items therefore valid combo - const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); - const selectedItems = stashItems.concat(shopItems); - const combinerCount = countBy(selectedItems, co => co); - - const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { - if (!combo.components.includes(c)) return false; - const comboCount = countBy(combo.components, co => co); - if (combinerCount[c] > comboCount[c]) return false; - return true; - })); - return comboItemObj.item; - }; - - const combinerCombo = vboxCombo(); - const checkVboxInfo = () => { - if (combinerCombo) return combinerCombo; - const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i]))); - if (stashBase > -1) return vbox.bound[stashBase]; - const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]]))); - if (storeBase) return vbox.free[storeBase[0]][storeBase[1]]; - if (stashSelect.length > 0) return vbox.bound[stashSelect[0]]; - if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]]; - return false; - }; - let vboxInfo = false; - if (itemUnequip.length) [, vboxInfo] = itemUnequip; - else if (stashSelect.length > 0 || storeSelect.length > 0) vboxInfo = checkVboxInfo(); if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; - if (!info && !vboxInfo) return false; - const comboInfo = vboxInfo || info; - const vboxCombos = itemInfo.combos.filter(c => c.components.includes(comboInfo)); - if (vboxCombos.length > 6 || vboxCombos.length === 0) return false; + + const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info)); + if (vboxCombos.length > 6 || vboxCombos.length === 0) return
; const comboTable = vboxCombos.map((c, i) => { const mouseOver = e => { @@ -126,14 +41,15 @@ function Combos(args) {
); }); - const comboList = comboTable.length > 0 ?
{comboTable}
: false; return (

COMBOS

Combine colours and items.
- {comboList} +
+ {comboTable} +
); } diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 2f808f08..e0eb4307 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -1,7 +1,5 @@ const preact = require('preact'); const { connect } = require('preact-redux'); -const countBy = require('lodash/countBy'); -const forEach = require('lodash/forEach'); const actions = require('../actions'); @@ -11,17 +9,23 @@ const StoreElement = require('./vbox.store'); const Combiner = require('./vbox.combiner'); const Combos = require('./vbox.combos'); +const { setVboxState } = require('./vbox.utils'); + const addState = connect( function receiveState(state) { const { ws, instance, player, - vboxSelected, info, itemInfo, itemUnequip, tutorial, + + vboxCombiner, + vboxHighlight, + vboxInfo, + vboxSelected, } = state; function sendVboxDiscard() { @@ -29,10 +33,15 @@ const addState = connect( } function sendVboxAccept(group, index) { + if (!(vboxSelected.storeSelect.length === 1 && vboxSelected.stashSelect.length === 0)) return false; document.activeElement.blur(); return ws.sendVboxAccept(instance.id, group, index); } + function sendVboxCombine() { + return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); + } + function sendVboxReclaim(i) { return ws.sendVboxReclaim(instance.id, i); } @@ -42,17 +51,23 @@ const addState = connect( } return { + player, instance, info, - player, - sendVboxAccept, - sendVboxDiscard, - sendVboxReclaim, - vboxSelected, itemInfo, itemUnequip, sendItemUnequip, tutorial, + + vboxCombiner, + vboxHighlight, + vboxInfo, + vboxSelected, + + sendVboxAccept, + sendVboxCombine, + sendVboxDiscard, + sendVboxReclaim, }; }, @@ -61,55 +76,26 @@ const addState = connect( return dispatch(actions.setInfo(item)); } - function setVboxSelected(v) { + function dispatchVboxSelect(v, state) { + setVboxState(dispatch, v, state); dispatch(actions.setItemUnequip([])); - dispatch(actions.setVboxSelected(v)); return dispatch(actions.setVboxSelected(v)); } return { + dispatchVboxSelect, setInfo, - setVboxSelected, }; } ); -function validVboxSelect(vbox, itemInfo, storeSelect, stashSelect) { - if (storeSelect.length === 0 && stashSelect.length === 0) return false; - - const validSelects = []; - - const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); - - const selectedItems = stashItems.concat(shopItems); - const itemCount = countBy(selectedItems, co => co); - - itemInfo.combos.forEach(combo => { - const comboCount = countBy(combo.components, co => co); - const buyCount = countBy(combo.components, co => co); - const valid = selectedItems.every(c => { - if (!combo.components.includes(c)) return false; - if (itemCount[c] > comboCount[c]) return false; - buyCount[c] -= 1; - return true; - }); - if (valid) { - forEach(buyCount, (value, key) => { - if (value > 0 && !validSelects.includes(key)) validSelects.push(key); - }); - } - }); - - return validSelects; -} - class Vbox extends preact.Component { shouldComponentUpdate(newProps) { // Single variable props if (newProps.itemUnequip !== this.props.itemUnequip) return true; if (newProps.tutorial !== this.props.tutorial) return true; if (newProps.vboxSelected !== this.props.vboxSelected) return true; + if (newProps.vboxHighlight !== this.props.vboxHighlight) return true; if (newProps.player !== this.props.player) return true; if (newProps.instance !== this.props.instance) return true; return false; @@ -121,33 +107,33 @@ class Vbox extends preact.Component { itemUnequip, player, tutorial, - vboxSelected, instance, + vboxCombiner, + vboxHighlight, + vboxInfo, + vboxSelected, + // Static itemInfo, // Function Calls + dispatchVboxSelect, sendItemUnequip, sendVboxAccept, + sendVboxCombine, sendVboxDiscard, sendVboxReclaim, - setVboxSelected, setInfo, } = args; if (!player) return false; const { vbox } = player; const { storeSelect, stashSelect } = vboxSelected; - const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0; - function combinerChange(newStashSelect) { - return setVboxSelected({ storeSelect, stashSelect: newStashSelect }); - } + const setVboxSelected = v => dispatchVboxSelect(v, { itemInfo, itemUnequip, vbox }); + const clearVboxSelected = () => setVboxSelected({ storeSelect: [], stashSelect: [] }); + const vboxBuySelected = () => sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); - const vboxHighlight = validVboxSelect(vbox, itemInfo, storeSelect, stashSelect); - // - // VBOX - // function vboxHover(e, v) { if (v) { e.stopPropagation(); @@ -157,17 +143,6 @@ class Vbox extends preact.Component { return true; } - function clearVboxSelected() { - setVboxSelected({ storeSelect: [], stashSelect: [] }); - } - - function vboxBuySelected() { - if (!vboxSelecting) return false; - document.activeElement.blur(); - sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); - return true; - } - function storeHdr() { return (
@@ -233,37 +208,33 @@ class Vbox extends preact.Component { clearVboxSelected = {clearVboxSelected} setInfo = {setInfo} setVboxSelected = {setVboxSelected} - storeSelect = {storeSelect} stashSelect = {stashSelect} + storeSelect = {storeSelect} vbox = {vbox} vboxHighlight = {vboxHighlight} vboxHover = {vboxHover} /> - - + +
); } diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index 452f268d..80f32528 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -1,169 +1,33 @@ const preact = require('preact'); const { connect } = require('preact-redux'); -const reactStringReplace = require('react-string-replace'); -const countBy = require('lodash/countBy'); - -const specThresholds = require('./vbox.info.thresholds'); -const { INFO } = require('./../constants'); -const { convertItem, removeTier } = require('../utils'); const { tutorialStage } = require('../tutorial.utils'); -const shapes = require('./shapes'); +const { genItemInfo } = require('./vbox.utils'); -const actions = require('../actions'); - -const addState = connect( - function receiveState(state) { - const { - ws, - info, - itemInfo, - itemUnequip, - instance, - player, - account, - tutorial, - vboxSelected, - } = state; - - return { - ws, - info, - itemInfo, - itemUnequip, - instance, - player, - account, - tutorial, - vboxSelected, - }; - }, - - function receiveDispatch(dispatch) { - function setTutorialNull() { - dispatch(actions.setTutorial(null)); - } - - function setInfo(info) { - dispatch(actions.setInfo(info)); - } - return { setTutorialNull, setInfo }; - } -); +const addState = connect(({ info, player, tutorial, vboxInfo, ws, itemInfo, instance }) => + ({ info, player, tutorial, vboxInfo, ws, itemInfo, instance })); function Info(args) { const { // Variables that will change info, - itemUnequip, + player, tutorial, - vboxHighlight, - vboxSelected, + vboxInfo, // Static - player, // Only used for colour calcs which will be update if info changes ws, itemInfo, - instance, // Only used for instance id - // functions - setTutorialNull, + instance, } = args; - const { comboItem } = this.state; - - const { vbox } = player; - const { stashSelect, storeSelect } = vboxSelected; - - const vboxCombo = () => { - if (!(vboxHighlight && vboxHighlight.length === 0)) return false; - // The selected items can't be combined with additional items therefore valid combo - const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); - const selectedItems = stashItems.concat(shopItems); - const combinerCount = countBy(selectedItems, co => co); - - const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => { - if (!combo.components.includes(c)) return false; - const comboCount = countBy(combo.components, co => co); - if (combinerCount[c] > comboCount[c]) return false; - return true; - })); - return comboItemObj.item; - }; - - const combinerCombo = vboxCombo(); - const checkVboxInfo = () => { - if (combinerCombo) return combinerCombo; - const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i]))); - if (stashBase > -1) return vbox.bound[stashBase]; - const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]]))); - if (storeBase) return vbox.free[storeBase[0]][storeBase[1]]; - if (stashSelect.length > 0) return vbox.bound[stashSelect[0]]; - if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]]; - return false; - }; - let vboxInfo = false; - if (itemUnequip.length) [, vboxInfo] = itemUnequip; - else if (stashSelect.length > 0 || storeSelect.length > 0) vboxInfo = checkVboxInfo(); if (tutorial) { - const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance); + const tutorialStageInfo = tutorialStage(tutorial, ws, instance); if (tutorialStageInfo) return tutorialStageInfo; } - function genItemInfo(item) { - const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item]; - const isSkill = fullInfo.skill; - const isSpec = fullInfo.spec; - const itemDescription = () => { - const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/; - const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]()); - return
{reactStringReplace(infoDescription, '\n', () =>
)}
; - }; - if (isSkill || isSpec) { - let infoName = fullInfo.item; - while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+'); + // Prioritise the vbox info + if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); - const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item)); - - let itemSourceInfo = itemSource.length && !isSpec - ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` - : false; - - let header = null; - if (!itemSource.length) header = isSkill ?

SKILL

:

SPEC

; - if (itemSourceInfo) { - while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+'); - const itemRegEx = /(Red|Blue|Green)/; - itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); - } - - const cooldown = isSkill && fullInfo.cooldown ?
{fullInfo.cooldown} Turn delay
: null; - - const speed = isSkill - ?
Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
- : null; - - const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null; - - return ( -
-

{infoName}

- {header} - {itemSourceInfo} - {cooldown} - {itemDescription()} - {speed} - {thresholds} -
- ); - } - return ( -
-

{fullInfo.item}

- {itemDescription()} -
- ); - } - const stateFullInfo = comboItem || vboxInfo; - if (stateFullInfo) return genItemInfo(stateFullInfo); + // check normal info state if (!info) return false; if (info.includes('constructName')) { return ( @@ -189,7 +53,7 @@ function Info(args) { ); } - return genItemInfo(info); + return genItemInfo(info, itemInfo, player, info); } module.exports = addState(Info); diff --git a/client/src/components/vbox.stash.jsx b/client/src/components/vbox.stash.jsx index 18dd6b78..264a9f60 100644 --- a/client/src/components/vbox.stash.jsx +++ b/client/src/components/vbox.stash.jsx @@ -8,20 +8,20 @@ const { removeTier } = require('../utils'); function stashElement(props) { const { - combinerChange, itemUnequip, + sendItemUnequip, + setInfo, + setVboxSelected, + stashSelect, + storeSelect, vbox, vboxBuySelected, vboxHighlight, vboxHover, - vboxSelecting, - stashSelect, - - sendItemUnequip, - setInfo, - setVboxSelected, - } = props; + + const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0; + function stashClick(e) { e.stopPropagation(); if (itemUnequip.length) return sendItemUnequip(itemUnequip); @@ -46,12 +46,13 @@ function stashElement(props) { const notValidCombo = vboxHighlight && !vboxHighlight.includes(v); - function onClick(type) { + function onClick(type, e) { + e.stopPropagation(); const combinerContainsIndex = stashSelect.indexOf(i) > -1; // removing if (combinerContainsIndex) { if (type === 'click') { - return combinerChange(without(stashSelect, i)); + return setVboxSelected({ storeSelect, stashSelect: without(stashSelect, i) }); } return true; } @@ -61,9 +62,7 @@ function stashElement(props) { return setVboxSelected({ storeSelect: [], stashSelect: [i] }); } - stashSelect.push(i); - // if (stashSelect.length === 3) setInfo(comboItem.item); - return combinerChange(stashSelect); + return setVboxSelected({ storeSelect, stashSelect: [...stashSelect, i] }); } const highlighted = stashSelect.indexOf(i) > -1; @@ -79,14 +78,14 @@ function stashElement(props) { key={i} draggable='true' onDragStart={ev => { - onClick('drag'); + onClick('drag', ev); ev.dataTransfer.setData('text', ''); }}> diff --git a/client/src/components/vbox.utils.jsx b/client/src/components/vbox.utils.jsx new file mode 100644 index 00000000..6d934263 --- /dev/null +++ b/client/src/components/vbox.utils.jsx @@ -0,0 +1,128 @@ +const preact = require('preact'); +const countBy = require('lodash/countBy'); +const forEach = require('lodash/forEach'); +const reactStringReplace = require('react-string-replace'); + +const actions = require('../actions'); +const specThresholds = require('./vbox.info.thresholds'); +const { INFO } = require('./../constants'); +const { removeTier } = require('../utils'); +const shapes = require('./shapes'); + +function setVboxState(dispatch, vboxSelected, state) { + const { + itemInfo, + itemUnequip, + vbox, + } = state; + const { storeSelect, stashSelect } = vboxSelected; + + // default returns + let vboxCombiner = false; + let vboxHighlight = false; + + if (!(storeSelect.length === 0 && stashSelect.length === 0)) { + vboxHighlight = []; + const stashItems = stashSelect.map(j => vbox.bound[j]); + const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); + + const selectedItems = stashItems.concat(shopItems); + const itemCount = countBy(selectedItems, co => co); + + itemInfo.combos.forEach(combo => { + const comboCount = countBy(combo.components, co => co); + const buyCount = countBy(combo.components, co => co); + const valid = selectedItems.every(c => { + if (!combo.components.includes(c)) return false; + if (itemCount[c] > comboCount[c]) return false; + buyCount[c] -= 1; + return true; + }); + if (valid) { + const fullCombo = combo.components.every(c => itemCount[c] === comboCount[c]); + if (fullCombo) vboxCombiner = combo.item; + + forEach(buyCount, (value, key) => { + if (value > 0 && !vboxHighlight.includes(key)) { + vboxHighlight.push(key); + } + }); + } + }); + } + + + const vboxInfo = () => { + if (vboxCombiner) return vboxCombiner; + if (itemUnequip.length) return itemUnequip[1]; + const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i]))); + if (stashBase > -1) return vbox.bound[stashBase]; + const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]]))); + if (storeBase) return vbox.free[storeBase[0]][storeBase[1]]; + if (stashSelect.length > 0) return vbox.bound[stashSelect[0]]; + if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]]; + return false; + }; + + dispatch(actions.setVboxInfo(vboxInfo())); + dispatch(actions.setVboxCombiner(vboxCombiner)); + return dispatch(actions.setVboxHighlight(vboxHighlight)); +} + +function genItemInfo(item, itemInfo, player, info) { + const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item]; + const isSkill = fullInfo.skill; + const isSpec = fullInfo.spec; + const itemDescription = () => { + const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat|LIFE|SPEED|POWER)/; + const infoDescription = reactStringReplace(fullInfo.description, regEx, m => shapes[m]()); + return
{reactStringReplace(infoDescription, '\n', () =>
)}
; + }; + if (isSkill || isSpec) { + let infoName = fullInfo.item; + while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+'); + + const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item)); + + let itemSourceInfo = itemSource.length && !isSpec + ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` + : false; + + let header = null; + if (!itemSource.length) header = isSkill ?

SKILL

:

SPEC

; + if (itemSourceInfo) { + while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+'); + const itemRegEx = /(Red|Blue|Green)/; + itemSourceInfo = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); + } + + const cooldown = isSkill && fullInfo.cooldown ?
{fullInfo.cooldown} Turn delay
: null; + + const speed = isSkill + ?
Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
+ : null; + + const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null; + + return ( +
+

{infoName}

+ {header} + {itemSourceInfo} + {cooldown} + {itemDescription()} + {speed} + {thresholds} +
+ ); + } + return ( +
+

{fullInfo.item}

+ {itemDescription()} +
+ ); +} + + +module.exports = { setVboxState, genItemInfo }; diff --git a/client/src/events.jsx b/client/src/events.jsx index f852313c..a4b637a8 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -26,6 +26,12 @@ function registerEvents(store) { return errorToast(msg); } + function clearTutorial() { + store.dispatch(actions.setTutorial(null)); + localStorage.setItem('tutorial-complete', true); + } + + function setPing(ping) { store.dispatch(actions.setPing(ping)); } @@ -182,6 +188,9 @@ function registerEvents(store) { store.dispatch(actions.setActiveSkill(null)); store.dispatch(actions.setInfo(null)); store.dispatch(actions.setItemUnequip([])); + store.dispatch(actions.setItemUnequip([])); + store.dispatch(actions.setVboxCombiner(null)); + store.dispatch(actions.setVboxHighlight(null)); store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })); } @@ -292,6 +301,9 @@ function registerEvents(store) { startDemo(); } + // store.subscribe(setInfo); + // store.on('SET_INFO', setInfo); + // events.on('SET_PLAYER', setInstance); // events.on('SEND_SKILL', function skillActive(gameId, constructId, targetConstructId, skill) { @@ -340,6 +352,7 @@ function registerEvents(store) { clearInfo, clearInstance, clearMtxActive, + clearTutorial, setAccount, setAccountInstances, setActiveItem, diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index 3dcb0670..0267cf3f 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -57,6 +57,9 @@ module.exports = { tutorialGame: createReducer(1, 'SET_TUTORIAL_GAME'), vboxSelected: createReducer({ storeSelect: [], stashSelect: [] }, 'SET_VBOX_SELECTED'), + vboxCombiner: createReducer(null, 'SET_VBOX_COMBINER'), + vboxHighlight: createReducer(null, 'SET_VBOX_HIGHLIGHT'), + vboxInfo: createReducer(null, 'SET_VBOX_INFO'), ws: createReducer(null, 'SET_WS'), }; diff --git a/client/src/socket.jsx b/client/src/socket.jsx index a9ec07ba..2ca12623 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -204,6 +204,11 @@ function createSocket(events) { send(['SubscriptionState', {}]); } + function clearTutorial(instanceId) { + events.clearTutorial(); + sendInstanceState(instanceId); + } + // ------------- // Incoming // ------------- @@ -430,6 +435,8 @@ function createSocket(events) { sendMtxBuy, sendMtxConstructSpawn, + clearTutorial, + connect, }; } diff --git a/client/src/tutorial.utils.jsx b/client/src/tutorial.utils.jsx index 8736bd72..2e311ead 100644 --- a/client/src/tutorial.utils.jsx +++ b/client/src/tutorial.utils.jsx @@ -97,14 +97,10 @@ function tutorialVbox(player, store, tutorial) { store.dispatch(actions.setTutorial(stage)); } -function tutorialStage(tutorial, ws, clearTutorial, instance) { +function tutorialStage(tutorial, ws, instance) { if (!(instance.time_control === 'Practice' && instance.rounds.length === 1)) return false; - const exit = () => { - clearTutorial(); - localStorage.setItem('tutorial-complete', true); - ws.sendInstanceState(instance.id); - }; + const exit = () => ws.clearTutorial(instance.id); const tutorialText = () => { if (tutorial === 1) { From 4dbbb4f38d9934e543427874330fbacdde02b60c Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 25 Nov 2019 20:11:48 +1000 Subject: [PATCH 69/97] mobile game styling fix --- client/assets/styles/styles.mobile.less | 15 ++++++++++++--- client/src/components/vbox.component.jsx | 3 --- client/src/events.jsx | 1 + client/src/socket.jsx | 1 + 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index 0c80a7bd..c35e327b 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -36,6 +36,10 @@ div:nth-child(4n) { margin: 0 0.25em; } + div { + padding: 0 0.25em; + } + } .team, #targeting, .resolving-skill { @@ -61,12 +65,11 @@ } .skills { - display: grid; - grid-template-rows: 1fr; - grid-template-columns: 1fr 1fr 1fr; + display: flex; button { font-size: 1em; letter-spacing: 0.1em; + margin-right: 0; } @@ -83,6 +86,7 @@ } .player { + width: calc(90%); .game-construct { grid-template-areas: "left" @@ -99,7 +103,12 @@ } } + .resolving-skill { + width: calc(90%); + } + .opponent { + width: calc(90%); .game-construct { grid-template-rows: 2fr min-content; grid-template-rows: 1fr; diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index e0eb4307..90acf959 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -108,12 +108,9 @@ class Vbox extends preact.Component { player, tutorial, instance, - vboxCombiner, vboxHighlight, - vboxInfo, vboxSelected, - // Static itemInfo, // Function Calls diff --git a/client/src/events.jsx b/client/src/events.jsx index a4b637a8..15e7cb79 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -191,6 +191,7 @@ function registerEvents(store) { store.dispatch(actions.setItemUnequip([])); store.dispatch(actions.setVboxCombiner(null)); store.dispatch(actions.setVboxHighlight(null)); + store.dispatch(actions.setVboxInfo(null)); store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })); } diff --git a/client/src/socket.jsx b/client/src/socket.jsx index 2ca12623..c97c4fb2 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -206,6 +206,7 @@ function createSocket(events) { function clearTutorial(instanceId) { events.clearTutorial(); + events.clearInstance(); sendInstanceState(instanceId); } From f4a7ba65ebab33fa63a26720ee9abdb5320ee49d Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 25 Nov 2019 21:46:54 +1000 Subject: [PATCH 70/97] unlock info size from store/stash divider --- client/assets/styles/styles.mobile.less | 10 ++- client/assets/styles/vbox.less | 84 +++++++++++++----------- client/src/components/vbox.component.jsx | 18 ++--- 3 files changed, 64 insertions(+), 48 deletions(-) diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index c35e327b..d15b1668 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -253,7 +253,7 @@ grid-template-areas: "store-hdr store-hdr stash-hdr stash-hdr" "store store stash stash" - "store store combiner combiner"; + "store store info-combiner info-combiner"; > div { padding: 0.25em; @@ -267,8 +267,12 @@ display: none; } - .combiner { - margin: 0; + .info-combiner { + .combiner { + margin: 0; + width: 100%; + height: 100%; + } } .stash { diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index b6bff59f..fbc29662 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -5,8 +5,8 @@ grid-template-rows: 3fr minmax(min-content, 2fr); grid-template-columns: 1fr 4fr 6fr min-content; grid-template-areas: - "store-hdr store info combos" - "stash-hdr stash combiner combos"; + "store-hdr store info-combiner combos" + "stash-hdr stash info-combiner combos"; margin-bottom: 1em; // immediate children @@ -169,48 +169,58 @@ } } - .info { - line-height: 1.6; + .info-combiner { + grid-area: info-combiner; + display: grid; + grid-template-areas: + "info" + "combiner"; + grid-template-rows: min-content 1fr; - h2 { - text-transform: uppercase; - } + .info { + grid-area: info; + line-height: 1.6; + height: 100%; - svg { - display: inline; - height: 1em; - } + h2 { + text-transform: uppercase; + } - figure { - display: inline; - height: 0.5em; svg { - margin-right: 0.5em; + display: inline; + height: 1em; + } + + figure { + display: inline; + height: 0.5em; + svg { + margin-right: 0.5em; + } + } + + figcaption { + font-size: 1em; + display: inline-block; + vertical-align: middle; + } + + margin-left: 1em; + } + + .combiner { + grid-area: combiner; + margin: 1em 0.5em; + width: 50%; + line-height: 1.3; + font-size: 1.25em; + letter-spacing: 0.1em; + border: 0.1em solid @gray-exists; + &:hover { + border: 0.1em solid @gray-hover; } } - - figcaption { - font-size: 1em; - display: inline-block; - vertical-align: middle; - } - - margin-left: 1em; - grid-area: info; - } - - .combiner { - grid-area: combiner; // align-self: flex-end; - height: 100%; - margin: 0 0.5em; - line-height: 1.3; - font-size: 1.25em; - letter-spacing: 0.1em; - border: 0.1em solid @gray-exists; - &:hover { - border: 0.1em solid @gray-hover; - } } .combos { diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 90acf959..017398ee 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -223,15 +223,17 @@ class Vbox extends preact.Component { vboxHighlight = {vboxHighlight} vboxHover = {vboxHover} /> - +
+ + +
-
); } From a50d10185fe4504ef73a25af8ee6a04ad0ce075b Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 25 Nov 2019 22:18:04 +1000 Subject: [PATCH 71/97] click clear, match default refund border width --- client/assets/styles/vbox.less | 3 ++- client/src/components/instance.component.jsx | 3 +++ client/src/components/vbox.combos.jsx | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index fbc29662..304b288a 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -3,7 +3,7 @@ grid-area: vbox; display: grid; grid-template-rows: 3fr minmax(min-content, 2fr); - grid-template-columns: 1fr 4fr 6fr min-content; + grid-template-columns: 1fr 4fr 6fr minmax(min-content, 2fr);; grid-template-areas: "store-hdr store info-combiner combos" "stash-hdr stash info-combiner combos"; @@ -71,6 +71,7 @@ button { line-height: 1.6; letter-spacing: 0.15em; + border-width: 1px; } } diff --git a/client/src/components/instance.component.jsx b/client/src/components/instance.component.jsx index c59b5833..2022f564 100644 --- a/client/src/components/instance.component.jsx +++ b/client/src/components/instance.component.jsx @@ -27,6 +27,9 @@ const addState = connect( function clearItems() { dispatch(actions.setItemUnequip([])); + dispatch(actions.setVboxCombiner(null)); + dispatch(actions.setVboxHighlight(null)); + dispatch(actions.setVboxInfo(null)); dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })); return true; } diff --git a/client/src/components/vbox.combos.jsx b/client/src/components/vbox.combos.jsx index f988064c..5973f221 100644 --- a/client/src/components/vbox.combos.jsx +++ b/client/src/components/vbox.combos.jsx @@ -15,7 +15,6 @@ function Combos(args) { // Static itemInfo, instance, // Only used for tutorial check - // functions } = args; if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; From 86a84cbcea43effa1436b86945a5bb2e830fa505 Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 25 Nov 2019 22:19:48 +1000 Subject: [PATCH 72/97] duplicate line --- client/src/events.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/events.jsx b/client/src/events.jsx index 15e7cb79..bb03367b 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -188,7 +188,6 @@ function registerEvents(store) { store.dispatch(actions.setActiveSkill(null)); store.dispatch(actions.setInfo(null)); store.dispatch(actions.setItemUnequip([])); - store.dispatch(actions.setItemUnequip([])); store.dispatch(actions.setVboxCombiner(null)); store.dispatch(actions.setVboxHighlight(null)); store.dispatch(actions.setVboxInfo(null)); From c10b68949cb305431a3a516905a3a8470a33816a Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 26 Nov 2019 10:42:06 +1000 Subject: [PATCH 73/97] should comp update for info / combos --- client/assets/styles/styles.mobile.less | 8 +- client/assets/styles/vbox.less | 6 +- client/src/components/vbox.combos.jsx | 88 ++++++++++++---------- client/src/components/vbox.info.jsx | 99 ++++++++++++++----------- client/src/components/vbox.utils.jsx | 2 +- 5 files changed, 111 insertions(+), 92 deletions(-) diff --git a/client/assets/styles/styles.mobile.less b/client/assets/styles/styles.mobile.less index d15b1668..27c8fa8a 100644 --- a/client/assets/styles/styles.mobile.less +++ b/client/assets/styles/styles.mobile.less @@ -259,15 +259,15 @@ padding: 0.25em; } - .info { - display: none; - } - .combos { display: none; } .info-combiner { + .info { + display: none; + } + .combiner { margin: 0; width: 100%; diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 304b288a..ae5a462f 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -71,7 +71,7 @@ button { line-height: 1.6; letter-spacing: 0.15em; - border-width: 1px; + border-width: 0.1em; } } @@ -108,7 +108,7 @@ &[disabled] { background: black; - border-width: 1px; + border-width: 0.1em; }; } @@ -145,8 +145,6 @@ &.highlight { color: black; background: @silver; - // border: 1px solid @white; (this bangs around the vbox) - // overwrite the classes on white svg elements svg { stroke-width: 0.75em; diff --git a/client/src/components/vbox.combos.jsx b/client/src/components/vbox.combos.jsx index 5973f221..f3831a57 100644 --- a/client/src/components/vbox.combos.jsx +++ b/client/src/components/vbox.combos.jsx @@ -6,51 +6,61 @@ const { convertItem } = require('../utils'); const addState = connect(({ info, itemInfo, instance, tutorial, vboxInfo }) => ({ info, itemInfo, instance, tutorial, vboxInfo })); -function Combos(args) { - const { - // Variables that will change - info, - tutorial, - vboxInfo, - // Static - itemInfo, - instance, // Only used for tutorial check - } = args; - if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; +class Combos extends preact.Component { + shouldComponentUpdate(newProps) { + if (newProps.info !== this.props.info) return true; + if (newProps.tutorial !== this.props.tutorial) return true; + if (newProps.vboxInfo !== this.props.vboxInfo) return true; + return false; + } - const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info)); - if (vboxCombos.length > 6 || vboxCombos.length === 0) return
; + render(props) { + const { + // Variables that will change + info, + tutorial, + vboxInfo, + // Static + itemInfo, + instance, // Only used for tutorial check + } = props; - const comboTable = vboxCombos.map((c, i) => { - const mouseOver = e => { - e.stopPropagation(); - this.setState({ comboItem: c.item }); - }; - const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) - ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, -
{convertItem(c.components[2])}
] - : c.components.map((u, j) =>
{convertItem(u)}
); - return ( -
-
- {convertItem(c.item)} + if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; + + const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info)); + if (vboxCombos.length > 6 || vboxCombos.length === 0) return
; + + const comboTable = vboxCombos.map((c, i) => { + const mouseOver = e => { + e.stopPropagation(); + this.setState({ comboItem: c.item }); + }; + const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) + ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, +
{convertItem(c.components[2])}
] + : c.components.map((u, j) =>
{convertItem(u)}
); + return ( +
+
+ {convertItem(c.item)} +
+ {componentTable} +
+ ); + }); + return ( +
+
+

COMBOS

+ Combine colours and items. +
+
+ {comboTable}
- {componentTable}
); - }); - return ( -
-
-

COMBOS

- Combine colours and items. -
-
- {comboTable} -
-
- ); + } } module.exports = addState(Combos); diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index 80f32528..26f0a975 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -6,54 +6,65 @@ const { genItemInfo } = require('./vbox.utils'); const addState = connect(({ info, player, tutorial, vboxInfo, ws, itemInfo, instance }) => ({ info, player, tutorial, vboxInfo, ws, itemInfo, instance })); -function Info(args) { - const { - // Variables that will change - info, - player, - tutorial, - vboxInfo, - // Static - ws, - itemInfo, - instance, - } = args; - - if (tutorial) { - const tutorialStageInfo = tutorialStage(tutorial, ws, instance); - if (tutorialStageInfo) return tutorialStageInfo; +class Info extends preact.Component { + shouldComponentUpdate(newProps) { + // Single variable props + if (newProps.info !== this.props.info) return true; + if (newProps.player !== this.props.player) return true; + if (newProps.tutorial !== this.props.tutorial) return true; + if (newProps.vboxInfo !== this.props.vboxInfo) return true; + return false; } - // Prioritise the vbox info - if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); + render(props) { + const { + // Variables that will change + info, + player, + tutorial, + vboxInfo, + // Static + ws, + itemInfo, + instance, + } = props; - // check normal info state - if (!info) return false; - if (info.includes('constructName')) { - return ( -
-

{info.replace('constructName ', '')}

-

This is the name of your construct.
- Names are randomly generated and are purely cosmetic.
- You can change change your construct name in the RESHAPE tab outside of games. -

-
- ); + if (tutorial) { + const tutorialStageInfo = tutorialStage(tutorial, ws, instance); + if (tutorialStageInfo) return tutorialStageInfo; + } + + // Prioritise the vbox info + if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); + + // check normal info state + if (!info) return false; + if (info.includes('constructName')) { + return ( +
+

{info.replace('constructName ', '')}

+

This is the name of your construct.
+ Names are randomly generated and are purely cosmetic.
+ You can change change your construct name in the RESHAPE tab outside of games. +

+
+ ); + } + + if (info.includes('constructAvatar')) { + return ( +
+

{info.replace('constructAvatar ', '')}

+

This is your construct avatar.
+ Avatars are randomly generated and are purely cosmetic.
+ You can change your construct avatar in the RESHAPE tab outside of games. +

+
+ ); + } + + return genItemInfo(info, itemInfo, player, info); } - - if (info.includes('constructAvatar')) { - return ( -
-

{info.replace('constructAvatar ', '')}

-

This is your construct avatar.
- Avatars are randomly generated and are purely cosmetic.
- You can change your construct avatar in the RESHAPE tab outside of games. -

-
- ); - } - - return genItemInfo(info, itemInfo, player, info); } module.exports = addState(Info); diff --git a/client/src/components/vbox.utils.jsx b/client/src/components/vbox.utils.jsx index 6d934263..59830470 100644 --- a/client/src/components/vbox.utils.jsx +++ b/client/src/components/vbox.utils.jsx @@ -66,7 +66,7 @@ function setVboxState(dispatch, vboxSelected, state) { dispatch(actions.setVboxInfo(vboxInfo())); dispatch(actions.setVboxCombiner(vboxCombiner)); - return dispatch(actions.setVboxHighlight(vboxHighlight)); + dispatch(actions.setVboxHighlight(vboxHighlight)); } function genItemInfo(item, itemInfo, player, info) { From e2444cc988fe4fb009eb2d0a49cb4af5c39c0423 Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 26 Nov 2019 10:49:14 +1000 Subject: [PATCH 74/97] wl --- WORKLOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WORKLOG.md b/WORKLOG.md index daaaefb6..106785ba 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -30,6 +30,9 @@ Hexagon Set - Increase intensity for each visit _mashy_ +* add back combo preview +* floating combat text combat (start opposite hp and float towards it) to speed up animations +* represent construct colours during game phase (try %bar or dots) * buy from preview if you have the required bases in vbox / inventory - a "buy" becomes available under the current info / preview section - clicking the buy automatically purchases / combine items @@ -50,7 +53,6 @@ _external_ _tba_ * supporter gold name in instance (anyone whos put any money into game) -* represent construct colours during game phase (coloured border?) * Speed up animations slightly (3s per normal event too long) - Improve combat text to start at the opposite end of construct and float towards health stats - Show combat text for skill cast possibly? Watch some pokemans etc for modern combat smoothing From f03317da545c88327a27456bee09dd9de414813a Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 26 Nov 2019 10:49:40 +1000 Subject: [PATCH 75/97] wl --- WORKLOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/WORKLOG.md b/WORKLOG.md index 106785ba..39803600 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -53,9 +53,6 @@ _external_ _tba_ * supporter gold name in instance (anyone whos put any money into game) -* Speed up animations slightly (3s per normal event too long) - - Improve combat text to start at the opposite end of construct and float towards health stats - - Show combat text for skill cast possibly? Watch some pokemans etc for modern combat smoothing * Give the bots some ai / make stronger so its a challenge for new people to beat - train a few games of with some round losses to get them into the game From d1649c986b779697a271270c96c0db7398952635 Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 26 Nov 2019 11:43:53 +1000 Subject: [PATCH 76/97] vbox css fix --- client/assets/styles/vbox.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index ae5a462f..209f31de 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -14,6 +14,10 @@ padding: 0.5em; } + label { + line-height: 0; + } + .store { grid-area: store; border-right: 0.15em solid @gray; From 8312b44b2b04cc8f852c6889806feaf3b9f45e87 Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 26 Nov 2019 12:03:31 +1000 Subject: [PATCH 77/97] change info / combos back to functional components with passed down props --- client/src/components/vbox.combos.jsx | 91 ++++++++----------- client/src/components/vbox.component.jsx | 106 +++++++++-------------- client/src/components/vbox.info.jsx | 103 ++++++++++------------ client/src/components/vbox.stash.jsx | 42 ++++++++- client/src/components/vbox.store.jsx | 36 +++++++- client/src/tutorial.utils.jsx | 4 +- 6 files changed, 203 insertions(+), 179 deletions(-) diff --git a/client/src/components/vbox.combos.jsx b/client/src/components/vbox.combos.jsx index f3831a57..01c959d2 100644 --- a/client/src/components/vbox.combos.jsx +++ b/client/src/components/vbox.combos.jsx @@ -1,66 +1,51 @@ const preact = require('preact'); -const { connect } = require('preact-redux'); const { convertItem } = require('../utils'); -const addState = connect(({ info, itemInfo, instance, tutorial, vboxInfo }) => - ({ info, itemInfo, instance, tutorial, vboxInfo })); +function Combos(props) { + const { + info, + instance, + itemInfo, + tutorial, + vboxInfo, + } = props; + if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; -class Combos extends preact.Component { - shouldComponentUpdate(newProps) { - if (newProps.info !== this.props.info) return true; - if (newProps.tutorial !== this.props.tutorial) return true; - if (newProps.vboxInfo !== this.props.vboxInfo) return true; - return false; - } + const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info)); + if (vboxCombos.length > 6 || vboxCombos.length === 0) return
; - render(props) { - const { - // Variables that will change - info, - tutorial, - vboxInfo, - // Static - itemInfo, - instance, // Only used for tutorial check - } = props; - - if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; - - const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info)); - if (vboxCombos.length > 6 || vboxCombos.length === 0) return
; - - const comboTable = vboxCombos.map((c, i) => { - const mouseOver = e => { - e.stopPropagation(); - this.setState({ comboItem: c.item }); - }; - const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) - ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, -
{convertItem(c.components[2])}
] - : c.components.map((u, j) =>
{convertItem(u)}
); - return ( -
-
- {convertItem(c.item)} -
- {componentTable} -
- ); - }); + const comboTable = vboxCombos.map((c, i) => { + const mouseOver = e => { + e.stopPropagation(); + // this.setState({ comboItem: c.item }); + // set comboInfo state here + }; + const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) + ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, +
{convertItem(c.components[2])}
] + : c.components.map((u, j) =>
{convertItem(u)}
); return ( -
-
-

COMBOS

- Combine colours and items. -
-
- {comboTable} +
+
+ {convertItem(c.item)}
+ {componentTable}
); - } + }); + return ( +
+
+

COMBOS

+ Combine colours and items. +
+
e.stopPropagation()}> + {comboTable} +
+
+ ); } -module.exports = addState(Combos); +module.exports = Combos; diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 017398ee..8db81e37 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -4,8 +4,8 @@ const { connect } = require('preact-redux'); const actions = require('../actions'); const InfoContainer = require('./vbox.info'); -const StashElement = require('./vbox.stash'); -const StoreElement = require('./vbox.store'); +const { StashHdr, StashElement } = require('./vbox.stash'); +const { StoreHdr, StoreElement } = require('./vbox.store'); const Combiner = require('./vbox.combiner'); const Combos = require('./vbox.combos'); @@ -28,6 +28,10 @@ const addState = connect( vboxSelected, } = state; + function clearTutorial() { + return ws.clearTutorial(instance.id); + } + function sendVboxDiscard() { return ws.sendVboxDiscard(instance.id); } @@ -64,6 +68,7 @@ const addState = connect( vboxInfo, vboxSelected, + clearTutorial, sendVboxAccept, sendVboxCombine, sendVboxDiscard, @@ -105,15 +110,18 @@ class Vbox extends preact.Component { const { // Changing state variables itemUnequip, + info, + instance, player, tutorial, - instance, vboxCombiner, vboxHighlight, + vboxInfo, vboxSelected, // Static itemInfo, // Function Calls + clearTutorial, dispatchVboxSelect, sendItemUnequip, sendVboxAccept, @@ -140,67 +148,16 @@ class Vbox extends preact.Component { return true; } - function storeHdr() { - return ( -
-

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'store')}> STORE -

-

vboxHover(e, 'bits')}> - {vbox.bits}b -

- -
- ); - } - - function stashHdr() { - const refund = storeSelect.length === 0 && stashSelect.length === 1 - ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost - : 0; - const tutorialDisabled = tutorial && tutorial < 8 - && instance.time_control === 'Practice' && instance.rounds.length === 1; - const refundBtn = ( - - ); - - return ( -
-

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'stash')}> STASH -

- {refundBtn} -
- ); - } - // EVERYTHING return (
- {storeHdr()} - {stashHdr()} + +
- +
- +
); } diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index 26f0a975..dac8e2e2 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -1,70 +1,55 @@ const preact = require('preact'); -const { connect } = require('preact-redux'); const { tutorialStage } = require('../tutorial.utils'); const { genItemInfo } = require('./vbox.utils'); -const addState = connect(({ info, player, tutorial, vboxInfo, ws, itemInfo, instance }) => - ({ info, player, tutorial, vboxInfo, ws, itemInfo, instance })); +function Info(props) { + const { + // Variables that will change + info, + player, + tutorial, + vboxInfo, + // Static + clearTutorial, + itemInfo, + instance, + } = props; -class Info extends preact.Component { - shouldComponentUpdate(newProps) { - // Single variable props - if (newProps.info !== this.props.info) return true; - if (newProps.player !== this.props.player) return true; - if (newProps.tutorial !== this.props.tutorial) return true; - if (newProps.vboxInfo !== this.props.vboxInfo) return true; - return false; + if (tutorial) { + const tutorialStageInfo = tutorialStage(tutorial, clearTutorial, instance); + if (tutorialStageInfo) return tutorialStageInfo; } - render(props) { - const { - // Variables that will change - info, - player, - tutorial, - vboxInfo, - // Static - ws, - itemInfo, - instance, - } = props; + // Prioritise the vbox info + if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); - if (tutorial) { - const tutorialStageInfo = tutorialStage(tutorial, ws, instance); - if (tutorialStageInfo) return tutorialStageInfo; - } - - // Prioritise the vbox info - if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); - - // check normal info state - if (!info) return false; - if (info.includes('constructName')) { - return ( -
-

{info.replace('constructName ', '')}

-

This is the name of your construct.
- Names are randomly generated and are purely cosmetic.
- You can change change your construct name in the RESHAPE tab outside of games. -

-
- ); - } - - if (info.includes('constructAvatar')) { - return ( -
-

{info.replace('constructAvatar ', '')}

-

This is your construct avatar.
- Avatars are randomly generated and are purely cosmetic.
- You can change your construct avatar in the RESHAPE tab outside of games. -

-
- ); - } - - return genItemInfo(info, itemInfo, player, info); + // check normal info state + if (!info) return false; + if (info.includes('constructName')) { + return ( +
+

{info.replace('constructName ', '')}

+

This is the name of your construct.
+ Names are randomly generated and are purely cosmetic.
+ You can change change your construct name in the RESHAPE tab outside of games. +

+
+ ); } + + if (info.includes('constructAvatar')) { + return ( +
+

{info.replace('constructAvatar ', '')}

+

This is your construct avatar.
+ Avatars are randomly generated and are purely cosmetic.
+ You can change your construct avatar in the RESHAPE tab outside of games. +

+
+ ); + } + + return genItemInfo(info, itemInfo, player, info); } -module.exports = addState(Info); +module.exports = Info; diff --git a/client/src/components/vbox.stash.jsx b/client/src/components/vbox.stash.jsx index 264a9f60..243f890b 100644 --- a/client/src/components/vbox.stash.jsx +++ b/client/src/components/vbox.stash.jsx @@ -6,6 +6,46 @@ const shapes = require('./shapes'); const buttons = require('./buttons'); const { removeTier } = require('../utils'); +function stashHdr(props) { + const { + instance, + itemInfo, + sendVboxReclaim, + tutorial, + vbox, + vboxHover, + vboxSelected, + } = props; + const { storeSelect, stashSelect } = vboxSelected; + const refund = storeSelect.length === 0 && stashSelect.length === 1 + ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost + : 0; + const tutorialDisabled = tutorial && tutorial < 8 + && instance.time_control === 'Practice' && instance.rounds.length === 1; + const refundBtn = ( + + ); + + return ( +
+

e.target.scrollIntoView(true)} + onMouseOver={e => vboxHover(e, 'stash')}> STASH +

+ {refundBtn} +
+ ); +} + function stashElement(props) { const { itemUnequip, @@ -105,4 +145,4 @@ function stashElement(props) { ); } -module.exports = stashElement; +module.exports = { stashHdr, stashElement }; diff --git a/client/src/components/vbox.store.jsx b/client/src/components/vbox.store.jsx index 4dfda70a..50c2e337 100644 --- a/client/src/components/vbox.store.jsx +++ b/client/src/components/vbox.store.jsx @@ -3,6 +3,40 @@ const range = require('lodash/range'); const shapes = require('./shapes'); +function storeHdr(props) { + const { + instance, + tutorial, + sendVboxDiscard, + vbox, + vboxHover, + } = props; + + return ( +
+

e.target.scrollIntoView(true)} + onMouseOver={e => vboxHover(e, 'store')}> STORE +

+

vboxHover(e, 'bits')}> + {vbox.bits}b +

+ +
+ ); +} + function storeElement(props) { const { @@ -75,4 +109,4 @@ function storeElement(props) { ); } -module.exports = storeElement; +module.exports = { storeHdr, storeElement }; diff --git a/client/src/tutorial.utils.jsx b/client/src/tutorial.utils.jsx index 2e311ead..05fedee5 100644 --- a/client/src/tutorial.utils.jsx +++ b/client/src/tutorial.utils.jsx @@ -97,10 +97,10 @@ function tutorialVbox(player, store, tutorial) { store.dispatch(actions.setTutorial(stage)); } -function tutorialStage(tutorial, ws, instance) { +function tutorialStage(tutorial, clearTutorial, instance) { if (!(instance.time_control === 'Practice' && instance.rounds.length === 1)) return false; - const exit = () => ws.clearTutorial(instance.id); + const exit = () => clearTutorial(); const tutorialText = () => { if (tutorial === 1) { From 5153ed07b0112b17fa0d7b5fe2d70f7eb16c25a8 Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 26 Nov 2019 13:27:50 +1000 Subject: [PATCH 78/97] add back shouldComponentUpdates =\ --- client/src/components/vbox.combiner.jsx | 86 +++++---- client/src/components/vbox.combos.jsx | 94 ++++++---- client/src/components/vbox.component.jsx | 128 +++++++------ client/src/components/vbox.info.jsx | 107 ++++++----- client/src/components/vbox.stash.jsx | 229 +++++++++++------------ client/src/components/vbox.store.jsx | 185 +++++++++--------- 6 files changed, 430 insertions(+), 399 deletions(-) diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index 9fef580e..cf42547b 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -1,44 +1,58 @@ const preact = require('preact'); +const { connect } = require('preact-redux'); -function Combiner(args) { - const { - vbox, - vboxCombiner, - vboxSelected, - vboxBuySelected, - sendVboxCombine, - } = args; +const addState = connect(({ vboxCombiner }) => ({ vboxCombiner })); - const { stashSelect, storeSelect } = vboxSelected; - - if (vboxCombiner) { - const combinerComboText = vboxCombiner.replace('Plus', '+'); - let bits = 0; - storeSelect.forEach(item => bits += item[0] + 1); - return ( - - ); +class Combiner extends preact.Component { + shouldComponentUpdate(newProps) { + if (newProps.vbox !== this.props.vbox) return true; + if (newProps.vboxSelected !== this.props.vboxSelected) return true; + if (newProps.vboxBuySelected !== this.props.vboxBuySelected) return true; + if (newProps.sendVboxCombine !== this.props.sendVboxCombine) return true; + if (newProps.vboxCombiner !== this.props.vboxCombiner) return true; + return false; } - if (stashSelect.length === 0 && storeSelect.length === 1) { - const item = storeSelect[0]; - return ( - - ); - } + render(args) { + const { + vbox, + vboxSelected, + vboxBuySelected, + sendVboxCombine, + vboxCombiner, + } = args; - return false; + const { stashSelect, storeSelect } = vboxSelected; + + if (vboxCombiner) { + const combinerComboText = vboxCombiner.replace('Plus', '+'); + let bits = 0; + storeSelect.forEach(item => bits += item[0] + 1); + return ( + + ); + } + + if (stashSelect.length === 0 && storeSelect.length === 1) { + const item = storeSelect[0]; + return ( + + ); + } + + return false; + } } -module.exports = Combiner; +module.exports = addState(Combiner); diff --git a/client/src/components/vbox.combos.jsx b/client/src/components/vbox.combos.jsx index 01c959d2..b35e71f7 100644 --- a/client/src/components/vbox.combos.jsx +++ b/client/src/components/vbox.combos.jsx @@ -1,51 +1,67 @@ const preact = require('preact'); +const { connect } = require('preact-redux'); const { convertItem } = require('../utils'); -function Combos(props) { - const { - info, - instance, - itemInfo, - tutorial, - vboxInfo, - } = props; +const addState = connect( + ({ info, instance, itemInfo, tutorial, vboxInfo }) => ({ + info, instance, itemInfo, tutorial, vboxInfo, + })); - if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; +class Combos extends preact.Component { + shouldComponentUpdate(newProps) { + if (newProps.info !== this.props.info) return true; + if (newProps.instance !== this.props.instance) return true; + if (newProps.itemInfo !== this.props.itemInfo) return true; + if (newProps.tutorial !== this.props.tutorial) return true; + if (newProps.vboxInfo !== this.props.vboxInfo) return true; + return false; + } - const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info)); - if (vboxCombos.length > 6 || vboxCombos.length === 0) return
; + render(props) { + const { + info, + instance, + itemInfo, + tutorial, + vboxInfo, + } = props; + if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; - const comboTable = vboxCombos.map((c, i) => { - const mouseOver = e => { - e.stopPropagation(); - // this.setState({ comboItem: c.item }); - // set comboInfo state here - }; - const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) - ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, -
{convertItem(c.components[2])}
] - : c.components.map((u, j) =>
{convertItem(u)}
); - return ( -
-
- {convertItem(c.item)} + const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info)); + if (vboxCombos.length > 6 || vboxCombos.length === 0) return
; + + const comboTable = vboxCombos.map((c, i) => { + const mouseOver = e => { + e.stopPropagation(); + // this.setState({ comboItem: c.item }); + // set comboInfo state here + }; + const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) + ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, +
{convertItem(c.components[2])}
] + : c.components.map((u, j) =>
{convertItem(u)}
); + return ( +
+
+ {convertItem(c.item)} +
+ {componentTable} +
+ ); + }); + return ( +
+
+

COMBOS

+ Combine colours and items. +
+
e.stopPropagation()}> + {comboTable}
- {componentTable}
); - }); - return ( -
-
-

COMBOS

- Combine colours and items. -
-
e.stopPropagation()}> - {comboTable} -
-
- ); + } } -module.exports = Combos; +module.exports = addState(Combos); diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 8db81e37..7cd5c0dc 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -4,8 +4,8 @@ const { connect } = require('preact-redux'); const actions = require('../actions'); const InfoContainer = require('./vbox.info'); -const { StashHdr, StashElement } = require('./vbox.stash'); -const { StoreHdr, StoreElement } = require('./vbox.store'); +const StashElement = require('./vbox.stash'); +const StoreElement = require('./vbox.store'); const Combiner = require('./vbox.combiner'); const Combos = require('./vbox.combos'); @@ -96,13 +96,11 @@ const addState = connect( class Vbox extends preact.Component { shouldComponentUpdate(newProps) { - // Single variable props if (newProps.itemUnequip !== this.props.itemUnequip) return true; + if (newProps.instance !== this.props.instance) return true; + if (newProps.player !== this.props.player) return true; if (newProps.tutorial !== this.props.tutorial) return true; if (newProps.vboxSelected !== this.props.vboxSelected) return true; - if (newProps.vboxHighlight !== this.props.vboxHighlight) return true; - if (newProps.player !== this.props.player) return true; - if (newProps.instance !== this.props.instance) return true; return false; } @@ -110,13 +108,9 @@ class Vbox extends preact.Component { const { // Changing state variables itemUnequip, - info, instance, player, tutorial, - vboxCombiner, - vboxHighlight, - vboxInfo, vboxSelected, // Static itemInfo, @@ -148,72 +142,94 @@ class Vbox extends preact.Component { return true; } + function storeHdr() { + return ( +
+

e.target.scrollIntoView(true)} + onMouseOver={e => vboxHover(e, 'store')}> STORE +

+

vboxHover(e, 'bits')}> + {vbox.bits}b +

+ +
+ ); + } + + function stashHdr() { + const refund = storeSelect.length === 0 && stashSelect.length === 1 + ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost + : 0; + const tutorialDisabled = tutorial && tutorial < 8 + && instance.time_control === 'Practice' && instance.rounds.length === 1; + const refundBtn = ( + + ); + + return ( +
+

e.target.scrollIntoView(true)} + onMouseOver={e => vboxHover(e, 'stash')}> STASH +

+ {refundBtn} +
+ ); + } + // EVERYTHING return (
- + {storeHdr()} + {stashHdr()} -
- +
); } diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index dac8e2e2..e71d75a0 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -1,55 +1,74 @@ const preact = require('preact'); +const { connect } = require('preact-redux'); + const { tutorialStage } = require('../tutorial.utils'); const { genItemInfo } = require('./vbox.utils'); -function Info(props) { - const { - // Variables that will change - info, - player, - tutorial, - vboxInfo, - // Static - clearTutorial, - itemInfo, - instance, - } = props; +const addState = connect( + ({ info, player, tutorial, vboxInfo, itemInfo, instance }) => ({ + info, player, tutorial, vboxInfo, itemInfo, instance, + })); - if (tutorial) { - const tutorialStageInfo = tutorialStage(tutorial, clearTutorial, instance); - if (tutorialStageInfo) return tutorialStageInfo; + +class Info extends preact.Component { + shouldComponentUpdate(newProps) { + if (newProps.clearTutorial !== this.props.clearTutorial) return true; + if (newProps.info !== this.props.info) return true; + if (newProps.player !== this.props.player) return true; + if (newProps.tutorial !== this.props.tutorial) return true; + if (newProps.vboxInfo !== this.props.vboxInfo) return true; + if (newProps.itemInfo !== this.props.itemInfo) return true; + if (newProps.instance !== this.props.instance) return true; + return false; } - // Prioritise the vbox info - if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); + render(props) { + const { + clearTutorial, + info, + player, + tutorial, + vboxInfo, + itemInfo, + instance, + } = props; - // check normal info state - if (!info) return false; - if (info.includes('constructName')) { - return ( -
-

{info.replace('constructName ', '')}

-

This is the name of your construct.
- Names are randomly generated and are purely cosmetic.
- You can change change your construct name in the RESHAPE tab outside of games. -

-
- ); + if (tutorial) { + const tutorialStageInfo = tutorialStage(tutorial, clearTutorial, instance); + if (tutorialStageInfo) return tutorialStageInfo; + } + + // Prioritise the vbox info + if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); + + // check normal info state + if (!info) return false; + if (info.includes('constructName')) { + return ( +
+

{info.replace('constructName ', '')}

+

This is the name of your construct.
+ Names are randomly generated and are purely cosmetic.
+ You can change change your construct name in the RESHAPE tab outside of games. +

+
+ ); + } + + if (info.includes('constructAvatar')) { + return ( +
+

{info.replace('constructAvatar ', '')}

+

This is your construct avatar.
+ Avatars are randomly generated and are purely cosmetic.
+ You can change your construct avatar in the RESHAPE tab outside of games. +

+
+ ); + } + + return genItemInfo(info, itemInfo, player, info); } - - if (info.includes('constructAvatar')) { - return ( -
-

{info.replace('constructAvatar ', '')}

-

This is your construct avatar.
- Avatars are randomly generated and are purely cosmetic.
- You can change your construct avatar in the RESHAPE tab outside of games. -

-
- ); - } - - return genItemInfo(info, itemInfo, player, info); } -module.exports = Info; +module.exports = addState(Info); diff --git a/client/src/components/vbox.stash.jsx b/client/src/components/vbox.stash.jsx index 243f890b..eab47d50 100644 --- a/client/src/components/vbox.stash.jsx +++ b/client/src/components/vbox.stash.jsx @@ -1,4 +1,6 @@ const preact = require('preact'); +const { connect } = require('preact-redux'); + const range = require('lodash/range'); const without = require('lodash/without'); @@ -6,143 +8,124 @@ const shapes = require('./shapes'); const buttons = require('./buttons'); const { removeTier } = require('../utils'); -function stashHdr(props) { - const { - instance, - itemInfo, - sendVboxReclaim, - tutorial, - vbox, - vboxHover, - vboxSelected, - } = props; - const { storeSelect, stashSelect } = vboxSelected; - const refund = storeSelect.length === 0 && stashSelect.length === 1 - ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost - : 0; - const tutorialDisabled = tutorial && tutorial < 8 - && instance.time_control === 'Practice' && instance.rounds.length === 1; - const refundBtn = ( - - ); +const addState = connect( + ({ itemUnequip, vboxHighlight, vboxSelected }) => ({ itemUnequip, vboxHighlight, vboxSelected })); - return ( -
-

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'stash')}> STASH -

- {refundBtn} -
- ); -} +class stashElement extends preact.Component { + shouldComponentUpdate(newProps) { + if (newProps.sendItemUnequip !== this.props.sendItemUnequip) return true; + if (newProps.setInfo !== this.props.setInfo) return true; + if (newProps.setVboxSelected !== this.props.setVboxSelected) return true; + if (newProps.vbox !== this.props.vbox) return true; + if (newProps.vboxBuySelected !== this.props.vboxBuySelected) return true; + if (newProps.vboxHover !== this.props.vboxHover) return true; -function stashElement(props) { - const { - itemUnequip, - sendItemUnequip, - setInfo, - setVboxSelected, - stashSelect, - storeSelect, - vbox, - vboxBuySelected, - vboxHighlight, - vboxHover, - } = props; - - const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0; - - function stashClick(e) { - e.stopPropagation(); - if (itemUnequip.length) return sendItemUnequip(itemUnequip); - if (vboxSelecting) return vboxBuySelected(); - return true; + if (newProps.itemUnequip !== this.props.itemUnequip) return true; + if (newProps.vboxHighlight !== this.props.vboxHighlight) return true; + if (newProps.vboxSelected !== this.props.vboxSelected) return true; + return false; } - function stashBtn(v, i) { - const stashHighlight = vboxSelecting || itemUnequip.length; + render(props) { + const { + sendItemUnequip, + setInfo, + setVboxSelected, + vbox, + vboxBuySelected, + vboxHover, - if (!v && v !== 0) { - const emptyInvClick = () => { - if (vboxSelecting) return vboxBuySelected(); - return false; - }; - return ; - } + itemUnequip, + vboxHighlight, + vboxSelected, + } = props; - const notValidCombo = vboxHighlight && !vboxHighlight.includes(v); + const { storeSelect, stashSelect } = vboxSelected; - function onClick(type, e) { + const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0; + + function stashClick(e) { e.stopPropagation(); - const combinerContainsIndex = stashSelect.indexOf(i) > -1; - // removing - if (combinerContainsIndex) { - if (type === 'click') { - return setVboxSelected({ storeSelect, stashSelect: without(stashSelect, i) }); - } - return true; - } - - if (notValidCombo) { - setInfo(vbox.bound[i]); - return setVboxSelected({ storeSelect: [], stashSelect: [i] }); - } - - return setVboxSelected({ storeSelect, stashSelect: [...stashSelect, i] }); + if (itemUnequip.length) return sendItemUnequip(itemUnequip); + if (vboxSelecting) return vboxBuySelected(); + return true; } - const highlighted = stashSelect.indexOf(i) > -1; - const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : ''; - const classes = highlighted - ? 'highlight' - : `${border} ${notValidCombo ? 'fade' : ''}`; + function stashBtn(v, i) { + const stashHighlight = vboxSelecting || itemUnequip.length; - const invObject = shapes[v] ? shapes[v]() : v; + if (!v && v !== 0) { + const emptyInvClick = () => { + if (vboxSelecting) return vboxBuySelected(); + return false; + }; + return ; + } + + const notValidCombo = vboxHighlight && !vboxHighlight.includes(v); + + function onClick(type, e) { + e.stopPropagation(); + const combinerContainsIndex = stashSelect.indexOf(i) > -1; + // removing + if (combinerContainsIndex) { + if (type === 'click') { + return setVboxSelected({ storeSelect, stashSelect: without(stashSelect, i) }); + } + return true; + } + + if (notValidCombo) { + setInfo(vbox.bound[i]); + return setVboxSelected({ storeSelect: [], stashSelect: [i] }); + } + + return setVboxSelected({ storeSelect, stashSelect: [...stashSelect, i] }); + } + + const highlighted = stashSelect.indexOf(i) > -1; + const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : ''; + const classes = highlighted + ? 'highlight' + : `${border} ${notValidCombo ? 'fade' : ''}`; + + const invObject = shapes[v] ? shapes[v]() : v; + + return ( + + ); + } return ( - +
e.stopPropagation()} + onDragOver={ev => ev.preventDefault()} + onDrop={stashClick} + > + {range(0, 6).map(i => stashBtn(vbox.bound[i], i))} +
); } - - return ( -
e.stopPropagation()} - onDragOver={ev => ev.preventDefault()} - onDrop={stashClick} - > - {range(0, 6).map(i => stashBtn(vbox.bound[i], i))} -
- ); } -module.exports = { stashHdr, stashElement }; +module.exports = addState(stashElement); diff --git a/client/src/components/vbox.store.jsx b/client/src/components/vbox.store.jsx index 50c2e337..25ea4904 100644 --- a/client/src/components/vbox.store.jsx +++ b/client/src/components/vbox.store.jsx @@ -1,112 +1,95 @@ const preact = require('preact'); +const { connect } = require('preact-redux'); const range = require('lodash/range'); const shapes = require('./shapes'); -function storeHdr(props) { - const { - instance, - tutorial, - sendVboxDiscard, - vbox, - vboxHover, - } = props; +const addState = connect(({ vboxHighlight }) => ({ vboxHighlight })); - return ( -
-

e.target.scrollIntoView(true)} - onMouseOver={e => vboxHover(e, 'store')}> STORE -

-

vboxHover(e, 'bits')}> - {vbox.bits}b -

- -
- ); -} - - -function storeElement(props) { - const { - clearVboxSelected, - setVboxSelected, - storeSelect, - stashSelect, - vbox, - vboxHighlight, - vboxHover, - } = props; - - function availableBtn(v, group, index) { - if (!v) return ; - const selected = storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index); - - const notValidCombo = vboxHighlight && !vboxHighlight.includes(v); - - function onClick(e) { - e.stopPropagation(); - if (storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index)) { - return setVboxSelected( - { storeSelect: storeSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect } - ); - } - - if (!storeSelect.length && !stashSelect.length) { - return setVboxSelected({ storeSelect: [[group, index]], stashSelect }); - } - if (notValidCombo) { - return setVboxSelected({ storeSelect: [[group, index]], stashSelect: [] }); - } - return setVboxSelected({ storeSelect: [...storeSelect, [group, index]], stashSelect }); - } - - - const classes = selected - ? `${v.toLowerCase()} highlight` - : `${v.toLowerCase()} ${notValidCombo ? 'fade' : ''}`; - - const vboxObject = shapes[v] ? shapes[v]() : v; - const disabled = vbox.bits <= group; - return ( - - ); +class storeElement extends preact.Component { + shouldComponentUpdate(newProps) { + if (newProps.clearVboxSelected !== this.props.clearVboxSelected) return true; + if (newProps.setVboxSelected !== this.props.setVboxSelected) return true; + if (newProps.vbox !== this.props.vbox) return true; + if (newProps.vboxHighlight !== this.props.vboxHighlight) return true; + if (newProps.vboxHover !== this.props.vboxHover) return true; + if (newProps.vboxSelected !== this.props.vboxSelected) return true; + return false; } - return ( -
e.stopPropagation()}> -
- {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} + render(props) { + const { + // passed + clearVboxSelected, + setVboxSelected, + vbox, + vboxHover, + vboxSelected, + // state + vboxHighlight, + } = props; + + const { storeSelect, stashSelect } = vboxSelected; + + function availableBtn(v, group, index) { + if (!v) return ; + const selected = storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index); + + const notValidCombo = vboxHighlight && !vboxHighlight.includes(v); + + function onClick(e) { + e.stopPropagation(); + if (storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index)) { + return setVboxSelected( + { storeSelect: storeSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect } + ); + } + + if (!storeSelect.length && !stashSelect.length) { + return setVboxSelected({ storeSelect: [[group, index]], stashSelect }); + } + if (notValidCombo) { + return setVboxSelected({ storeSelect: [[group, index]], stashSelect: [] }); + } + return setVboxSelected({ storeSelect: [...storeSelect, [group, index]], stashSelect }); + } + + + const classes = selected + ? `${v.toLowerCase()} highlight` + : `${v.toLowerCase()} ${notValidCombo ? 'fade' : ''}`; + + const vboxObject = shapes[v] ? shapes[v]() : v; + const disabled = vbox.bits <= group; + return ( + + ); + } + + return ( +
e.stopPropagation()}> +
+ {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} +
+
+ {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} + {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))} +
-
- {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} - {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))} -
-
- ); + ); + } } -module.exports = { storeHdr, storeElement }; +module.exports = addState(storeElement); From 79f5845e4862aa4a773fdb9d53eb6f595a6144e7 Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 26 Nov 2019 13:32:23 +1000 Subject: [PATCH 79/97] comments --- client/src/components/vbox.combiner.jsx | 2 ++ client/src/components/vbox.info.jsx | 2 ++ client/src/components/vbox.stash.jsx | 3 ++- client/src/components/vbox.store.jsx | 4 ++-- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index cf42547b..2767b956 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -15,10 +15,12 @@ class Combiner extends preact.Component { render(args) { const { + // passed props vbox, vboxSelected, vboxBuySelected, sendVboxCombine, + // state props vboxCombiner, } = args; diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index e71d75a0..bec74e6f 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -24,7 +24,9 @@ class Info extends preact.Component { render(props) { const { + // passed props clearTutorial, + // connect state props info, player, tutorial, diff --git a/client/src/components/vbox.stash.jsx b/client/src/components/vbox.stash.jsx index eab47d50..97511443 100644 --- a/client/src/components/vbox.stash.jsx +++ b/client/src/components/vbox.stash.jsx @@ -28,13 +28,14 @@ class stashElement extends preact.Component { render(props) { const { + // passed props sendItemUnequip, setInfo, setVboxSelected, vbox, vboxBuySelected, vboxHover, - + // connect state props itemUnequip, vboxHighlight, vboxSelected, diff --git a/client/src/components/vbox.store.jsx b/client/src/components/vbox.store.jsx index 25ea4904..9a168fc6 100644 --- a/client/src/components/vbox.store.jsx +++ b/client/src/components/vbox.store.jsx @@ -19,13 +19,13 @@ class storeElement extends preact.Component { render(props) { const { - // passed + // passed props clearVboxSelected, setVboxSelected, vbox, vboxHover, vboxSelected, - // state + // connect state props vboxHighlight, } = props; From d276edab14294046a20ee4e30028d19afe2e22a4 Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 26 Nov 2019 17:30:52 +1000 Subject: [PATCH 80/97] return of the combo preview --- client/src/actions.jsx | 2 ++ client/src/components/instance.component.jsx | 16 +++++++++- client/src/components/vbox.combos.jsx | 31 ++++++++++++++++---- client/src/components/vbox.component.jsx | 23 +++++---------- client/src/components/vbox.info.jsx | 14 +++++---- client/src/components/vbox.utils.jsx | 4 +-- client/src/reducers.jsx | 4 ++- 7 files changed, 62 insertions(+), 32 deletions(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index ab644966..00b32e31 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -23,7 +23,9 @@ export const setConstructRename = value => ({ type: 'SET_CONSTRUCT_RENAME', valu export const setGame = value => ({ type: 'SET_GAME', value }); export const setGameSkillInfo = value => ({ type: 'SET_GAME_SKILL_INFO', value }); export const setGameEffectInfo = value => ({ type: 'SET_GAME_EFFECT_INFO', value }); + export const setInfo = value => ({ type: 'SET_INFO', value }); +export const setComboPreview = value => ({ type: 'SET_COMBO_PREVIEW', value }); export const setEmail = value => ({ type: 'SET_EMAIL', value }); export const setInvite = value => ({ type: 'SET_INVITE', value }); diff --git a/client/src/components/instance.component.jsx b/client/src/components/instance.component.jsx index 2022f564..6a3a3df2 100644 --- a/client/src/components/instance.component.jsx +++ b/client/src/components/instance.component.jsx @@ -10,10 +10,12 @@ const actions = require('../actions'); const addState = connect( function receiveState(state) { const { + comboPreview, instance, nav, } = state; return { + comboPreview, instance, nav, }; @@ -34,7 +36,12 @@ const addState = connect( return true; } + function clearComboPreview() { + return dispatch(actions.setComboPreview(null)); + } + return { + clearComboPreview, setInfo, clearItems, }; @@ -43,7 +50,9 @@ const addState = connect( function Instance(args) { const { + comboPreview, instance, + clearComboPreview, clearItems, } = args; @@ -58,8 +67,13 @@ function Instance(args) { clearItems(); } + function mouseOver(e) { + e.stopPropagation(); + if (comboPreview) clearComboPreview(); + } + return ( -
+
diff --git a/client/src/components/vbox.combos.jsx b/client/src/components/vbox.combos.jsx index b35e71f7..f3c18682 100644 --- a/client/src/components/vbox.combos.jsx +++ b/client/src/components/vbox.combos.jsx @@ -2,11 +2,28 @@ const preact = require('preact'); const { connect } = require('preact-redux'); const { convertItem } = require('../utils'); +const actions = require('../actions'); const addState = connect( - ({ info, instance, itemInfo, tutorial, vboxInfo }) => ({ - info, instance, itemInfo, tutorial, vboxInfo, - })); + function receiveState(state) { + const { + info, instance, itemInfo, tutorial, vboxInfo, + } = state; + return { + info, instance, itemInfo, tutorial, vboxInfo, + }; + }, + + function receiveDispatch(dispatch) { + function setComboPreview(item) { + return dispatch(actions.setComboPreview(item)); + } + + return { + setComboPreview, + }; + } +); class Combos extends preact.Component { shouldComponentUpdate(newProps) { @@ -25,6 +42,7 @@ class Combos extends preact.Component { itemInfo, tutorial, vboxInfo, + setComboPreview, } = props; if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; @@ -34,8 +52,7 @@ class Combos extends preact.Component { const comboTable = vboxCombos.map((c, i) => { const mouseOver = e => { e.stopPropagation(); - // this.setState({ comboItem: c.item }); - // set comboInfo state here + setComboPreview(c.item); }; const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) ? [
{convertItem(c.components[0])} {convertItem(c.components[1])}
, @@ -56,7 +73,9 @@ class Combos extends preact.Component {

COMBOS

Combine colours and items.
-
e.stopPropagation()}> +
e.stopPropagation()} + onClick={e => e.stopPropagation()}> {comboTable}
diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 7cd5c0dc..f00e9b63 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -15,17 +15,12 @@ const addState = connect( function receiveState(state) { const { ws, + itemUnequip, instance, player, - info, - itemInfo, - itemUnequip, tutorial, - - vboxCombiner, - vboxHighlight, - vboxInfo, vboxSelected, + itemInfo, } = state; function clearTutorial() { @@ -55,20 +50,16 @@ const addState = connect( } return { - player, - instance, - info, - itemInfo, itemUnequip, - sendItemUnequip, + instance, + player, tutorial, - - vboxCombiner, - vboxHighlight, - vboxInfo, vboxSelected, + itemInfo, + clearTutorial, + sendItemUnequip, sendVboxAccept, sendVboxCombine, sendVboxDiscard, diff --git a/client/src/components/vbox.info.jsx b/client/src/components/vbox.info.jsx index bec74e6f..d2eddbec 100644 --- a/client/src/components/vbox.info.jsx +++ b/client/src/components/vbox.info.jsx @@ -5,8 +5,8 @@ const { tutorialStage } = require('../tutorial.utils'); const { genItemInfo } = require('./vbox.utils'); const addState = connect( - ({ info, player, tutorial, vboxInfo, itemInfo, instance }) => ({ - info, player, tutorial, vboxInfo, itemInfo, instance, + ({ info, player, tutorial, vboxInfo, itemInfo, instance, comboPreview }) => ({ + info, player, tutorial, vboxInfo, itemInfo, instance, comboPreview, })); @@ -19,6 +19,7 @@ class Info extends preact.Component { if (newProps.vboxInfo !== this.props.vboxInfo) return true; if (newProps.itemInfo !== this.props.itemInfo) return true; if (newProps.instance !== this.props.instance) return true; + if (newProps.comboPreview !== this.props.comboPreview) return true; return false; } @@ -33,17 +34,18 @@ class Info extends preact.Component { vboxInfo, itemInfo, instance, + comboPreview, } = props; + // dispaly priority + // tutorial -> comboPreview -> vboxInfo -> info if (tutorial) { const tutorialStageInfo = tutorialStage(tutorial, clearTutorial, instance); if (tutorialStageInfo) return tutorialStageInfo; } + if (comboPreview) return genItemInfo(comboPreview, itemInfo, player); + if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player); - // Prioritise the vbox info - if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); - - // check normal info state if (!info) return false; if (info.includes('constructName')) { return ( diff --git a/client/src/components/vbox.utils.jsx b/client/src/components/vbox.utils.jsx index 59830470..2069d66d 100644 --- a/client/src/components/vbox.utils.jsx +++ b/client/src/components/vbox.utils.jsx @@ -69,7 +69,7 @@ function setVboxState(dispatch, vboxSelected, state) { dispatch(actions.setVboxHighlight(vboxHighlight)); } -function genItemInfo(item, itemInfo, player, info) { +function genItemInfo(item, itemInfo, player) { const fullInfo = itemInfo.items.find(i => i.item === item) || INFO[item]; const isSkill = fullInfo.skill; const isSpec = fullInfo.spec; @@ -102,7 +102,7 @@ function genItemInfo(item, itemInfo, player, info) { ?
Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}%
: null; - const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null; + const thresholds = isSpec ? specThresholds(player, fullInfo, item) : null; return (
diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index 0267cf3f..ef43b31a 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -34,7 +34,6 @@ module.exports = { gameEffectInfo: createReducer(null, 'SET_GAME_EFFECT_INFO'), email: createReducer(null, 'SET_EMAIL'), invite: createReducer(null, 'SET_INVITE'), - info: createReducer(null, 'SET_INFO'), instance: createReducer(null, 'SET_INSTANCE'), instanceChat: createReducer(null, 'SET_INSTANCE_CHAT'), instances: createReducer([], 'SET_INSTANCES'), @@ -47,6 +46,9 @@ module.exports = { shop: createReducer(false, 'SET_SHOP'), pvp: createReducer(null, 'SET_PVP'), + info: createReducer(null, 'SET_INFO'), + comboPreview: createReducer(null, 'SET_COMBO_PREVIEW'), + subscription: createReducer(null, 'SET_SUBSCRIPTION'), team: createReducer([], 'SET_TEAM'), From d1dd2b30b69e52f2332537121f303821042c65db Mon Sep 17 00:00:00 2001 From: Mashy Date: Wed, 27 Nov 2019 17:00:40 +1000 Subject: [PATCH 81/97] combat text init --- client/assets/styles/game.less | 18 ++++++++++++++++++ client/src/components/construct.jsx | 18 ++++-------------- client/src/components/game.construct.jsx | 18 ++++++++++++++++++ client/src/events.jsx | 5 +++-- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index ea48cede..c7491100 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -37,6 +37,11 @@ height: 100%; width: 100%; } + + .combat-text { + left: 15%; + top: 60%; + } } .opponent { @@ -72,6 +77,11 @@ "avatar" } + .combat-text { + left: 15%; + top: 40%; + } + .effects { align-self: flex-start; } @@ -145,6 +155,14 @@ } } + .combat-text { + position: absolute; + z-index: 10; + span { + background-color: black; + } + } + .skills { z-index: 2; button { diff --git a/client/src/components/construct.jsx b/client/src/components/construct.jsx index c39b219c..a26ecdd5 100644 --- a/client/src/components/construct.jsx +++ b/client/src/components/construct.jsx @@ -96,26 +96,16 @@ class ConstructAvatar extends Component { } } - -const addStateText = connect( - function receiveState(state) { - const { animText } = state; - return { animText }; - } -); - -function constructText(props) { - const { construct, animText } = props; +function ConstructText(props) { + const { construct } = props; if (!construct) return false; - const text = animText && animText.constructId === construct.id - ? animText.text - : construct.name; + const text = construct.name; return

{text}

; } module.exports = { ConstructAvatar: addState(ConstructAvatar), - ConstructText: addStateText(constructText), + ConstructText, }; diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 4ffede73..59ffc44f 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -12,6 +12,23 @@ const actions = require('../actions'); const SkillBtn = require('./skill.btn'); +const addStateText = connect( + function receiveState(state) { + const { animText } = state; + return { animText }; + } +); + +function combatText(props) { + const { construct, animText } = props; + const text = animText && animText.constructId === construct.id + ?

{animText.text}

+ : null; + return text; +} + +const ConstructAnimationText = addStateText(combatText); + const addState = connect( function receiveState(state) { const { @@ -179,6 +196,7 @@ class GameConstruct extends Component {
{stats}
+
); diff --git a/client/src/events.jsx b/client/src/events.jsx index bb03367b..44b437b0 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -85,7 +85,7 @@ function registerEvents(store) { const newRes = game.resolved.slice(currentGame.resolved.length); return eachSeries(newRes, (r, cb) => { if (!r.event) return cb(); - const timeout = animations.getTime(r.stages); + let timeout = animations.getTime(r.stages); const anims = animations.getObjects(r, game, account); const text = animations.getText(r); store.dispatch(actions.setAnimFocus(animations.getFocusTargets(r, game))); @@ -107,8 +107,9 @@ function registerEvents(store) { } else { setTimeout( () => store.dispatch(actions.setAnimText(text)), - timeout - TIMES.POST_SKILL_DURATION_MS + timeout - TIMES.POST_SKILL_DURATION_MS - 500 ); + timeout -= 500; } } From 5e1b63108c8398793be2a3172849cb5d75904a7e Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 28 Nov 2019 12:01:05 +1000 Subject: [PATCH 82/97] move skill into combat text --- client/assets/styles/game.less | 9 +++- client/src/animations.utils.jsx | 16 ++++---- client/src/components/anims/slay.jsx | 19 ++++----- client/src/components/game.construct.jsx | 48 +++++++++++++++------- client/src/components/targeting.arrows.jsx | 16 +------- client/src/constants.jsx | 2 +- 6 files changed, 60 insertions(+), 50 deletions(-) diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index c7491100..86b9cf14 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -40,7 +40,7 @@ .combat-text { left: 15%; - top: 60%; + top: 40%; } } @@ -158,6 +158,11 @@ .combat-text { position: absolute; z-index: 10; + svg { + display: inline; + height: 1em; + margin-right: 0.1em + } span { background-color: black; } @@ -214,7 +219,7 @@ } &.ko-transition { - animation: target-ko 1s ease-in-out 0s 1; + animation: target-ko 1.1s ease-in-out 0s 1; } &.ko { diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index 21b38925..1e0dd81b 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -128,11 +128,11 @@ function getText(resolution) { let { amount } = event; let css = ''; if (colour === 'Green') { - css = 'green-damage'; + css = 'green'; amount *= -1; } - if (colour === 'Red') css = 'red-damage'; - if (colour === 'Blue') css = 'blue-damage'; + if (colour === 'Red') css = 'red'; + if (colour === 'Blue') css = 'blue'; const mitigationText = mitigation ? `(${mitigation})` @@ -142,7 +142,7 @@ function getText(resolution) { if (type === 'Healing') { const { amount, overhealing } = event; - return { text: `${amount} (${overhealing} OH)`, css: 'green-damage' }; + return { text: `${amount} (${overhealing} OH)`, css: 'green' }; } if (type === 'Inversion') { @@ -160,9 +160,9 @@ function getText(resolution) { if (type === 'Recharge') { const { red, blue } = event; - if (red > 0 && blue > 0) return { text: [`+${red}R +${blue}B`, ''], css: 'rb-damage' }; - if (red > 0) return { text: [`+${red}R`, ''], css: 'red-damage' }; - if (blue > 0) return { text: [`+${blue}B`, ''], css: 'blue-damage' }; + if (red > 0 && blue > 0) return { text: [`+${red}R +${blue}B`, ''], css: 'rb' }; + if (red > 0) return { text: [`+${red}R`, ''], css: 'red' }; + if (blue > 0) return { text: [`+${blue}B`, ''], css: 'blue' }; return nullText; } @@ -178,12 +178,14 @@ function getText(resolution) { const { green, red, blue } = resolution.target; const { text, css, effects } = generatePostSkill(); + const skill = resolution.event[1] ? resolution.event[1].skill : null; return { css, text, effects, life: { green, red, blue }, constructId: resolution.target.id, + skill, }; } diff --git a/client/src/components/anims/slay.jsx b/client/src/components/anims/slay.jsx index 31bc57d2..a65de8cd 100644 --- a/client/src/components/anims/slay.jsx +++ b/client/src/components/anims/slay.jsx @@ -4,9 +4,6 @@ const anime = require('animejs').default; const { connect } = require('preact-redux'); const { TIMES } = require('../../constants'); -const { randomPoints } = require('../../utils'); - -const duration = TIMES.TARGET_DURATION_MS; const addState = connect( function receiveState(state) { @@ -95,17 +92,17 @@ class Slay extends Component { this.animations.push(anime({ targets: '#slay', opacity: [ - { value: 1, delay: TIMES.TARGET_DELAY_MS, duration: TIMES.TARGET_DURATION_MS * 0.3 }, + { value: 1, delay: TIMES.TARGET_DELAY_MS, duration: TIMES.TARGET_DURATION_MS * 0.2 }, { value: 0, - delay: TIMES.TARGET_DURATION_MS * 0.7 + TIMES.POST_SKILL_DURATION_MS * 0.8, - duration: TIMES.POST_SKILL_DURATION_MS * 0.2, + delay: TIMES.TARGET_DURATION_MS + TIMES.POST_SKILL_DURATION_MS * 0.2, + duration: TIMES.POST_SKILL_DURATION_MS * 0.3, }], translateY: 0, translateX: 0, loop: false, delay: TIMES.TARGET_DELAY_MS, - duration: (duration * 1 / 2), + duration: (TIMES.TARGET_DURATION_MS * 0.5), easing: 'easeInQuad', })); @@ -113,15 +110,15 @@ class Slay extends Component { targets: ['#slayFilter feTurbulence', '#slayFilter feDisplacementMap'], baseFrequency: 10, scale: 100, - delay: (TIMES.TARGET_DELAY_MS + duration * 1 / 2), - duration: (duration * 1 / 2), + delay: (TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS * 0.5), + duration: (TIMES.TARGET_DURATION_MS * 0.5), easing: 'easeInQuad', })); this.animations.push(anime({ targets: '#sword', opacity: 0, - delay: (TIMES.TARGET_DELAY_MS + duration + TIMES.POST_SKILL_DURATION_MS * 0.7), + delay: (TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS), })); const projectiles = document.querySelectorAll('#slay circle'); @@ -130,7 +127,7 @@ class Slay extends Component { targets: proj, cx: Math.random() * 250 + 25, cy: Math.random() * 200 - 100, - delay: (TIMES.TARGET_DELAY_MS + duration + TIMES.POST_SKILL_DURATION_MS * 0.7), + delay: (TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS + TIMES.POST_SKILL_DURATION_MS * 0.2), duration: (TIMES.POST_SKILL_DURATION_MS * 0.3), easing: 'easeInQuad', })); diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 59ffc44f..58579c6a 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -4,7 +4,7 @@ const preact = require('preact'); const range = require('lodash/range'); const reactStringReplace = require('react-string-replace'); -const { STATS } = require('../utils'); +const { STATS, removeTier } = require('../utils'); const { ConstructAvatar, ConstructText } = require('./construct'); const shapes = require('./shapes'); const { INFO } = require('./../constants'); @@ -12,19 +12,38 @@ const actions = require('../actions'); const SkillBtn = require('./skill.btn'); -const addStateText = connect( - function receiveState(state) { - const { animText } = state; - return { animText }; - } -); +const addStateText = connect(({ animText, itemInfo }) => ({ animText, itemInfo })); -function combatText(props) { - const { construct, animText } = props; - const text = animText && animText.constructId === construct.id - ?

{animText.text}

- : null; - return text; +class combatText extends preact.Component { + shouldComponentUpdate(newProps) { + if (newProps.animText !== this.props.animText) return true; + return false; + } + + render(props) { + const { construct, animText, itemInfo } = props; + if (animText && animText.constructId === construct.id) { + const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animText.skill)); + const itemSourceInfo = itemSource.length + ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` + : false; + const itemRegEx = /(Red|Blue|Green)/; + const itemSourceDescription = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); + + return ( +
+

+ {animText.skill} +

+ {itemSourceDescription} +

+ {animText.text} +

+
+ ); + } + return null; + } } const ConstructAnimationText = addStateText(combatText); @@ -137,6 +156,7 @@ class GameConstruct extends Component { const koEvent = animText ? animText.text === 'KO!' && animText.constructId === construct.id : false; const ko = construct.green_life.value === 0 && !koEvent ? 'ko' : ''; const classes = eventClasses(animating, animFocus, construct, animText); + const cssClass = ['ko-transition', 'unfocus'].includes(classes) ? classes : null; const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
@@ -187,7 +207,7 @@ class GameConstruct extends Component { setTutorialGameClear(activeSkill, tutorialGame); }} style={ activeSkill ? { cursor: 'pointer' } : {}} - class={`game-construct ${ko} ${classes}`} > + class={`game-construct ${ko} ${cssClass}`}>
{crypSkills} {effectBox()} diff --git a/client/src/components/targeting.arrows.jsx b/client/src/components/targeting.arrows.jsx index a7a7e4b3..bed48261 100644 --- a/client/src/components/targeting.arrows.jsx +++ b/client/src/components/targeting.arrows.jsx @@ -81,21 +81,7 @@ class TargetSvg extends Component { // resolutions happening // just put skill name up - if (animating) { - if (!animSkill) return false; - const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animSkill)); - const itemSourceInfo = itemSource.length - ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` - : false; - const itemRegEx = /(Red|Blue|Green)/; - const itemSourceDescription = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); - return ( -
-

{animSkill}

-
{itemSourceDescription}
-
- ); - } + if (animating) return false; const playerTeam = game.players.find(t => t.id === account.id); const otherTeam = game.players.find(t => t.id !== account.id); diff --git a/client/src/constants.jsx b/client/src/constants.jsx index f16b7f3b..bcfa054d 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -3,7 +3,7 @@ const preact = require('preact'); const SOURCE_DURATION_MS = 1000; // Time for SOURCE ONLY const TARGET_DELAY_MS = 500; // Used for Source + Target const TARGET_DURATION_MS = 1500; // Time for TARGET ONLY -const POST_SKILL_DURATION_MS = 1000; // Time for all POST +const POST_SKILL_DURATION_MS = 1100; // Time for all POST const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS; // SOURCE + TARGET time module.exports = { From 51edec11fd97b9d0bdf1e59d2111409c9743f44f Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 28 Nov 2019 14:54:35 +1000 Subject: [PATCH 83/97] fixed recharge event --- WORKLOG.md | 1 - client/src/animations.utils.jsx | 6 ++-- client/src/components/game.construct.jsx | 41 +++++++++++++++++------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/WORKLOG.md b/WORKLOG.md index 39803600..d254b298 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -30,7 +30,6 @@ Hexagon Set - Increase intensity for each visit _mashy_ -* add back combo preview * floating combat text combat (start opposite hp and float towards it) to speed up animations * represent construct colours during game phase (try %bar or dots) * buy from preview if you have the required bases in vbox / inventory diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index 1e0dd81b..461abe84 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -160,9 +160,9 @@ function getText(resolution) { if (type === 'Recharge') { const { red, blue } = event; - if (red > 0 && blue > 0) return { text: [`+${red}R +${blue}B`, ''], css: 'rb' }; - if (red > 0) return { text: [`+${red}R`, ''], css: 'red' }; - if (blue > 0) return { text: [`+${blue}B`, ''], css: 'blue' }; + if (red > 0 && blue > 0) return { text: `+${red}R +${blue}B`, css: 'rb' }; + if (red > 0) return { text: `+${red}R`, css: 'red' }; + if (blue > 0) return { text: `+${blue}B`, css: 'blue' }; return nullText; } diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 58579c6a..2f1c0617 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -23,22 +23,39 @@ class combatText extends preact.Component { render(props) { const { construct, animText, itemInfo } = props; if (animText && animText.constructId === construct.id) { - const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animText.skill)); - const itemSourceInfo = itemSource.length - ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` - : false; - const itemRegEx = /(Red|Blue|Green)/; - const itemSourceDescription = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); + const itemSourceDescription = () => { + const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animText.skill)); + const itemSourceInfo = itemSource.length + ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` + : false; + const itemRegEx = /(Red|Blue|Green)/; + return reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); + }; - return ( -
-

- {animText.skill} -

- {itemSourceDescription} + const animationTextHtml = () => { + // monkaW hack to make red / blue recharge work nicely + if (animText.css === 'rb') { + const text = animText.text.split(' '); + return ( +

+ {text[0]}  + {text[1]} +

+ ); + } + return (

{animText.text}

+ ); + }; + + + return ( +
+

{animText.skill}

+ {itemSourceDescription()} + {animationTextHtml()}
); } From 33ad4db8f590b4d8207148daf4732c84a8f42a39 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 28 Nov 2019 15:43:48 +1000 Subject: [PATCH 84/97] server --- server/src/instance.rs | 36 +++-- server/src/player.rs | 287 ++++++++++++++++++++++++++------------- server/src/rpc.rs | 31 ++--- server/src/vbox.rs | 297 ++++++++++++++++++++++++++--------------- 4 files changed, 419 insertions(+), 232 deletions(-) diff --git a/server/src/instance.rs b/server/src/instance.rs index c5ec9c04..0d052d08 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -15,7 +15,7 @@ use chrono::prelude::*; use chrono::Duration; use account::Account; -use account; +use vbox; use player::{Player, Score, player_create}; @@ -466,35 +466,35 @@ impl Instance { Ok(()) } - pub fn vbox_discard(mut self, account: Uuid) -> Result { + pub fn vbox_refill(mut self, account: Uuid) -> Result { self.vbox_action_allowed(account)?; self.account_player(account)? - .vbox_discard()?; + .vbox_refill()?; Ok(self) } - pub fn vbox_accept(mut self, account: Uuid, group: usize, index: usize, construct_id: Option) -> Result { + pub fn vbox_buy(mut self, account: Uuid, group: vbox::ItemType, index: String, construct_id: Option) -> Result { self.vbox_action_allowed(account)?; self.account_player(account)? - .vbox_accept(group, index, construct_id)?; + .vbox_buy(group, index, construct_id)?; Ok(self) } - pub fn vbox_combine(mut self, account: Uuid, inv_indices: Vec, vbox_indices: Vec>) -> Result { + pub fn vbox_combine(mut self, account: Uuid, inv_indices: Vec, vbox_indices: vbox::VboxIndices) -> Result { self.vbox_action_allowed(account)?; self.account_player(account)? .vbox_combine(inv_indices, vbox_indices)?; Ok(self) } - pub fn vbox_reclaim(mut self, account: Uuid, index: usize) -> Result { + pub fn vbox_refund(mut self, account: Uuid, index: String) -> Result { self.vbox_action_allowed(account)?; self.account_player(account)? - .vbox_reclaim(index)?; + .vbox_refund(index)?; Ok(self) } - pub fn vbox_apply(mut self, account: Uuid, index: usize, construct_id: Uuid) -> Result { + pub fn vbox_apply(mut self, account: Uuid, index: String, construct_id: Uuid) -> Result { self.vbox_action_allowed(account)?; self.account_player(account)? .vbox_apply(index, construct_id)?; @@ -834,19 +834,17 @@ mod tests { fn instance_pve_test() { let mut instance = Instance::new(); - let bot_player = bot_player(); - let bot = bot_player.id; - instance.add_player(bot_player).unwrap(); + let bot = bot_player(); + let bot_one = bot.id; + instance.add_player(bot).unwrap(); - let player_account = Uuid::new_v4(); - let constructs = instance_mobs(player_account); - let player = Player::new(player_account, &"test".to_string(), constructs).set_bot(true); - - instance.add_player(player).expect("could not add player"); + let bot = bot_player(); + let bot_two = bot.id; + instance.add_player(bot).unwrap(); assert_eq!(instance.phase, InstancePhase::Lobby); - instance.player_ready(player_account).unwrap(); - instance.player_ready(bot).unwrap(); + instance.player_ready(bot_one).unwrap(); + instance.player_ready(bot_two).unwrap(); assert_eq!(instance.phase, InstancePhase::Finished); } diff --git a/server/src/player.rs b/server/src/player.rs index 6a0a5abd..9b1fbeca 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -1,3 +1,5 @@ +use std::collections::{HashMap}; + use uuid::Uuid; use rand::prelude::*; @@ -9,7 +11,7 @@ use failure::err_msg; use account; use account::Account; use construct::{Construct, Colours}; -use vbox::{Vbox}; +use vbox::{Vbox, ItemType, VboxIndices}; use item::{Item, ItemEffect}; use effect::{Effect}; @@ -155,124 +157,228 @@ impl Player { pub fn autobuy(&mut self) -> &mut Player { let mut rng = thread_rng(); - // first check if any constructs have no skills - // if there is one find an item in vbox that gives a skill - while let Some(c) = self.constructs.iter().position(|c| c.skills.len() == 0) { - if let Some(s) = self.vbox.bound.iter().position(|v| v.into_skill().is_some()) { - let construct_id = self.constructs[c].id; - self.vbox_apply(s, construct_id).expect("could not apply"); + // skill buying phase + while self.constructs.iter().any(|c| c.skills.len() < 3) { + // find the construct with the smallest number of skills + let construct_id = match self.constructs.iter().min_by_key(|c| c.skills.len()) { + None => panic!("no constructs in autobuy"), + Some(c) => c.id, + }; + + let i = self.vbox.stash.iter() + .find(|(_i, v)| v.into_skill().is_some()) + .map(|(i, _v)| i.clone()); + + // got a skill in stash + if let Some(i) = i { + // AAAAAAAAAAAAAAAAAAAA + // there's a bad bug here where if this apply fails + // the item in question will be silently dropped + self.vbox_apply(i, construct_id).ok(); continue; } - info!("no skills available..."); - } + // need to buy one + else { - // now keep buying and applying items cause whynot - // inb4 montecarlo gan + // do we have any colours in store? + let colours = self.vbox.store[&ItemType::Colours].keys() + .cloned() + .collect::>(); - loop { - let (target_construct_i, target_construct_id) = match self.constructs.iter().any(|c| c.skills.len() < 3) { - true => { - let mut target_construct_i = 0; - for (j, c) in self.constructs.iter().enumerate() { - if c.skills.len() < self.constructs[target_construct_i].skills.len() { - target_construct_i = j; + // how about a base skill? + let base = match self.vbox.store[&ItemType::Skills].iter().next() { + Some(b) => Some(b.0.clone()), + None => None, + }; + + // if no: try to refill and start again + match colours.len() < 2 || base.is_none() { + true => match self.vbox_refill() { + Ok(_) => continue, + Err(_) => break, // give up + }, + false => { + let mut vbox_items = HashMap::new(); + vbox_items.insert(ItemType::Colours, colours); + vbox_items.insert(ItemType::Skills, vec![base.unwrap()]); + + match self.vbox_combine(vec![], Some(vbox_items)) { + Ok(_) => continue, + Err(_) => break, // give up } } - (target_construct_i, self.constructs[target_construct_i].id) - }, - false => { - let i = rng.gen_range(0, 3); - (i, self.constructs[i].id) - }, - }; - - let needs_skills = self.constructs[target_construct_i].skills.len() < 3; - let group_i = match needs_skills { - true => 1, - false => 2, - }; - - - let num_colours = self.vbox.bound - .iter() - .filter(|v| [Item::Red, Item::Green, Item::Blue].contains(v)) - .count(); - - if self.vbox.bound.len() < 3 || num_colours < 2 { - if (needs_skills && self.vbox.bits < 4) || self.vbox.bits < 5 { - // info!("insufficient balance"); - break; } - - // get 2 colours and something else - let free_colours = self.vbox.free[0].iter().fold(0, |count, item| { - match item.is_some() { - true => count + 1, - false => count - } - }); - if free_colours < 2 { - break; - } - self.bot_vbox_accept(0).expect("could't accept colour item"); - self.bot_vbox_accept(0).expect("could't accept colour item"); - self.bot_vbox_accept(group_i).expect("could't accept group item"); } + } - // info!("{:?}", self.vbox.bound); - - let skills = [Item::Attack, Item::Block, Item::Buff, Item::Debuff, Item::Stun]; - let combo_i = match group_i { - 1 => self.vbox.bound.iter().position(|v| skills.contains(v)).expect("no skill found"), - 2 => self.vbox.bound.iter().position(|v| v.into_spec().is_some()).expect("no spec found"), - _ => panic!("unknown group_i"), + // spec buying phase + while self.constructs.iter().any(|c| c.specs.len() < 3) { + // find the construct with the smallest number of skills + let construct_id = match self.constructs.iter().min_by_key(|c| c.specs.len()) { + None => panic!("no constructs in autobuy"), + Some(c) => c.id, }; - // first 2 colours can be whatever - self.vbox_combine(vec![0, 1, combo_i], vec![]).ok(); - let item_i = self.vbox.bound.len() - 1; - self.vbox_apply(item_i, target_construct_id).ok(); + let i = self.vbox.stash.iter() + .find(|(_i, v)| v.into_spec().is_some()) + .map(|(i, _v)| i.clone()); + + // got a skill in stash + if let Some(i) = i { + // AAAAAAAAAAAAAAAAAAAA + // there's a bad bug here where if this apply fails + // the item in question will be silently dropped + self.vbox_apply(i, construct_id).ok(); + continue; + } + // need to buy one + else { + // do we have any colours in store? + let colours = self.vbox.store[&ItemType::Colours].keys() + .cloned() + .collect::>(); + + // how about a base spec? + let base = match self.vbox.store[&ItemType::Specs].iter().next() { + Some(b) => Some(b.0.clone()), + None => None, + }; + + // if no: try to refill and start again + match colours.len() < 2 || base.is_none() { + true => match self.vbox_refill() { + Ok(_) => continue, + Err(_) => break, // give up + }, + false => { + let mut vbox_items = HashMap::new(); + vbox_items.insert(ItemType::Colours, colours); + vbox_items.insert(ItemType::Specs, vec![base.unwrap()]); + + match self.vbox_combine(vec![], Some(vbox_items)) { + Ok(_) => continue, + Err(_) => break, // give up + } + } + } + } } + // upgrading phase + // NYI + + // // first check if any constructs have no skills + // // if there is one find an item in vbox that gives a skill + // while let Some(c) = self.constructs.iter().position(|c| c.skills.len() == 0) { + // if let Some(s) = self.vbox.stash.iter().position(|(i, v)| v.into_skill().is_some()) { + // let construct_id = self.constructs[c].id; + // self.vbox_apply(s, construct_id).expect("could not apply"); + // continue; + // } + // info!("no skills available..."); + // } + + // // now keep buying and applying items cause whynot + // // inb4 montecarlo gan + // loop { + // let (target_construct_i, target_construct_id) = match self.constructs.iter().any(|c| c.skills.len() < 3) { + // true => { + // let mut target_construct_i = 0; + // for (j, c) in self.constructs.iter().enumerate() { + // if c.skills.len() < self.constructs[target_construct_i].skills.len() { + // target_construct_i = j; + // } + // } + // (target_construct_i, self.constructs[target_construct_i].id) + // }, + // false => { + // let i = rng.gen_range(0, 3); + // (i, self.constructs[i].id) + // }, + // }; + + // let needs_skills = self.constructs[target_construct_i].skills.len() < 3; + // let group_i = match needs_skills { + // true => 1, + // false => 2, + // }; + + + // let num_colours = self.vbox.stash + // .iter() + // .filter(|(i, v)| [Item::Red, Item::Green, Item::Blue].contains(v)) + // .count(); + + // if self.vbox.stash.len() < 3 || num_colours < 2 { + // if (needs_skills && self.vbox.bits < 4) || self.vbox.bits < 5 { + // // info!("insufficient balance"); + // break; + // } + + // // get 2 colours and something else + // let store_colours = self.vbox.store[&ItemType::Colours].len(); + // if store_colours < 2 { + // break; + // } + // self.bot_vbox_accept(0).expect("could't accept colour item"); + // self.bot_vbox_accept(0).expect("could't accept colour item"); + // self.bot_vbox_accept(group_i).expect("could't accept group item"); + // } + + // // info!("{:?}", self.vbox.stash); + + // let skills = [Item::Attack, Item::Block, Item::Buff, Item::Debuff, Item::Stun]; + // let combo_i = match group_i { + // 1 => self.vbox.stash.iter().position(|v| skills.contains(v)).expect("no skill found"), + // 2 => self.vbox.stash.iter().position(|v| v.into_spec().is_some()).expect("no spec found"), + // _ => panic!("unknown group_i"), + // }; + + // // first 2 colours can be whatever + // self.vbox_combine(vec![0, 1, combo_i], vec![]).ok(); + // let item_i = self.vbox.stash.len() - 1; + // self.vbox_apply(item_i, target_construct_id).ok(); + // } + return self; } - pub fn vbox_discard(&mut self) -> Result<&mut Player, Error> { + pub fn vbox_refill(&mut self) -> Result<&mut Player, Error> { self.vbox.balance_sub(DISCARD_COST)?; self.vbox.fill(); Ok(self) } - pub fn bot_vbox_accept(&mut self, group: usize) -> Result<&mut Player, Error> { - self.vbox.bot_accept(group)?; + pub fn bot_vbox_accept(&mut self, group: ItemType) -> Result<&mut Player, Error> { + let item = self.vbox.bot_buy(group)?; + self.vbox.stash_add(item, None)?; Ok(self) } - pub fn vbox_accept(&mut self, group: usize, index: usize, construct_id: Option) -> Result<&mut Player, Error> { - self.vbox.accept(group, index, construct_id)?; - if construct_id.is_some() { - let equip_index = self.vbox.bound.len() - 1; - self.vbox_apply(equip_index, construct_id.expect("no construct"))?; - } + pub fn vbox_buy(&mut self, group: ItemType, index: String, construct_id: Option) -> Result<&mut Player, Error> { + let item = self.vbox.buy(group, &index)?; + + match construct_id { + Some(id) => { self.vbox_apply(index, id)?; }, + None => { self.vbox.stash_add(item, None)?; }, + }; + Ok(self) } - pub fn vbox_combine(&mut self, inv_indices: Vec, vbox_indices: Vec>) -> Result<&mut Player, Error> { + pub fn vbox_combine(&mut self, inv_indices: Vec, vbox_indices: VboxIndices) -> Result<&mut Player, Error> { self.vbox.combine(inv_indices, vbox_indices)?; Ok(self) } - pub fn vbox_reclaim(&mut self, index: usize) -> Result<&mut Player, Error> { - self.vbox.reclaim(index)?; + pub fn vbox_refund(&mut self, index: String) -> Result<&mut Player, Error> { + self.vbox.refund(index)?; Ok(self) } - pub fn vbox_apply(&mut self, index: usize, construct_id: Uuid) -> Result<&mut Player, Error> { - if self.vbox.bound.get(index).is_none() { - return Err(format_err!("no item at index {:?}", index)); - } - - let item = self.vbox.bound.remove(index); + pub fn vbox_apply(&mut self, index: String, construct_id: Uuid) -> Result<&mut Player, Error> { + let item = self.vbox.stash.remove(&index) + .ok_or(format_err!("no item at index {:?} {:?}", self.vbox.stash, index))?; match item.effect() { Some(ItemEffect::Skill) => { @@ -317,8 +423,8 @@ impl Player { } pub fn vbox_unequip(&mut self, target: Item, construct_id: Uuid, target_construct_id: Option) -> Result<&mut Player, Error> { - if self.vbox.bound.len() >= 9 && !target_construct_id.is_some() { - return Err(err_msg("too many items bound")); + if self.vbox.stash.len() >= 9 && !target_construct_id.is_some() { + return Err(err_msg("too many items stash")); } match target.effect() { @@ -349,13 +455,12 @@ impl Player { construct.apply_modifiers(&player_colours); } - self.vbox.bound.push(target); + let equip_index = self.vbox.stash_add(target, None)?; if target_construct_id.is_some() { - let equip_index = self.vbox.bound.len() - 1; self.vbox_apply(equip_index, target_construct_id.expect("no construct"))?; } - // self.vbox.bound.sort_unstable(); + // self.vbox.stash.sort_unstable(); Ok(self) } @@ -408,8 +513,8 @@ mod tests { let player_account = Uuid::new_v4(); let constructs = instance_mobs(player_account); let mut player = Player::new(player_account, &"test".to_string(), constructs).set_bot(true); - player.vbox.fill(); + player.vbox.fill(); player.autobuy(); assert!(player.constructs.iter().all(|c| c.skills.len() >= 1)); diff --git a/server/src/rpc.rs b/server/src/rpc.rs index bc0ba493..9f43a928 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::time::{Instant}; use std::thread::{spawn}; @@ -34,7 +35,7 @@ use mail::Email; use pg::{Db}; use pg::{PgPool}; use skill::{Skill, dev_resolve, Resolutions}; -use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip}; +use vbox::{ItemType, vbox_buy, vbox_apply, vbox_refill, vbox_combine, vbox_refund, vbox_unequip}; use http::{AUTH_CLEAR, TOKEN_HEADER}; #[derive(Debug,Clone,Serialize)] @@ -114,14 +115,14 @@ pub enum RpcRequest { InstanceState { instance_id: Uuid }, InstanceChat { instance_id: Uuid, index: usize }, - VboxAccept { instance_id: Uuid, group: usize, index: usize }, - VboxAcceptEquip { instance_id: Uuid, group: usize, index: usize, construct_id: Uuid }, - VboxDiscard { instance_id: Uuid }, - VboxCombine { instance_id: Uuid, inv_indices: Vec, vbox_indices: Vec> }, - VboxApply { instance_id: Uuid, construct_id: Uuid, index: usize }, + VboxBuy { instance_id: Uuid, group: ItemType, index: String }, + VboxBuyEquip { instance_id: Uuid, group: ItemType, index: String, construct_id: Uuid }, + VboxRefill { instance_id: Uuid }, + VboxCombine { instance_id: Uuid, inv_indices: Vec, vbox_indices: Option>> }, + VboxApply { instance_id: Uuid, construct_id: Uuid, index: String }, VboxUnequip { instance_id: Uuid, construct_id: Uuid, target: Item }, VboxUnequipApply { instance_id: Uuid, construct_id: Uuid, target: Item, target_construct_id: Uuid }, - VboxReclaim { instance_id: Uuid, index: usize }, + VboxRefund { instance_id: Uuid, index: String }, } struct Connection { @@ -245,11 +246,11 @@ impl Connection { RpcRequest::InstanceAbandon { instance_id } => Ok(instance_abandon(&mut tx, account, instance_id)?), - RpcRequest::VboxAccept { instance_id, group, index } => - Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index, None)?)), + RpcRequest::VboxBuy { instance_id, group, index } => + Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, None)?)), - RpcRequest::VboxAcceptEquip { instance_id, group, index, construct_id } => - Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index, Some(construct_id))?)), + RpcRequest::VboxBuyEquip { instance_id, group, index, construct_id } => + Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, Some(construct_id))?)), RpcRequest::VboxApply { instance_id, construct_id, index } => Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)), @@ -257,11 +258,11 @@ impl Connection { RpcRequest::VboxCombine { instance_id, inv_indices, vbox_indices } => Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, inv_indices, vbox_indices)?)), - RpcRequest::VboxDiscard { instance_id } => - Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)), + RpcRequest::VboxRefill { instance_id } => + Ok(RpcMessage::InstanceState(vbox_refill(&mut tx, account, instance_id)?)), - RpcRequest::VboxReclaim { instance_id, index } => - Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)), + RpcRequest::VboxRefund { instance_id, index } => + Ok(RpcMessage::InstanceState(vbox_refund(&mut tx, account, instance_id, index)?)), RpcRequest::VboxUnequip { instance_id, construct_id, target } => Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target, None)?)), diff --git a/server/src/vbox.rs b/server/src/vbox.rs index faf93fdc..e2507c74 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -1,8 +1,9 @@ use uuid::Uuid; use std::iter; +use std::collections::HashMap; -// reclaims +// refunds use rand::prelude::*; use rand::{thread_rng}; use rand::distributions::{WeightedIndex}; @@ -19,30 +20,48 @@ use construct::{Colours}; use item::*; +pub type VboxIndices = Option>>; + #[derive(Debug,Clone,Serialize,Deserialize)] pub struct Vbox { pub bits: usize, - pub free: Vec>>, - pub bound: Vec, + pub store: HashMap>, + pub stash: HashMap, } +#[derive(Debug,Copy,Clone,Serialize,Deserialize,Hash,PartialEq,Eq)] pub enum ItemType { Colours, Skills, Specs, } +const STORE_COLOURS_CAPACITY: usize = 6; +const STORE_SKILLS_CAPACITY: usize = 3; +const STORE_SPECS_CAPACITY: usize = 3; +const STASH_CAPACITY: usize = 6; +const STARTING_ATTACK_COUNT: usize = 3; + impl Vbox { pub fn new() -> Vbox { - let starting_items = vec![ - Item::Attack, - Item::Attack, - Item::Attack, - ]; + let mut colours: HashMap = HashMap::new(); + let mut skills: HashMap = HashMap::new(); + let mut specs: HashMap = HashMap::new(); + + let store = [ + (ItemType::Colours, colours), + (ItemType::Skills, skills), + (ItemType::Colours, specs), + ].iter().cloned().collect(); + + let mut stash = HashMap::new(); + for i in 0..STARTING_ATTACK_COUNT { + stash.insert(i.to_string(), Item::Attack); + } Vbox { - free: vec![vec![], vec![], vec![]], - bound: starting_items, + store, + stash, bits: 30, } } @@ -65,103 +84,130 @@ impl Vbox { pub fn fill(&mut self) -> &mut Vbox { let mut rng = thread_rng(); - self.free = [ItemType::Colours, ItemType::Skills, ItemType::Specs].iter() - .map(|item_type| { - let items = match item_type { - ItemType::Colours => vec![ - (Some(Item::Red), 1), - (Some(Item::Green), 1), - (Some(Item::Blue), 1), - ], - ItemType::Skills => vec![ - (Some(Item::Attack), 1), - (Some(Item::Block), 1), - (Some(Item::Buff), 1), - (Some(Item::Debuff), 1), - (Some(Item::Stun), 1), - ], - ItemType::Specs => vec![ - (Some(Item::Power), 1), - (Some(Item::Life), 1), - (Some(Item::Speed), 1), - ], - }; + let colours = vec![ + (Item::Red, 1), + (Item::Green, 1), + (Item::Blue, 1), + ]; + let colour_dist = WeightedIndex::new(colours.iter().map(|item| item.1)).unwrap(); - let dist = WeightedIndex::new(items.iter().map(|item| item.1)).unwrap(); - iter::repeat_with(|| { - items[dist.sample(&mut rng)].0}).take(match item_type { - ItemType::Colours => 6, - _ => 3, - }).collect::>>() - }) - .collect::>>>(); + let skills = vec![ + (Item::Attack, 1), + (Item::Block, 1), + (Item::Buff, 1), + (Item::Debuff, 1), + (Item::Stun, 1), + ]; + let skill_dist = WeightedIndex::new(skills.iter().map(|item| item.1)).unwrap(); + + let specs = vec![ + (Item::Power, 1), + (Item::Life, 1), + (Item::Speed, 1), + ]; + let spec_dist = WeightedIndex::new(specs.iter().map(|item| item.1)).unwrap(); + + for item_type in [ItemType::Colours, ItemType::Skills, ItemType::Specs].iter() { + let (items, num, dist) = match item_type { + ItemType::Colours => (&colours, STORE_COLOURS_CAPACITY, &colour_dist), + ItemType::Skills => (&skills, STORE_SKILLS_CAPACITY, &skill_dist), + ItemType::Specs => (&specs, STORE_SPECS_CAPACITY, &spec_dist), + }; + + let drops = iter::repeat_with(|| items[dist.sample(&mut rng)].0) + .take(num) + .enumerate() + .map(|(i, item)| (i.to_string(), item)) + .collect::>(); + + self.store.insert(*item_type, drops); + } self } - pub fn accept(&mut self, i: usize, j: usize, construct_id: Option) -> Result<&mut Vbox, Error> { - if self.bound.len() >= 6 && !construct_id.is_some() { - return Err(err_msg("too many items bound")); - } - + pub fn buy(&mut self, item: ItemType, i: &String) -> Result { // check item exists - self.free - .get(i).ok_or(format_err!("no item group at index {:?}", i))? - .get(j).ok_or(format_err!("no item at index {:?}", j))?; + let selection = self.store + .get_mut(&item).ok_or(format_err!("no item group {:?}", item))? + .remove(i).ok_or(format_err!("no item at index {:?} {:}", item, i))?; - // check can purchase - let cost = match self.free[i][j] { - None => 0, - _ => self.free[i][j].unwrap().cost() - }; - self.balance_sub(cost)?; + self.balance_sub(selection.cost())?; - // actually move - match self.free[i][j] { - None => (), - _ => self.bound.push(self.free[i][j].unwrap()) + Ok(selection) + } + + pub fn stash_add(&mut self, item: Item, index: Option<&String>) -> Result { + if self.stash.len() >= STASH_CAPACITY { + return Err(err_msg("stash full")); } - // self.bound.push(self.free[i][j].unwrap()); - self.free[i][j] = None; - // self.bound.sort_unstable(); - Ok(self) + if let Some(index) = index { + if self.stash.contains_key(index) { + return Err(format_err!("slot occupied {:?}", index)); + } + self.stash.insert(index.clone(), item); + return Ok(index.to_string()); + } + + for i in (0..STASH_CAPACITY).map(|i| i.to_string()) { + if !self.stash.contains_key(&i) { + self.stash.insert(i.clone(), item); + return Ok(i); + } + } + + return Err(err_msg("stash full")); } - pub fn bot_accept(&mut self, i: usize) -> Result<&mut Vbox, Error> { - let buy_index = self.free[i].iter().position(|item| item.is_some()); - self.accept(i, buy_index.expect("no valid buys"), None) + pub fn bot_buy(&mut self, item: ItemType) -> Result { + let buy_index = self.store[&item] + .keys() + .next() + .ok_or(format_err!("no item in group {:?}", item))? + .clone(); + + self.buy(item, &buy_index) } - pub fn reclaim(&mut self, i: usize) -> Result<&mut Vbox, Error> { - self.bound.get(i).ok_or(format_err!("no item at index {:?}", i))?; - let reclaimed = self.bound.remove(i); - let refund = reclaimed.cost(); - // info!("reclaiming {:?} for {:?}", refund, reclaimed); + pub fn refund(&mut self, i: String) -> Result<&mut Vbox, Error> { + let refunded = self.stash.remove(&i) + .ok_or(format_err!("no item at index {:?} {:?}", self.stash, i))?; + + let refund = refunded.cost(); + // info!("refunding {:?} for {:?}", refund, refunded); self.balance_add(refund); Ok(self) } - pub fn combine(&mut self, mut inv_indices: Vec, vbox_indicies: Vec>) -> Result<&mut Vbox, Error> { - if !inv_indices.iter().all(|i| self.bound.get(*i).is_some()) { - return Err(err_msg("item missing index")); - } - // try to buy up the vbox indicies and add them to the inventory indicies for combining - for vi in vbox_indicies.iter() { - inv_indices.push(self.bound.len()); - self.accept(vi[0], vi[1], Some(Uuid::nil()))?; - } + pub fn combine(&mut self, stash_indices: Vec, store_indices: Option>>) -> Result<&mut Vbox, Error> { + // find base item for index to insert into + let base_index = stash_indices.iter() + .find(|i| match self.stash.get(i.clone()) { + Some(item) => item.into_skill().is_some(), + None => false, + }); - // have to sort the indices and keep track of the iteration - // because when removing the elements the array shifts - inv_indices.sort_unstable(); - let mut input = inv_indices + let mut input = stash_indices .iter() - .enumerate() - .map(|(i, index)| { - self.bound.remove(index.saturating_sub(i)) - }) - .collect::>(); + .map(|i| self.stash.remove(i) + .ok_or(format_err!("no item at index {:?} {:?}", self.stash, i))) + .collect::, Error>>()?; + + if let Some(store_indices) = store_indices { + let mut purchased = store_indices.iter() + .map(|(g, list)| + list.iter() + .map(|i| self.buy(*g, i)) + .collect::, Error>>() + ) + .collect::>, Error>>()? + .into_iter() + .flatten() + .collect(); + + input.append(&mut purchased); + } // sort the input to align with the combinations // combos are sorted when created @@ -169,40 +215,37 @@ impl Vbox { let combos = get_combos(); let combo = combos.iter().find(|c| c.components == input).ok_or(err_msg("not a combo"))?; - self.bound.push(combo.item); - // self.bound.sort_unstable(); - if self.bound.len() > 6 { - return Err(err_msg("too many items bound")); - } + self.stash_add(combo.item, base_index)?; + Ok(self) } } -pub fn vbox_discard(tx: &mut Transaction, account: &Account, instance_id: Uuid) -> Result { +pub fn vbox_refill(tx: &mut Transaction, account: &Account, instance_id: Uuid) -> Result { let instance = instance_get(tx, instance_id)? - .vbox_discard(account.id)?; + .vbox_refill(account.id)?; return instance_update(tx, instance); } -pub fn vbox_accept(tx: &mut Transaction, account: &Account, instance_id: Uuid, group: usize, index: usize, construct_id: Option) -> Result { +pub fn vbox_buy(tx: &mut Transaction, account: &Account, instance_id: Uuid, group: ItemType, index: String, construct_id: Option) -> Result { let instance = instance_get(tx, instance_id)? - .vbox_accept(account.id, group, index, construct_id)?; + .vbox_buy(account.id, group, index, construct_id)?; return instance_update(tx, instance); } -pub fn vbox_combine(tx: &mut Transaction, account: &Account, instance_id: Uuid, inv_indices: Vec, vbox_indices: Vec>) -> Result { +pub fn vbox_combine(tx: &mut Transaction, account: &Account, instance_id: Uuid, stash_indices: Vec, vbox_indices: VboxIndices) -> Result { let instance = instance_get(tx, instance_id)? - .vbox_combine(account.id, inv_indices, vbox_indices)?; + .vbox_combine(account.id, stash_indices, vbox_indices)?; return instance_update(tx, instance); } -pub fn vbox_reclaim(tx: &mut Transaction, account: &Account, instance_id: Uuid, index: usize) -> Result { +pub fn vbox_refund(tx: &mut Transaction, account: &Account, instance_id: Uuid, index: String) -> Result { let instance = instance_get(tx, instance_id)? - .vbox_reclaim(account.id, index)?; + .vbox_refund(account.id, index)?; return instance_update(tx, instance); } -pub fn vbox_apply(tx: &mut Transaction, account: &Account, instance_id: Uuid, construct_id: Uuid, index: usize) -> Result { +pub fn vbox_apply(tx: &mut Transaction, account: &Account, instance_id: Uuid, construct_id: Uuid, index: String) -> Result { let instance = instance_get(tx, instance_id)? .vbox_apply(account.id, index, construct_id)?; return instance_update(tx, instance); @@ -221,9 +264,49 @@ mod tests { #[test] fn combine_test() { let mut vbox = Vbox::new(); - vbox.bound = vec![Item::Attack, Item::Green, Item::Green]; - vbox.combine(vec![1,2,0], vec![]).unwrap(); - assert_eq!(vbox.bound[0], Item::Heal); + vbox.stash.insert(0.to_string(), Item::Attack); + vbox.stash.insert(1.to_string(), Item::Green); + vbox.stash.insert(2.to_string(), Item::Green); + vbox.combine(vec![0.to_string(), 1.to_string(), 2.to_string()], None).unwrap(); + assert_eq!(vbox.stash["0"], Item::Heal); + } + + #[test] + fn buy_test() { + let mut vbox = Vbox::new(); + vbox.fill(); + + // cannot rebuy same + vbox.buy(ItemType::Skills, &0.to_string()).unwrap(); + assert!(vbox.store[&ItemType::Skills].get(&0.to_string()).is_none()); + assert!(vbox.buy(ItemType::Skills, &0.to_string()).is_err()); + } + + #[test] + fn capacity_test() { + let mut vbox = Vbox::new(); + vbox.fill(); + vbox.stash_add(Item::Red, None).unwrap(); + vbox.stash_add(Item::Red, None).unwrap(); + vbox.stash_add(Item::Red, None).unwrap(); + assert!(vbox.stash_add(Item::Red, None).is_err()); + } + + #[test] + fn store_and_stash_combine_test() { + let mut vbox = Vbox::new(); + vbox.fill(); + + let mut skill_combine_args = HashMap::new(); + skill_combine_args.insert(ItemType::Colours, vec![0.to_string(), 1.to_string()]); + skill_combine_args.insert(ItemType::Skills, vec![0.to_string()]); + + let mut spec_combine_args = HashMap::new(); + spec_combine_args.insert(ItemType::Colours, vec![2.to_string(), 3.to_string()]); + spec_combine_args.insert(ItemType::Specs, vec![0.to_string()]); + + vbox.combine(vec![], Some(skill_combine_args)).unwrap(); + vbox.combine(vec![], Some(spec_combine_args)).unwrap(); } #[test] @@ -239,10 +322,10 @@ mod tests { } #[test] - fn reclaim_test() { + fn refund_test() { let mut vbox = Vbox::new(); - vbox.bound = vec![Item::Strike]; - vbox.reclaim(0).unwrap(); + vbox.stash.insert(0.to_string(), Item::Strike); + vbox.refund(0.to_string()).unwrap(); assert_eq!(vbox.bits, 32); } From 4920821ec2a6e918a7441458ea16a48fba7f9345 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 28 Nov 2019 15:48:31 +1000 Subject: [PATCH 85/97] rm free and bound --- client/src/components/instance.constructs.jsx | 6 +- client/src/components/vbox.combiner.jsx | 2 +- client/src/components/vbox.component.jsx | 2 +- client/src/components/vbox.stash.jsx | 4 +- client/src/components/vbox.store.jsx | 10 ++-- client/src/components/vbox.utils.jsx | 16 +++--- client/src/tutorial.utils.jsx | 56 +++++++++---------- 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/client/src/components/instance.constructs.jsx b/client/src/components/instance.constructs.jsx index c0a0b36d..3ed752b7 100644 --- a/client/src/components/instance.constructs.jsx +++ b/client/src/components/instance.constructs.jsx @@ -98,7 +98,7 @@ function Construct(props) { const duplicateSkill = construct.skills.length !== 0 && construct.skills.every(sk => { if (!itemEquip && itemEquip !== 0) return false; if (!sk) return false; - return sk.skill === vbox.bound[itemEquip]; + return sk.skill === vbox.stash[itemEquip]; }); const tutorialDisableEquip = tutorialShouldDisableEquip(tutorial, iter, instance, construct); function onClick(e) { @@ -136,7 +136,7 @@ function Construct(props) { return true; } - const equipping = skillList.includes(vbox.bound[itemEquip]) && !skill + const equipping = skillList.includes(vbox.stash[itemEquip]) && !skill && !tutorialDisableEquip && !duplicateSkill && i === construct.skills.length; const border = () => { if (!skill) return ''; @@ -169,7 +169,7 @@ function Construct(props) { const s = construct.specs[i]; if (!s) { - const equipping = specList.includes(vbox.bound[itemEquip]) && i === construct.specs.length; + const equipping = specList.includes(vbox.stash[itemEquip]) && i === construct.specs.length; const classes = `${equipping ? 'equipping' : 'gray'} empty`; return ( ); } diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index f00e9b63..9d192b9c 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -161,7 +161,7 @@ class Vbox extends preact.Component { function stashHdr() { const refund = storeSelect.length === 0 && stashSelect.length === 1 - ? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost + ? itemInfo.items.find(i => i.item === vbox.stash[stashSelect[0]]).cost : 0; const tutorialDisabled = tutorial && tutorial < 8 && instance.time_control === 'Practice' && instance.rounds.length === 1; diff --git a/client/src/components/vbox.stash.jsx b/client/src/components/vbox.stash.jsx index 97511443..cec94686 100644 --- a/client/src/components/vbox.stash.jsx +++ b/client/src/components/vbox.stash.jsx @@ -81,7 +81,7 @@ class stashElement extends preact.Component { } if (notValidCombo) { - setInfo(vbox.bound[i]); + setInfo(vbox.stash[i]); return setVboxSelected({ storeSelect: [], stashSelect: [i] }); } @@ -123,7 +123,7 @@ class stashElement extends preact.Component { onDragOver={ev => ev.preventDefault()} onDrop={stashClick} > - {range(0, 6).map(i => stashBtn(vbox.bound[i], i))} + {range(0, 6).map(i => stashBtn(vbox.stash[i], i.toString()))}
); } diff --git a/client/src/components/vbox.store.jsx b/client/src/components/vbox.store.jsx index 9a168fc6..f4d1878c 100644 --- a/client/src/components/vbox.store.jsx +++ b/client/src/components/vbox.store.jsx @@ -32,7 +32,7 @@ class storeElement extends preact.Component { const { storeSelect, stashSelect } = vboxSelected; function availableBtn(v, group, index) { - if (!v) return ; + if (!v) return ; const selected = storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index); const notValidCombo = vboxHighlight && !vboxHighlight.includes(v); @@ -63,7 +63,7 @@ class storeElement extends preact.Component { const disabled = vbox.bits <= group; return (
); diff --git a/client/src/components/vbox.utils.jsx b/client/src/components/vbox.utils.jsx index 2069d66d..e40a0b2e 100644 --- a/client/src/components/vbox.utils.jsx +++ b/client/src/components/vbox.utils.jsx @@ -23,8 +23,8 @@ function setVboxState(dispatch, vboxSelected, state) { if (!(storeSelect.length === 0 && stashSelect.length === 0)) { vboxHighlight = []; - const stashItems = stashSelect.map(j => vbox.bound[j]); - const shopItems = storeSelect.map(j => vbox.free[j[0]][j[1]]); + const stashItems = stashSelect.map(j => vbox.stash[j]); + const shopItems = storeSelect.map(j => vbox.store[j[0]][j[1]]); const selectedItems = stashItems.concat(shopItems); const itemCount = countBy(selectedItems, co => co); @@ -55,12 +55,12 @@ function setVboxState(dispatch, vboxSelected, state) { const vboxInfo = () => { if (vboxCombiner) return vboxCombiner; if (itemUnequip.length) return itemUnequip[1]; - const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.bound[i]))); - if (stashBase > -1) return vbox.bound[stashBase]; - const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.free[j[0]][j[1]]))); - if (storeBase) return vbox.free[storeBase[0]][storeBase[1]]; - if (stashSelect.length > 0) return vbox.bound[stashSelect[0]]; - if (storeSelect.length > 0) return vbox.free[storeSelect[0][0]][storeSelect[0][1]]; + const stashBase = stashSelect.find(i => !(['Red', 'Blue', 'Green'].includes(vbox.stash[i]))); + if (stashBase > -1) return vbox.stash[stashBase]; + const storeBase = storeSelect.find(j => !(['Red', 'Blue', 'Green'].includes(vbox.store[j[0]][j[1]]))); + if (storeBase) return vbox.store[storeBase[0]][storeBase[1]]; + if (stashSelect.length > 0) return vbox.stash[stashSelect[0]]; + if (storeSelect.length > 0) return vbox.store[storeSelect[0][0]][storeSelect[0][1]]; return false; }; diff --git a/client/src/tutorial.utils.jsx b/client/src/tutorial.utils.jsx index 05fedee5..e60974f4 100644 --- a/client/src/tutorial.utils.jsx +++ b/client/src/tutorial.utils.jsx @@ -24,21 +24,21 @@ function tutorialVbox(player, store, tutorial) { if (vbox.bits < 29) { stage += 1; } else { - vbox.free[0] = vbox.free[0].slice(0, 2); - vbox.free[1] = []; - vbox.free[2] = []; - vbox.bound.fill(null, 0, 3); + vbox.store[0] = vbox.store[0].slice(0, 2); + vbox.store[1] = []; + vbox.store[2] = []; + vbox.stash.fill(null, 0, 3); } } if (stage === 2) { - if (!(vbox.bound.slice(0, 3).every(i => i === 'Attack') && vbox.bound.length >= 3)) { + if (!(vbox.stash.slice(0, 3).every(i => i === 'Attack') && vbox.stash.length >= 3)) { stage += 1; } else { - vbox.free[0] = vbox.free[0].slice(0, 2); - vbox.free[1] = []; - vbox.free[2] = []; - vbox.bound.fill(null, 1, 3); + vbox.store[0] = vbox.store[0].slice(0, 2); + vbox.store[1] = []; + vbox.store[2] = []; + vbox.stash.fill(null, 1, 3); } } @@ -46,21 +46,21 @@ function tutorialVbox(player, store, tutorial) { if (player.constructs[0].skills.length !== 0) { stage += 1; } else { - vbox.free[0] = vbox.free[0].slice(0, 2); - vbox.free[1] = []; - vbox.free[2] = []; - vbox.bound.fill(null, 0, 2); + vbox.store[0] = vbox.store[0].slice(0, 2); + vbox.store[1] = []; + vbox.store[2] = []; + vbox.stash.fill(null, 0, 2); } } if (stage === 4) { - if (!vbox.free[2][0] || vbox.bits < 24) { + if (!vbox.store[2][0] || vbox.bits < 24) { stage += 1; } else { - vbox.free[0] = []; - vbox.free[1] = []; - vbox.free[2] = vbox.free[2].slice(0, 1); - vbox.bound.fill(null, 0, 2); + vbox.store[0] = []; + vbox.store[1] = []; + vbox.store[2] = vbox.store[2].slice(0, 1); + vbox.stash.fill(null, 0, 2); } } @@ -68,10 +68,10 @@ function tutorialVbox(player, store, tutorial) { if (player.constructs[0].specs.length !== 0) { stage += 1; } else { - vbox.free[0] = []; - vbox.free[1] = []; - vbox.free[2] = vbox.free[2].slice(0, 1); - vbox.bound.fill(null, 0, 2); + vbox.store[0] = []; + vbox.store[1] = []; + vbox.store[2] = vbox.store[2].slice(0, 1); + vbox.stash.fill(null, 0, 2); } } @@ -79,9 +79,9 @@ function tutorialVbox(player, store, tutorial) { if (player.constructs.every(c => c.skills.length !== 0)) { stage += 1; } else { - vbox.free[0] = []; - vbox.free[1] = []; - vbox.free[2] = []; + vbox.store[0] = []; + vbox.store[1] = []; + vbox.store[2] = []; } } @@ -89,9 +89,9 @@ function tutorialVbox(player, store, tutorial) { if (vbox.bits < 25) { stage += 1; } else { - vbox.free[0] = []; - vbox.free[1] = []; - vbox.free[2] = []; + vbox.store[0] = []; + vbox.store[1] = []; + vbox.store[2] = []; } } store.dispatch(actions.setTutorial(stage)); From 24951c144253ee0b3256c3cd6bfa0a19713d4602 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 28 Nov 2019 15:51:42 +1000 Subject: [PATCH 86/97] costs --- client/src/components/vbox.combiner.jsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/client/src/components/vbox.combiner.jsx b/client/src/components/vbox.combiner.jsx index 515db398..9c7ddd96 100644 --- a/client/src/components/vbox.combiner.jsx +++ b/client/src/components/vbox.combiner.jsx @@ -26,10 +26,17 @@ class Combiner extends preact.Component { const { stashSelect, storeSelect } = vboxSelected; + function cost([group, i]) { + if (group === 'Colours') return 1; + if (group === 'Skills') return 2; + if (group === 'Specs') return 3; + }; + + if (vboxCombiner) { const combinerComboText = vboxCombiner.replace('Plus', '+'); let bits = 0; - storeSelect.forEach(item => bits += item[0] + 1); + storeSelect.forEach(item => bits += cost(item)); return ( ); } From e78a502a40f73b0813375df2859926b2d5f4009b Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 28 Nov 2019 15:54:37 +1000 Subject: [PATCH 87/97] PogU --- client/assets/styles/game.less | 4 ++-- client/src/components/game.construct.jsx | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index 86b9cf14..e6f1c735 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -40,7 +40,7 @@ .combat-text { left: 15%; - top: 40%; + top: 0%; } } @@ -79,7 +79,7 @@ .combat-text { left: 15%; - top: 40%; + top: 100%; } .effects { diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 2f1c0617..8172c3fc 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -1,13 +1,13 @@ -const { connect } = require('preact-redux'); -const { Component } = require('preact'); const preact = require('preact'); +const { connect } = require('preact-redux'); +const anime = require('animejs').default; const range = require('lodash/range'); const reactStringReplace = require('react-string-replace'); const { STATS, removeTier } = require('../utils'); const { ConstructAvatar, ConstructText } = require('./construct'); const shapes = require('./shapes'); -const { INFO } = require('./../constants'); +const { INFO, TIMES } = require('./../constants'); const actions = require('../actions'); const SkillBtn = require('./skill.btn'); @@ -20,6 +20,19 @@ class combatText extends preact.Component { return false; } + componentDidUpdate(prevProps) { + const { animText, construct } = this.props; + if (animText && animText !== prevProps.animText && animText.constructId === construct.id) { + anime({ + targets: '.combat-text', + top: '40%', + duration: TIMES.POST_SKILL_DURATION_MS, + }); + + console.log('grep'); + } + } + render(props) { const { construct, animText, itemInfo } = props; if (animText && animText.constructId === construct.id) { @@ -132,7 +145,7 @@ const eventClasses = (animating, animFocus, construct, postSkill) => { return postSkill.css; }; -class GameConstruct extends Component { +class GameConstruct extends preact.Component { constructor() { super(); this.resolvedLength = 0; From 18126c1b0cf6cbf298371d6edfd04433fcc2990a Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 28 Nov 2019 16:01:44 +1000 Subject: [PATCH 88/97] change names --- client/assets/styles/vbox.less | 2 +- client/src/components/instance.constructs.jsx | 14 +++---- client/src/components/vbox.component.jsx | 30 +++++++-------- client/src/constants.jsx | 8 ++-- client/src/socket.jsx | 37 ++++++++----------- client/src/tutorial.utils.jsx | 2 +- client/src/utils.jsx | 2 +- server/src/vbox.rs | 2 +- 8 files changed, 46 insertions(+), 51 deletions(-) diff --git a/client/assets/styles/vbox.less b/client/assets/styles/vbox.less index 209f31de..aab8da8e 100644 --- a/client/assets/styles/vbox.less +++ b/client/assets/styles/vbox.less @@ -116,7 +116,7 @@ }; } - .reclaiming { + .Refunding { button:not([disabled]) { &, &:hover, &:active { background: @red; diff --git a/client/src/components/instance.constructs.jsx b/client/src/components/instance.constructs.jsx index 3ed752b7..5a752394 100644 --- a/client/src/components/instance.constructs.jsx +++ b/client/src/components/instance.constructs.jsx @@ -24,8 +24,8 @@ const addState = connect( tutorial, } = state; - function sendVboxAcceptEquip(constructId) { - return ws.sendVboxAcceptEquip(instance.id, vboxSelected.storeSelect[0][0], vboxSelected.storeSelect[0][1], constructId); + function sendVboxBuyEquip(constructId) { + return ws.sendVboxBuyEquip(instance.id, vboxSelected.storeSelect[0][0], vboxSelected.storeSelect[0][1], constructId); } function sendVboxApply(constructId, i) { @@ -40,7 +40,7 @@ const addState = connect( instance, player, account, - sendVboxAcceptEquip, + sendVboxBuyEquip, sendVboxUnequipApply, sendVboxApply, itemInfo, @@ -83,7 +83,7 @@ function Construct(props) { itemInfo, // Function Calls sendVboxApply, - sendVboxAcceptEquip, + sendVboxBuyEquip, sendVboxUnequipApply, setItemUnequip, setInfo, @@ -106,7 +106,7 @@ function Construct(props) { e.preventDefault(); if (duplicateSkill || tutorialDisableEquip) return true; if (itemEquip !== -1) return sendVboxApply(construct.id, itemEquip); - if (vboxSelected.storeSelect.length === 1) return sendVboxAcceptEquip(construct.id); + if (vboxSelected.storeSelect.length === 1) return sendVboxBuyEquip(construct.id); if (itemUnequip.length && itemUnequip[0] !== construct.id) return sendVboxUnequipApply(construct.id); setItemUnequip([]); return true; @@ -261,7 +261,7 @@ class InstanceConstructs extends preact.Component { // Function calls setInfo, sendVboxApply, - sendVboxAcceptEquip, + sendVboxBuyEquip, sendVboxUnequipApply, setItemUnequip, } = props; @@ -281,7 +281,7 @@ class InstanceConstructs extends preact.Component { setItemUnequip, player, sendVboxApply, - sendVboxAcceptEquip, + sendVboxBuyEquip, sendVboxUnequipApply, setInfo, itemInfo, diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 9d192b9c..2891e060 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -27,22 +27,22 @@ const addState = connect( return ws.clearTutorial(instance.id); } - function sendVboxDiscard() { - return ws.sendVboxDiscard(instance.id); + function sendVboxRefill() { + return ws.sendVboxRefill(instance.id); } - function sendVboxAccept(group, index) { + function sendVboxBuy(group, index) { if (!(vboxSelected.storeSelect.length === 1 && vboxSelected.stashSelect.length === 0)) return false; document.activeElement.blur(); - return ws.sendVboxAccept(instance.id, group, index); + return ws.sendVboxBuy(instance.id, group, index); } function sendVboxCombine() { return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.storeSelect); } - function sendVboxReclaim(i) { - return ws.sendVboxReclaim(instance.id, i); + function sendVboxRefund(i) { + return ws.sendVboxRefund(instance.id, i); } function sendItemUnequip([constructId, item]) { @@ -60,10 +60,10 @@ const addState = connect( clearTutorial, sendItemUnequip, - sendVboxAccept, + sendVboxBuy, sendVboxCombine, - sendVboxDiscard, - sendVboxReclaim, + sendVboxRefill, + sendVboxRefund, }; }, @@ -109,10 +109,10 @@ class Vbox extends preact.Component { clearTutorial, dispatchVboxSelect, sendItemUnequip, - sendVboxAccept, + sendVboxBuy, sendVboxCombine, - sendVboxDiscard, - sendVboxReclaim, + sendVboxRefill, + sendVboxRefund, setInfo, } = args; @@ -122,7 +122,7 @@ class Vbox extends preact.Component { const setVboxSelected = v => dispatchVboxSelect(v, { itemInfo, itemUnequip, vbox }); const clearVboxSelected = () => setVboxSelected({ storeSelect: [], stashSelect: [] }); - const vboxBuySelected = () => sendVboxAccept(storeSelect[0][0], storeSelect[0][1]); + const vboxBuySelected = () => sendVboxBuy(storeSelect[0][0], storeSelect[0][1]); function vboxHover(e, v) { if (v) { @@ -151,7 +151,7 @@ class Vbox extends preact.Component { && instance.time_control === 'Practice' && instance.rounds.length === 1) } onClick={e => e.stopPropagation()} - onMouseDown={() => sendVboxDiscard()}> + onMouseDown={() => sendVboxRefill()}> refill
2b @@ -172,7 +172,7 @@ class Vbox extends preact.Component { onClick={e => e.stopPropagation()} onMouseDown={e => { e.stopPropagation(); - sendVboxReclaim(vboxSelected.stashSelect[0]); + sendVboxRefund(vboxSelected.stashSelect[0]); }}> refund
{refund}b diff --git a/client/src/constants.jsx b/client/src/constants.jsx index f16b7f3b..989e689f 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -45,10 +45,10 @@ module.exports = { item: 'READY', description: 'Ready for the game to begin. When all players are ready the first VBOX PHASE begins.', }, - reclaim: { - item: 'RECLAIM', - description:

Reclaim items refunding the listed cost of the item.
- Click to enable and then click the item to reclaim.

, + Refund: { + item: 'Refund', + description:

Refund items refunding the listed cost of the item.
+ Click to enable and then click the item to Refund.

, }, refill: { item: 'REFILL', diff --git a/client/src/socket.jsx b/client/src/socket.jsx index c97c4fb2..ffe00b7d 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -2,6 +2,7 @@ const toast = require('izitoast'); const cbor = require('borc'); const throttle = require('lodash/throttle'); +const groupBy = require('lodash/groupBy'); const SOCKET_URL = `${window.location.protocol === 'https:' ? 'wss://' : 'ws://'}${window.location.host}/api/ws`; @@ -77,13 +78,13 @@ function createSocket(events) { send(['InstanceChat', { instance_id: instanceId, index }]); } - function sendVboxAccept(instanceId, group, index) { - send(['VboxAccept', { instance_id: instanceId, group, index }]); + function sendVboxBuy(instanceId, group, index) { + send(['VboxBuy', { instance_id: instanceId, group, index }]); events.clearInstance(); } - function sendVboxAcceptEquip(instanceId, group, index, constructId) { - send(['VboxAcceptEquip', { instance_id: instanceId, group, index, construct_id: constructId }]); + function sendVboxBuyEquip(instanceId, group, index, constructId) { + send(['VboxBuyEquip', { instance_id: instanceId, group, index, construct_id: constructId }]); events.clearInstance(); } @@ -102,18 +103,20 @@ function createSocket(events) { events.clearInstance(); } - function sendVboxDiscard(instanceId) { - send(['VboxDiscard', { instance_id: instanceId }]); + function sendVboxRefill(instanceId) { + send(['VboxRefill', { instance_id: instanceId }]); events.clearInstance(); } function sendVboxCombine(instanceId, invIndicies, vboxIndicies) { - send(['VboxCombine', { instance_id: instanceId, inv_indices: invIndicies, vbox_indices: vboxIndicies }]); + const formatted = {}; + vboxIndicies.forEach(p => formatted[p[0]] ? formatted[p[0]].push(p[1]) : formatted[p[0]] = [p[1]]); + send(['VboxCombine', { instance_id: instanceId, inv_indices: invIndicies, vbox_indices: formatted }]); events.clearInstance(); } - function sendVboxReclaim(instanceId, index) { - send(['VboxReclaim', { instance_id: instanceId, index }]); + function sendVboxRefund(instanceId, index) { + send(['VboxRefund', { instance_id: instanceId, index }]); events.clearInstance(); } @@ -204,12 +207,6 @@ function createSocket(events) { send(['SubscriptionState', {}]); } - function clearTutorial(instanceId) { - events.clearTutorial(); - events.clearInstance(); - sendInstanceState(instanceId); - } - // ------------- // Incoming // ------------- @@ -416,12 +413,12 @@ function createSocket(events) { sendInstanceChat, sendInstanceLeave, - sendVboxAccept, - sendVboxAcceptEquip, + sendVboxBuy, + sendVboxBuyEquip, sendVboxApply, - sendVboxReclaim, + sendVboxRefund, sendVboxCombine, - sendVboxDiscard, + sendVboxRefill, sendVboxUnequip, sendVboxUnequipApply, @@ -436,8 +433,6 @@ function createSocket(events) { sendMtxBuy, sendMtxConstructSpawn, - clearTutorial, - connect, }; } diff --git a/client/src/tutorial.utils.jsx b/client/src/tutorial.utils.jsx index e60974f4..0760a13c 100644 --- a/client/src/tutorial.utils.jsx +++ b/client/src/tutorial.utils.jsx @@ -204,7 +204,7 @@ function tutorialStage(tutorial, clearTutorial, instance) {

Press READY to progress to the GAME PHASE
or continue creating new items to strengthen your constructs further

You can unequip skills and specs back into the inventory by double clicking.
- Reclaim can be used to refund the cost of items in your inventory.

+ Refund can be used to refund the cost of items in your inventory.

); } diff --git a/client/src/utils.jsx b/client/src/utils.jsx index a14c684e..550c69e6 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -197,7 +197,7 @@ function postData(url = '/', data = {}) { cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached credentials: 'include', // include, same-origin, *omit headers: { - Accept: 'application/json', + Buy: 'application/json', 'content-type': 'application/json', }, redirect: 'error', // manual, *follow, error diff --git a/server/src/vbox.rs b/server/src/vbox.rs index e2507c74..fdfd1d3d 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -130,7 +130,7 @@ impl Vbox { // check item exists let selection = self.store .get_mut(&item).ok_or(format_err!("no item group {:?}", item))? - .remove(i).ok_or(format_err!("no item at index {:?} {:}", item, i))?; + .remove(i).ok_or(format_err!("no item at index {:?} {:}", self, i))?; self.balance_sub(selection.cost())?; From 91c82324e2e85ef44ffb8609813bf1defe819ca4 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 28 Nov 2019 16:31:37 +1000 Subject: [PATCH 89/97] clean up equipping api --- client/src/socket.jsx | 2 +- server/src/instance.rs | 2 +- server/src/player.rs | 99 +++++++----------------------------------- server/src/rpc.rs | 10 ++--- 4 files changed, 20 insertions(+), 93 deletions(-) diff --git a/client/src/socket.jsx b/client/src/socket.jsx index ffe00b7d..a99fe130 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -84,7 +84,7 @@ function createSocket(events) { } function sendVboxBuyEquip(instanceId, group, index, constructId) { - send(['VboxBuyEquip', { instance_id: instanceId, group, index, construct_id: constructId }]); + send(['VboxBuy', { instance_id: instanceId, group, index, construct_id: constructId }]); events.clearInstance(); } diff --git a/server/src/instance.rs b/server/src/instance.rs index 0d052d08..65c17b65 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -497,7 +497,7 @@ impl Instance { pub fn vbox_apply(mut self, account: Uuid, index: String, construct_id: Uuid) -> Result { self.vbox_action_allowed(account)?; self.account_player(account)? - .vbox_apply(index, construct_id)?; + .vbox_equip(index, construct_id)?; Ok(self) } diff --git a/server/src/player.rs b/server/src/player.rs index 9b1fbeca..b0988a3a 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -174,7 +174,8 @@ impl Player { // AAAAAAAAAAAAAAAAAAAA // there's a bad bug here where if this apply fails // the item in question will be silently dropped - self.vbox_apply(i, construct_id).ok(); + let item = self.vbox.stash.remove(&i).unwrap(); + self.vbox_apply(item, construct_id).ok(); continue; } // need to buy one @@ -228,7 +229,8 @@ impl Player { // AAAAAAAAAAAAAAAAAAAA // there's a bad bug here where if this apply fails // the item in question will be silently dropped - self.vbox_apply(i, construct_id).ok(); + let item = self.vbox.stash.remove(&i).unwrap(); + self.vbox_apply(item, construct_id).ok(); continue; } // need to buy one @@ -267,79 +269,6 @@ impl Player { // upgrading phase // NYI - // // first check if any constructs have no skills - // // if there is one find an item in vbox that gives a skill - // while let Some(c) = self.constructs.iter().position(|c| c.skills.len() == 0) { - // if let Some(s) = self.vbox.stash.iter().position(|(i, v)| v.into_skill().is_some()) { - // let construct_id = self.constructs[c].id; - // self.vbox_apply(s, construct_id).expect("could not apply"); - // continue; - // } - // info!("no skills available..."); - // } - - // // now keep buying and applying items cause whynot - // // inb4 montecarlo gan - // loop { - // let (target_construct_i, target_construct_id) = match self.constructs.iter().any(|c| c.skills.len() < 3) { - // true => { - // let mut target_construct_i = 0; - // for (j, c) in self.constructs.iter().enumerate() { - // if c.skills.len() < self.constructs[target_construct_i].skills.len() { - // target_construct_i = j; - // } - // } - // (target_construct_i, self.constructs[target_construct_i].id) - // }, - // false => { - // let i = rng.gen_range(0, 3); - // (i, self.constructs[i].id) - // }, - // }; - - // let needs_skills = self.constructs[target_construct_i].skills.len() < 3; - // let group_i = match needs_skills { - // true => 1, - // false => 2, - // }; - - - // let num_colours = self.vbox.stash - // .iter() - // .filter(|(i, v)| [Item::Red, Item::Green, Item::Blue].contains(v)) - // .count(); - - // if self.vbox.stash.len() < 3 || num_colours < 2 { - // if (needs_skills && self.vbox.bits < 4) || self.vbox.bits < 5 { - // // info!("insufficient balance"); - // break; - // } - - // // get 2 colours and something else - // let store_colours = self.vbox.store[&ItemType::Colours].len(); - // if store_colours < 2 { - // break; - // } - // self.bot_vbox_accept(0).expect("could't accept colour item"); - // self.bot_vbox_accept(0).expect("could't accept colour item"); - // self.bot_vbox_accept(group_i).expect("could't accept group item"); - // } - - // // info!("{:?}", self.vbox.stash); - - // let skills = [Item::Attack, Item::Block, Item::Buff, Item::Debuff, Item::Stun]; - // let combo_i = match group_i { - // 1 => self.vbox.stash.iter().position(|v| skills.contains(v)).expect("no skill found"), - // 2 => self.vbox.stash.iter().position(|v| v.into_spec().is_some()).expect("no spec found"), - // _ => panic!("unknown group_i"), - // }; - - // // first 2 colours can be whatever - // self.vbox_combine(vec![0, 1, combo_i], vec![]).ok(); - // let item_i = self.vbox.stash.len() - 1; - // self.vbox_apply(item_i, target_construct_id).ok(); - // } - return self; } @@ -359,7 +288,7 @@ impl Player { let item = self.vbox.buy(group, &index)?; match construct_id { - Some(id) => { self.vbox_apply(index, id)?; }, + Some(id) => { self.vbox_apply(item, id)?; }, None => { self.vbox.stash_add(item, None)?; }, }; @@ -376,10 +305,14 @@ impl Player { Ok(self) } - pub fn vbox_apply(&mut self, index: String, construct_id: Uuid) -> Result<&mut Player, Error> { + pub fn vbox_equip(&mut self, index: String, construct_id: Uuid) -> Result<&mut Player, Error> { let item = self.vbox.stash.remove(&index) - .ok_or(format_err!("no item at index {:?} {:?}", self.vbox.stash, index))?; + .ok_or(format_err!("no item at index {:?} {:}", self, &index))?; + self.vbox_apply(item, construct_id) + } + + pub fn vbox_apply(&mut self, item: Item, construct_id: Uuid) -> Result<&mut Player, Error> { match item.effect() { Some(ItemEffect::Skill) => { let skill = item.into_skill().ok_or(format_err!("item {:?} has no associated skill", item))?; @@ -455,12 +388,10 @@ impl Player { construct.apply_modifiers(&player_colours); } - let equip_index = self.vbox.stash_add(target, None)?; - - if target_construct_id.is_some() { - self.vbox_apply(equip_index, target_construct_id.expect("no construct"))?; - } - // self.vbox.stash.sort_unstable(); + match target_construct_id { + Some(cid) => { self.vbox_apply(target, cid)?; }, + None => { self.vbox.stash_add(target, None)?; }, + }; Ok(self) } diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 9f43a928..e27a62dd 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -115,8 +115,7 @@ pub enum RpcRequest { InstanceState { instance_id: Uuid }, InstanceChat { instance_id: Uuid, index: usize }, - VboxBuy { instance_id: Uuid, group: ItemType, index: String }, - VboxBuyEquip { instance_id: Uuid, group: ItemType, index: String, construct_id: Uuid }, + VboxBuy { instance_id: Uuid, group: ItemType, index: String, construct_id: Option }, VboxRefill { instance_id: Uuid }, VboxCombine { instance_id: Uuid, inv_indices: Vec, vbox_indices: Option>> }, VboxApply { instance_id: Uuid, construct_id: Uuid, index: String }, @@ -246,11 +245,8 @@ impl Connection { RpcRequest::InstanceAbandon { instance_id } => Ok(instance_abandon(&mut tx, account, instance_id)?), - RpcRequest::VboxBuy { instance_id, group, index } => - Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, None)?)), - - RpcRequest::VboxBuyEquip { instance_id, group, index, construct_id } => - Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, Some(construct_id))?)), + RpcRequest::VboxBuy { instance_id, group, index, construct_id } => + Ok(RpcMessage::InstanceState(vbox_buy(&mut tx, account, instance_id, group, index, construct_id)?)), RpcRequest::VboxApply { instance_id, construct_id, index } => Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)), From 63028fe297df381e5d1dec48c51c26b835781c47 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 28 Nov 2019 16:54:37 +1000 Subject: [PATCH 90/97] wip experimenting with values --- client/assets/styles/game.less | 4 ++-- client/src/components/construct.jsx | 2 +- client/src/components/game.construct.jsx | 5 ++--- client/src/constants.jsx | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index e6f1c735..1746abea 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -40,7 +40,7 @@ .combat-text { left: 15%; - top: 0%; + top: 20%; } } @@ -219,7 +219,7 @@ } &.ko-transition { - animation: target-ko 1.1s ease-in-out 0s 1; + animation: target-ko 1.3s ease-in-out 0s 1; } &.ko { diff --git a/client/src/components/construct.jsx b/client/src/components/construct.jsx index a26ecdd5..34453f9e 100644 --- a/client/src/components/construct.jsx +++ b/client/src/components/construct.jsx @@ -19,7 +19,7 @@ const addState = connect( ); class ConstructAvatar extends Component { - constructor(props) { + constructor() { super(); // The animation ids are a check to ensure that animations are not repeated // When a new construct animation is communicated with state it will have a corresponding Id diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 8172c3fc..347b4511 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -26,10 +26,9 @@ class combatText extends preact.Component { anime({ targets: '.combat-text', top: '40%', - duration: TIMES.POST_SKILL_DURATION_MS, + duration: TIMES.POST_SKILL_DURATION_MS - 500, + easing: 'easeOutQuad', }); - - console.log('grep'); } } diff --git a/client/src/constants.jsx b/client/src/constants.jsx index bcfa054d..e0ee5edc 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -3,7 +3,7 @@ const preact = require('preact'); const SOURCE_DURATION_MS = 1000; // Time for SOURCE ONLY const TARGET_DELAY_MS = 500; // Used for Source + Target const TARGET_DURATION_MS = 1500; // Time for TARGET ONLY -const POST_SKILL_DURATION_MS = 1100; // Time for all POST +const POST_SKILL_DURATION_MS = 1300; // Time for all POST const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS; // SOURCE + TARGET time module.exports = { From 11ec807ae23c9f6abd59caf6e0411968afe26ad4 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 28 Nov 2019 17:30:06 +1000 Subject: [PATCH 91/97] fix highlighting issues --- client/src/actions.jsx | 2 +- client/src/components/vbox.utils.jsx | 11 ++++++++--- client/src/keyboard.jsx | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 00b32e31..f6745548 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -49,7 +49,7 @@ export const setTeamSelect = value => ({ type: 'SET_TEAM_SELECT', value: Array.f export const setTutorial = value => ({ type: 'SET_TUTORIAL', value }); export const setTutorialGame = value => ({ type: 'SET_TUTORIAL_GAME', value }); -export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value }); +export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value: Object.create(value) }); export const setVboxCombiner = value => ({ type: 'SET_VBOX_COMBINER', value }); export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value }); export const setVboxInfo = value => ({ type: 'SET_VBOX_INFO', value }); diff --git a/client/src/components/vbox.utils.jsx b/client/src/components/vbox.utils.jsx index e40a0b2e..030d308e 100644 --- a/client/src/components/vbox.utils.jsx +++ b/client/src/components/vbox.utils.jsx @@ -21,7 +21,7 @@ function setVboxState(dispatch, vboxSelected, state) { let vboxCombiner = false; let vboxHighlight = false; - if (!(storeSelect.length === 0 && stashSelect.length === 0)) { + if (storeSelect.length || stashSelect.length) { vboxHighlight = []; const stashItems = stashSelect.map(j => vbox.stash[j]); const shopItems = storeSelect.map(j => vbox.store[j[0]][j[1]]); @@ -66,7 +66,7 @@ function setVboxState(dispatch, vboxSelected, state) { dispatch(actions.setVboxInfo(vboxInfo())); dispatch(actions.setVboxCombiner(vboxCombiner)); - dispatch(actions.setVboxHighlight(vboxHighlight)); + dispatch(actions.setVboxHighlight(vboxHighlight.length ? vboxHighlight : null)); } function genItemInfo(item, itemInfo, player) { @@ -124,5 +124,10 @@ function genItemInfo(item, itemInfo, player) { ); } +function cost(group) { + if (group === 'Colours') return 1; + if (group === 'Skills') return 2; + if (group === 'Specs') return 3; +}; -module.exports = { setVboxState, genItemInfo }; +module.exports = { setVboxState, genItemInfo, cost }; diff --git a/client/src/keyboard.jsx b/client/src/keyboard.jsx index 43d7343b..cca738f9 100644 --- a/client/src/keyboard.jsx +++ b/client/src/keyboard.jsx @@ -10,6 +10,7 @@ function setupKeys(store) { key('esc', () => store.dispatch(actions.setInfo(null))); key('esc', () => store.dispatch(actions.setItemUnequip([]))); key('esc', () => store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] }))); + key('esc', () => store.dispatch(actions.setVboxHighlight(null))); key('esc', () => store.dispatch(actions.setMtxActive(null))); } From 84e3e776ca98a320a8a0aa78fb67ffa5ef9cbec0 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 28 Nov 2019 23:46:07 +1000 Subject: [PATCH 92/97] fixt tutorial --- client/src/components/vbox.component.jsx | 19 +++++-- client/src/tutorial.utils.jsx | 65 ++++++++++++++---------- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 2891e060..2f1770da 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -23,8 +23,8 @@ const addState = connect( itemInfo, } = state; - function clearTutorial() { - return ws.clearTutorial(instance.id); + function sendInstance() { + return ws.sendInstanceState(instance.id); } function sendVboxRefill() { @@ -58,7 +58,7 @@ const addState = connect( itemInfo, - clearTutorial, + sendInstance, sendItemUnequip, sendVboxBuy, sendVboxCombine, @@ -72,6 +72,10 @@ const addState = connect( return dispatch(actions.setInfo(item)); } + function setTutorial(stage) { + return dispatch(actions.setTutorial(stage)); + } + function dispatchVboxSelect(v, state) { setVboxState(dispatch, v, state); dispatch(actions.setItemUnequip([])); @@ -81,6 +85,7 @@ const addState = connect( return { dispatchVboxSelect, setInfo, + setTutorial, }; } ); @@ -106,14 +111,15 @@ class Vbox extends preact.Component { // Static itemInfo, // Function Calls - clearTutorial, dispatchVboxSelect, sendItemUnequip, + sendInstance, sendVboxBuy, sendVboxCombine, sendVboxRefill, sendVboxRefund, setInfo, + setTutorial, } = args; if (!player) return false; @@ -123,7 +129,10 @@ class Vbox extends preact.Component { const setVboxSelected = v => dispatchVboxSelect(v, { itemInfo, itemUnequip, vbox }); const clearVboxSelected = () => setVboxSelected({ storeSelect: [], stashSelect: [] }); const vboxBuySelected = () => sendVboxBuy(storeSelect[0][0], storeSelect[0][1]); - + const clearTutorial = () => { + setTutorial(null); + sendInstance(); + }; function vboxHover(e, v) { if (v) { e.stopPropagation(); diff --git a/client/src/tutorial.utils.jsx b/client/src/tutorial.utils.jsx index 0760a13c..2df85c6b 100644 --- a/client/src/tutorial.utils.jsx +++ b/client/src/tutorial.utils.jsx @@ -24,21 +24,26 @@ function tutorialVbox(player, store, tutorial) { if (vbox.bits < 29) { stage += 1; } else { - vbox.store[0] = vbox.store[0].slice(0, 2); - vbox.store[1] = []; - vbox.store[2] = []; - vbox.stash.fill(null, 0, 3); + for (let i = 2; i < 6; i += 1) { + delete vbox.store.Colours[i]; + } + vbox.store.Skills = {}; + vbox.store.Specs = {}; + delete vbox.stash[0]; + delete vbox.stash[1]; + delete vbox.stash[2]; } } if (stage === 2) { - if (!(vbox.stash.slice(0, 3).every(i => i === 'Attack') && vbox.stash.length >= 3)) { + if (!(vbox.stash[0] === 'Attack' && vbox.stash[1] === 'Attack' && vbox.stash[2] === 'Attack')) { stage += 1; } else { - vbox.store[0] = vbox.store[0].slice(0, 2); - vbox.store[1] = []; - vbox.store[2] = []; - vbox.stash.fill(null, 1, 3); + vbox.store.Colours = {}; + vbox.store.Skills = {}; + vbox.store.Specs = {}; + delete vbox.stash[0]; + delete vbox.stash[1]; } } @@ -46,21 +51,24 @@ function tutorialVbox(player, store, tutorial) { if (player.constructs[0].skills.length !== 0) { stage += 1; } else { - vbox.store[0] = vbox.store[0].slice(0, 2); - vbox.store[1] = []; - vbox.store[2] = []; - vbox.stash.fill(null, 0, 2); + vbox.store.Colours = {}; + vbox.store.Skills = {}; + vbox.store.Specs = {}; + delete vbox.stash[0]; + delete vbox.stash[1]; } } if (stage === 4) { - if (!vbox.store[2][0] || vbox.bits < 24) { + if (!vbox.store.Specs[0] || vbox.bits < 24) { stage += 1; } else { - vbox.store[0] = []; - vbox.store[1] = []; - vbox.store[2] = vbox.store[2].slice(0, 1); - vbox.stash.fill(null, 0, 2); + vbox.store.Colours = {}; + vbox.store.Skills = {}; + delete vbox.store.Specs[1]; + delete vbox.store.Specs[2]; + delete vbox.stash[0]; + delete vbox.stash[1]; } } @@ -68,10 +76,11 @@ function tutorialVbox(player, store, tutorial) { if (player.constructs[0].specs.length !== 0) { stage += 1; } else { - vbox.store[0] = []; - vbox.store[1] = []; - vbox.store[2] = vbox.store[2].slice(0, 1); - vbox.stash.fill(null, 0, 2); + vbox.store.Colours = {}; + vbox.store.Skills = {}; + vbox.store.Specs = {}; + delete vbox.stash[0]; + delete vbox.stash[1]; } } @@ -79,9 +88,9 @@ function tutorialVbox(player, store, tutorial) { if (player.constructs.every(c => c.skills.length !== 0)) { stage += 1; } else { - vbox.store[0] = []; - vbox.store[1] = []; - vbox.store[2] = []; + vbox.store.Colours = {}; + vbox.store.Skills = {}; + vbox.store.Specs = {}; } } @@ -89,9 +98,9 @@ function tutorialVbox(player, store, tutorial) { if (vbox.bits < 25) { stage += 1; } else { - vbox.store[0] = []; - vbox.store[1] = []; - vbox.store[2] = []; + vbox.store.Colours = {}; + vbox.store.Skills = {}; + vbox.store.Specs = {}; } } store.dispatch(actions.setTutorial(stage)); From 75a1c1b3c4283f4c1b4f3e0f0ce43688fd081935 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 29 Nov 2019 00:06:42 +1000 Subject: [PATCH 93/97] duplicate events on same construct won't move --- client/src/events.jsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/src/events.jsx b/client/src/events.jsx index 44b437b0..f1b7e158 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -93,10 +93,12 @@ function registerEvents(store) { if (r.stages.includes('START_SKILL') && anims.animSource) { store.dispatch(actions.setAnimSource(anims.animSource)); + store.dispatch(actions.setAnimText(null)); } if (r.stages.includes('END_SKILL') && anims.animTarget) { store.dispatch(actions.setAnimTarget(anims.animTarget)); + store.dispatch(actions.setAnimText(null)); if (animations.isCbAnim(anims.animSkill)) store.dispatch(actions.setAnimCb(cb)); } @@ -107,9 +109,9 @@ function registerEvents(store) { } else { setTimeout( () => store.dispatch(actions.setAnimText(text)), - timeout - TIMES.POST_SKILL_DURATION_MS - 500 + timeout - TIMES.POST_SKILL_DURATION_MS - 700 ); - timeout -= 500; + timeout -= 700; } } @@ -117,7 +119,7 @@ function registerEvents(store) { store.dispatch(actions.setAnimSkill(null)); store.dispatch(actions.setAnimSource(null)); store.dispatch(actions.setAnimTarget(null)); - store.dispatch(actions.setAnimText(null)); + // store.dispatch(actions.setAnimText(null)); store.dispatch(actions.setAnimFocus([])); if (r.stages.includes('END_SKILL') && animations.isCbAnim(anims.animSkill)) return true; return cb(); From 798b68cff110b13e22a1a8c822ec7353192fb664 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 29 Nov 2019 09:41:09 +1000 Subject: [PATCH 94/97] text cleanup --- client/src/constants.jsx | 3 +-- client/src/tutorial.utils.jsx | 33 +++++++++++++-------------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/client/src/constants.jsx b/client/src/constants.jsx index 708c9089..c6b6dfaf 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -47,8 +47,7 @@ module.exports = { }, Refund: { item: 'Refund', - description:

Refund items refunding the listed cost of the item.
- Click to enable and then click the item to Refund.

, + description: 'Refund the listed cost of a single selected item from the stash.', }, refill: { item: 'REFILL', diff --git a/client/src/tutorial.utils.jsx b/client/src/tutorial.utils.jsx index 2df85c6b..740aa867 100644 --- a/client/src/tutorial.utils.jsx +++ b/client/src/tutorial.utils.jsx @@ -118,7 +118,7 @@ function tutorialStage(tutorial, clearTutorial, instance) {

Tutorial

Welcome to the vbox phase tutorial.

Colours are used to create powerful combinations with base items.

-

Buy the two colours from the vbox to continue.

+

Buy the two colours from the store to continue.

); } @@ -127,11 +127,8 @@ function tutorialStage(tutorial, clearTutorial, instance) { return (

Tutorial

-

In a normal game you start with three base Attack skill items.

-

The Attack item can be combined with colours to create a new skill.

-

Select the Attack item along with two colours.
- Once selected press COMBINE to create a new combo. -

+

You start the game with the base Attack skill item.

+

Highlight all three items then click combine.

); } @@ -143,8 +140,8 @@ function tutorialStage(tutorial, clearTutorial, instance) {

Tutorial

The first construct on your team is {constructOne}.

Skill items can be equipped to your constructs to be used in the combat phase.

-

Click the newly combined skill from the stash.
- Once selected click the construct SKILL slot to equip the skill.

+

Click your new skill from the stash.
+ Once selected click the flashing SKILL slot to equip the skill.

); } @@ -155,7 +152,7 @@ function tutorialStage(tutorial, clearTutorial, instance) {

Tutorial

You can also buy specialisation items for your constructs.
Specialisation items increase stats including power, speed and life.

-

Buy the specialisation item from the vbox to continue.

+

Buy the specialisation item from the store to continue.

); } @@ -166,8 +163,8 @@ function tutorialStage(tutorial, clearTutorial, instance) {

Tutorial

Equipping specialisation items will increase the stats of your constructs.

These can also be combined with colours for further specialisation.

-

Click the specialisation item from the stash.
- Once selected click the construct SPEC slot to equip the specialisation.

+

Click the specialisation item in the stash.
+ Once selected click the flashing SPEC slot to equip the specialisation.

); } @@ -190,13 +187,11 @@ function tutorialStage(tutorial, clearTutorial, instance) { return (

Tutorial

-

Each round you start with a vbox full of different skills, specs and colours.

-

Bits are your currency for buying skills, specs and colours from the vbox.
- Colours cost 1b, Skills cost 2b and specs cost 3b.
- You can refill the vbox by pressing the refill button for 2b.
- After each combat round you get more bits to further upgrade your team. +

Each round you start with 30 bits and a store full of different skills, specs and colours.

+

Bits are your currency for buying items.
+ You can refill the store by pressing the refill button for 2b.

-

Press the REFILL button to get a new vbox and continue.

+

Press the REFILL button to buy new items.

); } @@ -211,9 +206,7 @@ function tutorialStage(tutorial, clearTutorial, instance) {

Tutorial

That completes the VBOX Tutorial.

Press READY to progress to the GAME PHASE
- or continue creating new items to strengthen your constructs further

-

You can unequip skills and specs back into the inventory by double clicking.
- Refund can be used to refund the cost of items in your inventory.

+ You can continue creating new items to upgrade your constructs further.

); } From 3d34d3bbe25615d39c96e6ddac169a1221f32d49 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 29 Nov 2019 12:55:01 +1000 Subject: [PATCH 95/97] keep item fadeout while full combo is selected --- client/src/components/vbox.utils.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/vbox.utils.jsx b/client/src/components/vbox.utils.jsx index 030d308e..4a4a90d1 100644 --- a/client/src/components/vbox.utils.jsx +++ b/client/src/components/vbox.utils.jsx @@ -66,7 +66,7 @@ function setVboxState(dispatch, vboxSelected, state) { dispatch(actions.setVboxInfo(vboxInfo())); dispatch(actions.setVboxCombiner(vboxCombiner)); - dispatch(actions.setVboxHighlight(vboxHighlight.length ? vboxHighlight : null)); + dispatch(actions.setVboxHighlight(vboxHighlight)); } function genItemInfo(item, itemInfo, player) { From 980f03abf61ddff793d907b5a9b15a84f26356c6 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 29 Nov 2019 13:06:01 +1000 Subject: [PATCH 96/97] v1.10.0 --- VERSION | 2 +- acp/package.json | 2 +- client/package.json | 2 +- ops/package.json | 2 +- server/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index ee672d89..ed21137e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.9.1 \ No newline at end of file +1.10.0 \ No newline at end of file diff --git a/acp/package.json b/acp/package.json index ca3b6f27..7a6a5902 100644 --- a/acp/package.json +++ b/acp/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.9.1", + "version": "1.10.0", "description": "", "main": "index.js", "scripts": { diff --git a/client/package.json b/client/package.json index b5585de2..4cbd135c 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.9.1", + "version": "1.10.0", "description": "", "main": "index.js", "scripts": { diff --git a/ops/package.json b/ops/package.json index a3094609..63b2a82e 100644 --- a/ops/package.json +++ b/ops/package.json @@ -1,6 +1,6 @@ { "name": "mnml-ops", - "version": "1.9.1", + "version": "1.10.0", "description": "", "main": "index.js", "scripts": { diff --git a/server/Cargo.toml b/server/Cargo.toml index b666e932..fb7f73c9 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mnml" -version = "1.9.1" +version = "1.10.0" authors = ["ntr "] [dependencies] From 39987d0c9d5380ccb02fdce2f55c882442a9901f Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 29 Nov 2019 13:49:48 +1000 Subject: [PATCH 97/97] fix esc actions --- client/src/actions.jsx | 2 +- client/src/keyboard.jsx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index f6745548..e426f70b 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -49,7 +49,7 @@ export const setTeamSelect = value => ({ type: 'SET_TEAM_SELECT', value: Array.f export const setTutorial = value => ({ type: 'SET_TUTORIAL', value }); export const setTutorialGame = value => ({ type: 'SET_TUTORIAL_GAME', value }); -export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value: Object.create(value) }); +export const setVboxSelected = value => ({ type: 'SET_VBOX_SELECTED', value: value }); export const setVboxCombiner = value => ({ type: 'SET_VBOX_COMBINER', value }); export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value }); export const setVboxInfo = value => ({ type: 'SET_VBOX_INFO', value }); diff --git a/client/src/keyboard.jsx b/client/src/keyboard.jsx index cca738f9..d9cc79ca 100644 --- a/client/src/keyboard.jsx +++ b/client/src/keyboard.jsx @@ -11,6 +11,8 @@ function setupKeys(store) { key('esc', () => store.dispatch(actions.setItemUnequip([]))); key('esc', () => store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] }))); key('esc', () => store.dispatch(actions.setVboxHighlight(null))); + key('esc', () => store.dispatch(actions.setVboxCombiner(null))); + key('esc', () => store.dispatch(actions.setVboxInfo(null))); key('esc', () => store.dispatch(actions.setMtxActive(null))); }