Merge branch 'menu-tabs' into develop
This commit is contained in:
commit
5da9c217d4
@ -10,9 +10,9 @@
|
||||
* treats
|
||||
* constructs jiggle when clicked
|
||||
* background colour changes depending on time of day
|
||||
|
||||
* bug fixes
|
||||
* pvp 1st round doesn't resolve until warden timer completes
|
||||
* hit animation wobble
|
||||
* combat text scale + translate
|
||||
* susbcriber gold name in instance
|
||||
|
||||
* bot game grind
|
||||
* stress test
|
||||
|
||||
@ -6,7 +6,6 @@ MNML_PATH=$(realpath "$DIR/../")
|
||||
VERSION=$(<"$MNML_PATH/VERSION")
|
||||
|
||||
SERVER_BIN_DIR="/usr/local/mnml/bin"
|
||||
|
||||
CLIENT_DIST_DIR="/var/lib/mnml/client"
|
||||
CLIENT_PUBLIC_DIR="/var/lib/mnml/public/current"
|
||||
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
@import 'colours.less';
|
||||
|
||||
.account {
|
||||
margin-top: 2em;
|
||||
grid-area: bottom;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
grid-gap: 0 1em;
|
||||
|
||||
@ -8,10 +8,17 @@ aside {
|
||||
"timer controls";
|
||||
|
||||
grid-template-columns: min-content 1fr;
|
||||
grid-template-rows: 1fr 1fr 1fr;
|
||||
grid-gap: 0.5em 0;
|
||||
grid-template-rows: 1fr;
|
||||
|
||||
padding: 1em 1em 1em 0;
|
||||
padding-left: 1em;
|
||||
|
||||
.controls {
|
||||
grid-area: controls;
|
||||
|
||||
display: grid;
|
||||
grid-auto-rows: 1fr;
|
||||
grid-gap: 0.5em 0;
|
||||
}
|
||||
|
||||
// fix chrome being inconsistent
|
||||
table {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
@import 'colours.less';
|
||||
|
||||
.instance {
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
grid-template-columns: 2fr minmax(min-content, 1fr);
|
||||
grid-template-columns: 1fr minmax(min-content, 1fr);
|
||||
grid-template-rows: min-content 1fr;
|
||||
|
||||
grid-template-areas:
|
||||
|
||||
@ -4,16 +4,16 @@
|
||||
height: 100%;
|
||||
display: grid;
|
||||
|
||||
grid-template-rows: minmax(min-content, 2fr) 1fr;
|
||||
grid-template-rows: min-content 1fr 2fr;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
grid-template-areas:
|
||||
"hdr"
|
||||
"top"
|
||||
"bottom";
|
||||
|
||||
.top {
|
||||
grid-area: top;
|
||||
padding: 0 0 0.5em 2em;
|
||||
border-bottom: 0.1em solid #222;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@ -24,9 +24,10 @@
|
||||
|
||||
.team {
|
||||
display: grid;
|
||||
grid-area: top;
|
||||
grid-area: bottom;
|
||||
grid-template-columns: repeat(auto-fill, minmax(min-content, 33%));
|
||||
max-height: 100%;
|
||||
margin-top: 1em;
|
||||
|
||||
.team-select:not(:nth-child(3n)) {
|
||||
margin-right: 0.5em;
|
||||
@ -61,9 +62,6 @@
|
||||
}
|
||||
|
||||
.inventory {
|
||||
margin-top: 2em;
|
||||
grid-area: bottom;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
||||
@ -71,6 +69,10 @@
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.news {
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.list {
|
||||
letter-spacing: 0.25em;
|
||||
text-transform: uppercase;
|
||||
@ -87,4 +89,21 @@
|
||||
flex-flow: column;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
grid-area: hdr;
|
||||
|
||||
button {
|
||||
width: 25%;
|
||||
border-top: 0;
|
||||
border: 1px solid #222;
|
||||
&:not(:last-child) {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ hr {
|
||||
color: #222;
|
||||
margin: 1.5em 0;
|
||||
width: 100%;
|
||||
border-top: 1px solid #222;
|
||||
}
|
||||
|
||||
figure {
|
||||
@ -84,16 +85,17 @@ dl {
|
||||
|
||||
#mnml {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(min-content, 1fr) 8fr 1fr;
|
||||
grid-template-rows: min-content 1fr min-content;
|
||||
grid-template-columns: 9fr 1fr;
|
||||
grid-template-rows: min-content min-content 1fr;
|
||||
grid-template-areas:
|
||||
"hd hd ctrl"
|
||||
"nav main ctrl"
|
||||
"nav main ctrl";
|
||||
"hdr ctrl"
|
||||
"main ctrl"
|
||||
"main ctrl";
|
||||
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 1em;
|
||||
grid-area: main;
|
||||
}
|
||||
|
||||
@ -198,12 +200,6 @@ button[disabled] {
|
||||
*/
|
||||
|
||||
.welcome {
|
||||
.highlight {
|
||||
color: black;
|
||||
background: @white;
|
||||
border: 1px solid @white;
|
||||
}
|
||||
|
||||
.login {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
@ -213,11 +209,6 @@ button[disabled] {
|
||||
|
||||
.options {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
@ -263,3 +254,47 @@ figure.gray {
|
||||
.mobile-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
header {
|
||||
.options {
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
button {
|
||||
&.highlight {
|
||||
color: @white;
|
||||
box-shadow: inset 0px 5px 0px 0px @white;
|
||||
border: 0;
|
||||
&:first-child {
|
||||
border-left: 1px solid #444;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid #444;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
border: 1px solid #444;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-bottom: 1em;
|
||||
list-style: inside;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
const { connect } = require('preact-redux');
|
||||
const preact = require('preact');
|
||||
|
||||
const Team = require('./team');
|
||||
const AccountManagement = require('./account.management');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
ws,
|
||||
account,
|
||||
} = state;
|
||||
|
||||
return {
|
||||
account,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
function Account(args) {
|
||||
const {
|
||||
account,
|
||||
} = args;
|
||||
|
||||
return (
|
||||
<main class="menu">
|
||||
<Team />
|
||||
<AccountManagement />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Account);
|
||||
@ -151,19 +151,9 @@ class AccountStatus extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<section class='account' onClick={tlClick}>
|
||||
<section class='account top' onClick={tlClick}>
|
||||
<div>
|
||||
<h1>{account.name}</h1>
|
||||
<div class="list">
|
||||
<figure>
|
||||
<figcaption>spawn new construct</figcaption>
|
||||
<button onClick={() => sendConstructSpawn()} type="submit">
|
||||
¤50
|
||||
</button>
|
||||
</figure>
|
||||
</div>
|
||||
<button onClick={() => logout()}>Logout</button>
|
||||
<button><a href={`mailto:humans@mnml.gg?subject=Account%20Support:%20${account.name}`}>✉ support</a></button>
|
||||
{subInfo()}
|
||||
</div>
|
||||
<div>
|
||||
<label for="email">Email Settings:</label>
|
||||
@ -216,7 +206,16 @@ class AccountStatus extends Component {
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
{subInfo()}
|
||||
<div class="list">
|
||||
<figure>
|
||||
<figcaption>spawn new construct</figcaption>
|
||||
<button onClick={() => sendConstructSpawn()} type="submit">
|
||||
¤50
|
||||
</button>
|
||||
</figure>
|
||||
</div>
|
||||
<button onClick={() => logout()}>Logout</button>
|
||||
<button><a href={`mailto:humans@mnml.gg?subject=Account%20Support:%20${account.name}`}>✉ support</a></button>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
89
client/src/components/collection.jsx
Normal file
89
client/src/components/collection.jsx
Normal file
@ -0,0 +1,89 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
|
||||
const actions = require('./../actions');
|
||||
const { COLOURS } = require('./../utils');
|
||||
const { ConstructAvatar } = require('./construct');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws, constructs, teamPage, teamSelect } = state;
|
||||
|
||||
function sendConstructSpawn(name) {
|
||||
return ws.sendMtxConstructSpawn(name);
|
||||
}
|
||||
|
||||
return {
|
||||
constructs,
|
||||
teamPage,
|
||||
teamSelect,
|
||||
};
|
||||
},
|
||||
function receiveDispatch(dispatch) {
|
||||
function setTeam(constructIds) {
|
||||
dispatch(actions.setTeamSelect(constructIds));
|
||||
}
|
||||
|
||||
return {
|
||||
setTeam,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
function Collection(args) {
|
||||
const {
|
||||
constructs,
|
||||
teamPage,
|
||||
teamSelect,
|
||||
setTeam,
|
||||
} = args;
|
||||
|
||||
if (!constructs) return <div></div>;
|
||||
|
||||
// redux limitation + suggested workaround
|
||||
// so much for dumb components
|
||||
function selectConstruct(id) {
|
||||
// remove
|
||||
const i = teamSelect.findIndex(sid => sid === id);
|
||||
if (i > -1) {
|
||||
teamSelect[i] = null;
|
||||
return setTeam(teamSelect);
|
||||
}
|
||||
|
||||
// window insert
|
||||
const insert = teamSelect.findIndex(j => j === null);
|
||||
if (insert === -1) return setTeam([id, null, null]);
|
||||
teamSelect[insert] = id;
|
||||
return setTeam(teamSelect);
|
||||
}
|
||||
console.log(constructs.length);
|
||||
const dispConstructs = constructs.length >= ((teamPage + 1) * 6)
|
||||
? constructs.slice(teamPage * 6, (teamPage + 1) * 6)
|
||||
: constructs.slice(teamPage * 6, constructs.length);
|
||||
|
||||
const constructPanels = dispConstructs.map(construct => {
|
||||
const colour = teamSelect.indexOf(construct.id);
|
||||
const selected = colour > -1;
|
||||
|
||||
const borderColour = selected ? COLOURS[colour] : '#000000';
|
||||
|
||||
return (
|
||||
<div
|
||||
key={construct.id}
|
||||
class="construct team-select"
|
||||
style={ { 'border-color': borderColour || 'whitesmoke' } }
|
||||
onClick={() => selectConstruct(construct.id)} >
|
||||
<ConstructAvatar construct={construct} />
|
||||
<h2>{construct.name}</h2>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<section class="team">
|
||||
{constructPanels}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Collection);
|
||||
@ -125,9 +125,11 @@ function Controls(args) {
|
||||
return (
|
||||
<aside class="controls">
|
||||
{timer}
|
||||
<div class="controls">
|
||||
{scoreboard(game, opponent, true)}
|
||||
{game.phase === 'Finish' ? quitBtn : readyBtn}
|
||||
{scoreboard(game, player)}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,40 +1,96 @@
|
||||
// eslint-disable-next-line
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
const preact = require('preact');
|
||||
|
||||
const { saw } = require('./shapes');
|
||||
const actions = require('./../actions');
|
||||
|
||||
function pingColour(ping) {
|
||||
if (ping < 100) return 'forestgreen';
|
||||
if (ping < 200) return 'yellow';
|
||||
return 'red';
|
||||
}
|
||||
const actions = require('../actions');
|
||||
|
||||
const addState = connect(
|
||||
({ account, ping, showNav }) => {
|
||||
return { account, ping };
|
||||
function receiveState(state) {
|
||||
const {
|
||||
ws,
|
||||
account,
|
||||
nav,
|
||||
} = state;
|
||||
|
||||
function sendInstanceState(instance) {
|
||||
return ws.sendInstanceState(instance.id);
|
||||
}
|
||||
|
||||
function sendAccountStates() {
|
||||
ws.sendEmailState();
|
||||
ws.sendSubscriptionState();
|
||||
}
|
||||
|
||||
return {
|
||||
account,
|
||||
nav,
|
||||
|
||||
sendInstanceState,
|
||||
sendAccountStates,
|
||||
};
|
||||
},
|
||||
function receiveDispatch(dispatch) {
|
||||
function setNav(place) {
|
||||
dispatch(actions.setGame(null));
|
||||
dispatch(actions.setInstance(null));
|
||||
dispatch(actions.setCombiner([]));
|
||||
dispatch(actions.setReclaiming(false));
|
||||
dispatch(actions.setActiveSkill(null));
|
||||
dispatch(actions.setActiveConstruct(null));
|
||||
dispatch(actions.setInfo(null));
|
||||
dispatch(actions.setItemEquip(null));
|
||||
dispatch(actions.setItemUnequip([]));
|
||||
dispatch(actions.setVboxHighlight([]));
|
||||
|
||||
return dispatch(actions.setNav(place));
|
||||
}
|
||||
|
||||
return {
|
||||
setNav,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
function renderHeader(args) {
|
||||
const { account, ping } = args;
|
||||
function Header(args) {
|
||||
const {
|
||||
account,
|
||||
nav,
|
||||
|
||||
const accountStatus = account
|
||||
? (<div class="header-status">
|
||||
<h1 class="header-username">{account.name}</h1>
|
||||
{saw(pingColour(ping))}
|
||||
<div class="ping-text">{ping}ms</div>
|
||||
</div>)
|
||||
: '';
|
||||
sendAccountStates,
|
||||
setNav,
|
||||
} = args;
|
||||
|
||||
if (!account) return false;
|
||||
|
||||
function navTo(p) {
|
||||
return setNav(p);
|
||||
}
|
||||
|
||||
function accountClick() {
|
||||
sendAccountStates();
|
||||
navTo('account');
|
||||
}
|
||||
|
||||
return (
|
||||
<header>
|
||||
<h1 class="header-title">mnml.gg</h1>
|
||||
{accountStatus}
|
||||
<div class="options">
|
||||
<button
|
||||
onClick={() => navTo('play')}
|
||||
class={`login-btn ${nav === 'play' ? 'highlight' : ''}`}>
|
||||
MNML
|
||||
</button>
|
||||
<button
|
||||
onClick={() => navTo('shop')}
|
||||
class={`login-btn ${nav === 'shop' ? 'highlight' : ''}`}>
|
||||
Shop
|
||||
</button>
|
||||
<button
|
||||
onClick={accountClick}
|
||||
class={`login-btn ${nav === 'account' ? 'highlight' : ''}`}>
|
||||
⚙ {account.name}
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
module.exports = addState(renderHeader);
|
||||
module.exports = addState(Header);
|
||||
@ -18,7 +18,19 @@ function InfoComponent(args) {
|
||||
// const { info } = args;
|
||||
|
||||
function Info() {
|
||||
if (!info) return false;
|
||||
if (!info) {
|
||||
return (
|
||||
<div>
|
||||
<h2>VBOX phase</h2>
|
||||
<p>double clicking items in the <b>VBOX</b> will purchase and move them to your <b>INVENTORY</b>.</p>
|
||||
<p>
|
||||
hover over an item to see its effects and combinations.<br />
|
||||
click an item and then click a construct to equip that item to it.<br />
|
||||
</p>
|
||||
<p>click the <b>READY</b> button on the right to progress to the <b>GAME PHASE</b>.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const fullInfo = itemInfo.items.find(i => i.item === info) || INFO[info];
|
||||
if (!fullInfo) return false;
|
||||
const isSkill = fullInfo.skill;
|
||||
|
||||
@ -98,7 +98,7 @@ function Construct(props) {
|
||||
const skill = construct.skills[i];
|
||||
const s = skill
|
||||
? skill.skill
|
||||
: (<span class="gray">+</span>);
|
||||
: (<span class="gray">SKILL</span>);
|
||||
|
||||
function skillClick(e) {
|
||||
if (!skill) return false;
|
||||
|
||||
@ -93,11 +93,13 @@ function Controls(args) {
|
||||
);
|
||||
|
||||
return (
|
||||
<aside class="controls">
|
||||
<aside>
|
||||
{timer}
|
||||
<div class="controls">
|
||||
{scoreboard(instance, opponent, true)}
|
||||
<button class="ready" onClick={() => sendReady()}>Ready</button>
|
||||
{scoreboard(instance, player)}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
const { connect } = require('preact-redux');
|
||||
const { Elements } = require('react-stripe-elements');
|
||||
|
||||
const preact = require('preact');
|
||||
const toast = require('izitoast');
|
||||
|
||||
const actions = require('./../actions');
|
||||
const StripeBtns = require('./stripe.buttons');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
ws,
|
||||
account,
|
||||
shop,
|
||||
} = state;
|
||||
|
||||
function mtxBuy(mtx) {
|
||||
return ws.sendMtxBuy(mtx.variant);
|
||||
}
|
||||
|
||||
return {
|
||||
account,
|
||||
shop,
|
||||
mtxBuy,
|
||||
};
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setMtxActive(mtx) {
|
||||
dispatch(actions.setConstructRename(null));
|
||||
dispatch(actions.setMtxActive(mtx));
|
||||
return true;
|
||||
}
|
||||
|
||||
return {
|
||||
setMtxActive,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
function Inventory(args) {
|
||||
const {
|
||||
account,
|
||||
shop,
|
||||
setMtxActive,
|
||||
mtxBuy,
|
||||
} = args;
|
||||
|
||||
if (!shop) return false;
|
||||
|
||||
const useMtx = (item, i) => (
|
||||
<figure key={i} onClick={() => setMtxActive(item)} >
|
||||
<figcaption>{item}</figcaption>
|
||||
<button disabled={account.balance === 0}>¤1</button>
|
||||
</figure>
|
||||
);
|
||||
|
||||
const availableMtx = (item, i) => (
|
||||
<figure key={i} onClick={() => mtxBuy(item)} >
|
||||
<figcaption>{item.variant}</figcaption>
|
||||
<button disabled={account.balance < item.credits}>¤{item.credits}</button>
|
||||
</figure>
|
||||
);
|
||||
|
||||
return (
|
||||
<div class="inventory">
|
||||
<div>
|
||||
<h1>Shop</h1>
|
||||
<Elements>
|
||||
<StripeBtns account={account} />
|
||||
</Elements>
|
||||
<div class='list'>
|
||||
{shop.available.map(availableMtx)}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="credits">¤ {account.balance}</h1>
|
||||
<div class='list'>
|
||||
{shop.owned.map(useMtx)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Inventory);
|
||||
30
client/src/components/main.bottom.jsx
Normal file
30
client/src/components/main.bottom.jsx
Normal file
@ -0,0 +1,30 @@
|
||||
const { connect } = require('preact-redux');
|
||||
const preact = require('preact');
|
||||
|
||||
const actions = require('./../actions');
|
||||
|
||||
const Team = require('./team');
|
||||
const Collection = require('./collection');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
nav,
|
||||
} = state;
|
||||
|
||||
return {
|
||||
nav,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
function Bottom(args) {
|
||||
const {
|
||||
nav,
|
||||
} = args;
|
||||
|
||||
if (nav === 'account') return <Collection />;
|
||||
return <Team />;
|
||||
}
|
||||
|
||||
module.exports = addState(Bottom);
|
||||
@ -5,14 +5,14 @@ const { connect } = require('preact-redux');
|
||||
const Welcome = require('./welcome');
|
||||
const Game = require('./game');
|
||||
const Instance = require('./instance.component');
|
||||
const Team = require('./team');
|
||||
const Play = require('./play');
|
||||
const Account = require('./account.page');
|
||||
const Header = require('./header');
|
||||
const Top = require('./main.top');
|
||||
const Bottom = require('./main.bottom');
|
||||
|
||||
const addState = connect(
|
||||
state => {
|
||||
const { game, instance, account, nav, team, constructs } = state;
|
||||
return { game, instance, account, nav, team, constructs };
|
||||
const { game, instance, account, nav } = state;
|
||||
return { game, instance, account, nav };
|
||||
}
|
||||
);
|
||||
|
||||
@ -37,12 +37,13 @@ function Main(props) {
|
||||
}
|
||||
|
||||
if (nav === 'transition') return false;
|
||||
if (nav === 'play') return <Play />;
|
||||
if (nav === 'team') return <Team />;
|
||||
if (nav === 'account') return <Account />;
|
||||
|
||||
return (
|
||||
<Play />
|
||||
<main class="menu">
|
||||
<Header />
|
||||
<Top />
|
||||
<Bottom />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
34
client/src/components/main.top.jsx
Normal file
34
client/src/components/main.top.jsx
Normal file
@ -0,0 +1,34 @@
|
||||
const { connect } = require('preact-redux');
|
||||
const preact = require('preact');
|
||||
|
||||
const actions = require('./../actions');
|
||||
|
||||
const AccountTop = require('./account.top');
|
||||
const Play = require('./play');
|
||||
const Shop = require('./shop');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
nav,
|
||||
} = state;
|
||||
|
||||
return {
|
||||
nav,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
function Top(args) {
|
||||
const {
|
||||
nav,
|
||||
} = args;
|
||||
|
||||
if (nav === 'account') return <AccountTop />;
|
||||
if (nav === 'play') return <Play />
|
||||
if (nav === 'shop') return <Shop />
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = addState(Top);
|
||||
@ -1,7 +1,6 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
|
||||
// const Header = require('./header');
|
||||
const Main = require('./main');
|
||||
const Nav = require('./nav');
|
||||
const Controls = require('./controls');
|
||||
|
||||
@ -92,7 +92,6 @@ function Nav(args) {
|
||||
|
||||
const canJoin = team.some(c => !c);
|
||||
|
||||
|
||||
return (
|
||||
<nav onClick={hideNav} >
|
||||
<h1 class="header-title">mnml.gg</h1>
|
||||
|
||||
@ -3,7 +3,14 @@ const { connect } = require('preact-redux');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws } = state;
|
||||
const {
|
||||
ws,
|
||||
instances,
|
||||
} = state;
|
||||
|
||||
function sendInstanceState(id) {
|
||||
ws.sendInstanceState(id);
|
||||
}
|
||||
|
||||
function sendInstancePractice() {
|
||||
ws.sendInstancePractice();
|
||||
@ -14,6 +21,9 @@ const addState = connect(
|
||||
}
|
||||
|
||||
return {
|
||||
instances,
|
||||
|
||||
sendInstanceState,
|
||||
sendInstanceQueue,
|
||||
sendInstancePractice,
|
||||
};
|
||||
@ -22,13 +32,33 @@ const addState = connect(
|
||||
|
||||
function JoinButtons(args) {
|
||||
const {
|
||||
instances,
|
||||
|
||||
sendInstanceState,
|
||||
sendInstanceQueue,
|
||||
sendInstancePractice,
|
||||
} = args;
|
||||
|
||||
if (instances.length) {
|
||||
return (
|
||||
<aside class='play-ctrl'>
|
||||
<div class="timer-container"></div>
|
||||
<div class="controls">
|
||||
<button
|
||||
class='pvp ready full'
|
||||
onClick={() => sendInstanceState(instances[0].id)}
|
||||
type="submit">
|
||||
Rejoin
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<aside class='play-ctrl'>
|
||||
<div class="timer-container"></div>
|
||||
<div class="controls">
|
||||
<button
|
||||
class='pvp ready'
|
||||
onClick={() => sendInstanceQueue()}
|
||||
@ -39,8 +69,9 @@ function JoinButtons(args) {
|
||||
class='practice ready'
|
||||
onClick={() => sendInstancePractice()}
|
||||
type="submit">
|
||||
Practice
|
||||
Learn
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,118 +1,128 @@
|
||||
const { connect } = require('preact-redux');
|
||||
// const { connect } = require('preact-redux');
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
const { Elements } = require('react-stripe-elements');
|
||||
|
||||
const Header = require('./header');
|
||||
const Team = require('./team');
|
||||
const StripeBtns = require('./stripe.buttons');
|
||||
|
||||
const { stringSort } = require('./../utils');
|
||||
const { ConstructAvatar } = require('./construct');
|
||||
const actions = require('./../actions');
|
||||
const Inventory = require('./inventory');
|
||||
|
||||
const idSort = stringSort('id');
|
||||
const VERSION = process.env.npm_package_version;
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
ws,
|
||||
constructs,
|
||||
constructRename,
|
||||
team,
|
||||
mtxActive,
|
||||
account,
|
||||
shop,
|
||||
} = state;
|
||||
|
||||
function sendInstancePractice() {
|
||||
return ws.sendInstancePractice();
|
||||
}
|
||||
|
||||
function sendConstructAvatarReroll(id) {
|
||||
console.log('using', mtxActive, 'on', id);
|
||||
return ws.sendMtxApply(id, mtxActive, '');
|
||||
}
|
||||
|
||||
function sendConstructRename(id, name) {
|
||||
ws.sendMtxApply(id, 'Rename', name);
|
||||
function mtxBuy(mtx) {
|
||||
return ws.sendMtxBuy(mtx.variant);
|
||||
}
|
||||
|
||||
return {
|
||||
constructs,
|
||||
mtxActive,
|
||||
constructRename,
|
||||
team,
|
||||
sendConstructRename,
|
||||
sendInstancePractice,
|
||||
sendConstructAvatarReroll,
|
||||
account,
|
||||
shop,
|
||||
mtxBuy,
|
||||
};
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setConstructRename(id) {
|
||||
dispatch(actions.setConstructRename(id));
|
||||
function setMtxActive(mtx) {
|
||||
dispatch(actions.setConstructRename(null));
|
||||
dispatch(actions.setMtxActive(mtx));
|
||||
return true;
|
||||
}
|
||||
|
||||
function clearMtxRename() {
|
||||
dispatch(actions.setConstructRename(null));
|
||||
dispatch(actions.setMtxActive(null));
|
||||
function setNav(place) {
|
||||
return dispatch(actions.setNav(place));
|
||||
}
|
||||
|
||||
return {
|
||||
clearMtxRename,
|
||||
setConstructRename,
|
||||
setMtxActive,
|
||||
setNav,
|
||||
};
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
function Play(args) {
|
||||
const {
|
||||
team,
|
||||
constructRename,
|
||||
clearMtxRename,
|
||||
setConstructRename,
|
||||
sendConstructRename,
|
||||
mtxActive,
|
||||
sendConstructAvatarReroll,
|
||||
account,
|
||||
shop,
|
||||
mtxBuy,
|
||||
|
||||
setMtxActive,
|
||||
setNav,
|
||||
} = args;
|
||||
|
||||
const constructPanels = team
|
||||
.map(construct => {
|
||||
const constructName = constructRename === construct.id
|
||||
? <input id='renameInput' type="text" style="text-align: center" placeholder="enter a new name"></input>
|
||||
: <h2>{construct.name}</h2>;
|
||||
if (!shop) return false;
|
||||
|
||||
const confirm = constructRename === construct.id
|
||||
? <button onClick={() => sendConstructRename(construct.id, document.getElementById('renameInput').value)}>
|
||||
Confirm
|
||||
</button>
|
||||
: false;
|
||||
|
||||
const cancel = constructRename === construct.id
|
||||
? <button onClick={() => clearMtxRename()}>
|
||||
Cancel
|
||||
</button>
|
||||
: false;
|
||||
return (
|
||||
<div
|
||||
key={construct.id}
|
||||
style={ mtxActive ? { cursor: 'pointer' } : {}}
|
||||
onClick={() => {
|
||||
if (!mtxActive) return false;
|
||||
if (mtxActive === 'Rename') return setConstructRename(construct.id);
|
||||
return sendConstructAvatarReroll(construct.id);
|
||||
}}
|
||||
class="construct">
|
||||
<ConstructAvatar construct={construct} />
|
||||
{constructName}
|
||||
{confirm}
|
||||
{cancel}
|
||||
</div>
|
||||
const useMtx = (item, i) => (
|
||||
<figure key={i} onClick={() => setMtxActive(item)} >
|
||||
<figcaption>{item}</figcaption>
|
||||
<button disabled={account.balance === 0}>¤1</button>
|
||||
</figure>
|
||||
);
|
||||
});
|
||||
|
||||
const availableMtx = (item, i) => (
|
||||
<figure key={i} onClick={() => mtxBuy(item)} >
|
||||
<figcaption>{item.variant}</figcaption>
|
||||
<button disabled={account.balance < item.credits}>¤{item.credits}</button>
|
||||
</figure>
|
||||
);
|
||||
|
||||
const subscription = account.subscribed
|
||||
? <button
|
||||
class="stripe-btn"
|
||||
disabled>
|
||||
Subscribed
|
||||
</button>
|
||||
: <button
|
||||
onClick={() => setNav('shop')}
|
||||
class="stripe-btn"
|
||||
role="link">
|
||||
Subscribe
|
||||
</button>;
|
||||
|
||||
|
||||
return (
|
||||
<main class="menu">
|
||||
<div class="team top">
|
||||
{constructPanels}
|
||||
<div class="inventory top">
|
||||
<div class="news">
|
||||
<h1>mnml v{VERSION}</h1>
|
||||
<p>use the buttons on the right to join an instance.</p>
|
||||
<p>
|
||||
select <b>PVP</b> to play against other players.<br />
|
||||
click <b>LEARN</b> to practice the game without time controls.
|
||||
</p>
|
||||
<p>
|
||||
if you enjoy the game please support its development by <b>subscribing</b> or purchasing <b>credits</b>.<br />
|
||||
glhf
|
||||
</p>
|
||||
<p>--ntr & mashy</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="credits">¤ {account.balance}</h1>
|
||||
<div class='list'>
|
||||
{subscription}
|
||||
<button
|
||||
onClick={() => setNav('shop')}
|
||||
class="stripe-btn"
|
||||
role="link">
|
||||
Get Credits
|
||||
</button>
|
||||
<div id="error-message"></div>
|
||||
</div>
|
||||
<div class='list'>
|
||||
{shop.owned.map(useMtx)}
|
||||
</div>
|
||||
<div class='list'>
|
||||
{shop.available.map(availableMtx)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Inventory />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ module.exports = {
|
||||
None: () =>
|
||||
<figure>
|
||||
{diamond(['gray'])}
|
||||
<figcaption> </figcaption>
|
||||
<figcaption>SPEC</figcaption>
|
||||
</figure>,
|
||||
|
||||
|
||||
|
||||
58
client/src/components/shop.jsx
Normal file
58
client/src/components/shop.jsx
Normal file
@ -0,0 +1,58 @@
|
||||
// const { connect } = require('preact-redux');
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
const { Elements } = require('react-stripe-elements');
|
||||
|
||||
const StripeBtns = require('./stripe.buttons');
|
||||
const actions = require('./../actions');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
ws,
|
||||
account,
|
||||
} = state;
|
||||
|
||||
return {
|
||||
account,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
function Shop(args) {
|
||||
const {
|
||||
account,
|
||||
} = args;
|
||||
|
||||
return (
|
||||
<div class="inventory top">
|
||||
<div class="news">
|
||||
<h1>support the game</h1>
|
||||
<p>
|
||||
<b>credits</b> are in game currency that can be used to purchase:
|
||||
<ul>
|
||||
<li>img sets</li>
|
||||
<li>construct renames</li>
|
||||
<li>new constructs</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
<b>subscriptions</b> grant extra benefits:
|
||||
<ul>
|
||||
<li>additional credits</li>
|
||||
<li>chat wheel (soon ™)</li>
|
||||
<li>account icons (soon ™)</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="credits">¤ {account.balance}</h1>
|
||||
<Elements>
|
||||
<StripeBtns account={account} />
|
||||
</Elements>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Shop);
|
||||
@ -6,8 +6,16 @@ function subPlan() {
|
||||
return 'prod_FWSA8RoyMMV3st';
|
||||
}
|
||||
|
||||
function bitsSku() {
|
||||
if (window.location.host === 'mnml.gg') return 'sku_Fjdu7zOy3sLGc5';
|
||||
function bitsSku(d) {
|
||||
if (window.location.host === 'mnml.gg') {
|
||||
if (d === 50) return 'sku_Fl5tLCWogUsgus';
|
||||
if (d === 20) return 'sku_Fl5qegnxYRv7Cy';
|
||||
if (d === 10) return 'sku_Fl5qVosoDsUVgy';
|
||||
if (d === 5) return 'sku_Fjdu7zOy3sLGc5';
|
||||
|
||||
// !!!!
|
||||
return 'sku_Fjdu7zOy3sLGc5';
|
||||
}
|
||||
return 'sku_FjuNxONdWewjH2';
|
||||
}
|
||||
|
||||
@ -16,6 +24,7 @@ function BitsBtn(args) {
|
||||
stripe,
|
||||
account,
|
||||
} = args;
|
||||
|
||||
function subscribeClick() {
|
||||
stripe.redirectToCheckout({
|
||||
items: [{ plan: subPlan(), quantity: 1 }],
|
||||
@ -25,9 +34,9 @@ function BitsBtn(args) {
|
||||
});
|
||||
}
|
||||
|
||||
function bitsClick() {
|
||||
function bitsClick(d) {
|
||||
stripe.redirectToCheckout({
|
||||
items: [{ sku: bitsSku(), quantity: 1 }],
|
||||
items: [{ sku: bitsSku(d), quantity: 1 }],
|
||||
successUrl: window.location.origin,
|
||||
cancelUrl: window.location.origin,
|
||||
clientReferenceId: account.id,
|
||||
@ -48,16 +57,30 @@ function BitsBtn(args) {
|
||||
</button>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div class='list'>
|
||||
{subscription}
|
||||
<button
|
||||
onClick={bitsClick}
|
||||
class="stripe-btn"
|
||||
role="link">
|
||||
Get Credits
|
||||
</button>
|
||||
</div>
|
||||
<div class='list'>
|
||||
<figure onClick={() => bitsClick(5)} >
|
||||
<figcaption>$5 AUD</figcaption>
|
||||
<button class="stripe-btn">¤50</button>
|
||||
</figure>
|
||||
<figure onClick={() => bitsClick(10)} >
|
||||
<figcaption>$10 AUD</figcaption>
|
||||
<button class="stripe-btn">¤110</button>
|
||||
</figure>
|
||||
<figure onClick={() => bitsClick(20)} >
|
||||
<figcaption>$20 AUD</figcaption>
|
||||
<button class="stripe-btn">¤250</button>
|
||||
</figure>
|
||||
<figure onClick={() => bitsClick(50)} >
|
||||
<figcaption>$50 AUD</figcaption>
|
||||
<button class="stripe-btn">¤660</button>
|
||||
</figure>
|
||||
<div id="error-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ function TeamCtrl(args) {
|
||||
class='ready'
|
||||
disabled={teamSelect.some(c => !c)}
|
||||
onClick={sendAccountSetTeam}>
|
||||
Set Team
|
||||
Set
|
||||
</button>
|
||||
<div class="team-page-ctrl">
|
||||
<button onClick={() => setTeamPage(teamPage - 1)} disabled={disableDecrement}> « </button>
|
||||
|
||||
@ -1,88 +1,112 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
const preact = require('preact');
|
||||
|
||||
const actions = require('./../actions');
|
||||
const { COLOURS } = require('./../utils');
|
||||
const { ConstructAvatar } = require('./construct');
|
||||
const actions = require('./../actions');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws, constructs, teamPage, teamSelect } = state;
|
||||
const {
|
||||
ws,
|
||||
constructs,
|
||||
constructRename,
|
||||
team,
|
||||
mtxActive,
|
||||
} = state;
|
||||
|
||||
function sendConstructSpawn(name) {
|
||||
return ws.sendMtxConstructSpawn(name);
|
||||
function sendInstancePractice() {
|
||||
return ws.sendInstancePractice();
|
||||
}
|
||||
|
||||
function sendConstructAvatarReroll(id) {
|
||||
console.log('using', mtxActive, 'on', id);
|
||||
return ws.sendMtxApply(id, mtxActive, '');
|
||||
}
|
||||
|
||||
function sendConstructRename(id, name) {
|
||||
ws.sendMtxApply(id, 'Rename', name);
|
||||
}
|
||||
|
||||
return {
|
||||
constructs,
|
||||
teamPage,
|
||||
teamSelect,
|
||||
mtxActive,
|
||||
constructRename,
|
||||
team,
|
||||
sendConstructRename,
|
||||
sendInstancePractice,
|
||||
sendConstructAvatarReroll,
|
||||
};
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setTeam(constructIds) {
|
||||
dispatch(actions.setTeamSelect(constructIds));
|
||||
function setConstructRename(id) {
|
||||
dispatch(actions.setConstructRename(id));
|
||||
}
|
||||
|
||||
function clearMtxRename() {
|
||||
dispatch(actions.setConstructRename(null));
|
||||
dispatch(actions.setMtxActive(null));
|
||||
}
|
||||
|
||||
return {
|
||||
setTeam,
|
||||
clearMtxRename,
|
||||
setConstructRename,
|
||||
};
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
function Team(args) {
|
||||
const {
|
||||
constructs,
|
||||
teamPage,
|
||||
teamSelect,
|
||||
setTeam,
|
||||
team,
|
||||
constructRename,
|
||||
clearMtxRename,
|
||||
setConstructRename,
|
||||
sendConstructRename,
|
||||
mtxActive,
|
||||
sendConstructAvatarReroll,
|
||||
} = args;
|
||||
|
||||
if (!constructs) return <div></div>;
|
||||
const constructPanels = team
|
||||
.map(construct => {
|
||||
const constructName = constructRename === construct.id
|
||||
? <input id='renameInput' type="text" style="text-align: center" placeholder="enter a new name"></input>
|
||||
: <h2>{construct.name}</h2>;
|
||||
|
||||
// redux limitation + suggested workaround
|
||||
// so much for dumb components
|
||||
function selectConstruct(id) {
|
||||
// remove
|
||||
const i = teamSelect.findIndex(sid => sid === id);
|
||||
if (i > -1) {
|
||||
teamSelect[i] = null;
|
||||
return setTeam(teamSelect);
|
||||
}
|
||||
const confirm = constructRename === construct.id
|
||||
? <button onClick={() => sendConstructRename(construct.id, document.getElementById('renameInput').value)}>
|
||||
Confirm
|
||||
</button>
|
||||
: false;
|
||||
|
||||
// window insert
|
||||
const insert = teamSelect.findIndex(j => j === null);
|
||||
if (insert === -1) return setTeam([id, null, null]);
|
||||
teamSelect[insert] = id;
|
||||
return setTeam(teamSelect);
|
||||
}
|
||||
console.log(constructs.length);
|
||||
const dispConstructs = constructs.length >= ((teamPage + 1) * 6)
|
||||
? constructs.slice(teamPage * 6, (teamPage + 1) * 6)
|
||||
: constructs.slice(teamPage * 6, constructs.length);
|
||||
|
||||
const constructPanels = dispConstructs.map(construct => {
|
||||
const colour = teamSelect.indexOf(construct.id);
|
||||
const selected = colour > -1;
|
||||
|
||||
const borderColour = selected ? COLOURS[colour] : '#000000';
|
||||
const cancel = constructRename === construct.id
|
||||
? <button onClick={() => clearMtxRename()}>
|
||||
Cancel
|
||||
</button>
|
||||
: false;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={construct.id}
|
||||
class="construct team-select"
|
||||
style={ { 'border-color': borderColour || 'whitesmoke' } }
|
||||
onClick={() => selectConstruct(construct.id)} >
|
||||
style={ mtxActive ? { cursor: 'pointer' } : {}}
|
||||
onClick={() => {
|
||||
if (!mtxActive) return false;
|
||||
if (mtxActive === 'Rename') return setConstructRename(construct.id);
|
||||
return sendConstructAvatarReroll(construct.id);
|
||||
}}
|
||||
class="construct">
|
||||
<ConstructAvatar construct={construct} />
|
||||
<h2>{construct.name}</h2>
|
||||
{constructName}
|
||||
{confirm}
|
||||
{cancel}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<section class="team top">
|
||||
<div class="team">
|
||||
{constructPanels}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -192,6 +192,7 @@ function Vbox(args) {
|
||||
|
||||
function onClick(e) {
|
||||
e.stopPropagation();
|
||||
setCombiner([]);
|
||||
if (selected) return clearVboxSelected();
|
||||
return setVboxSelected([group, index]);
|
||||
}
|
||||
@ -203,7 +204,8 @@ function Vbox(args) {
|
||||
<button
|
||||
class={classes}
|
||||
onMouseOver={e => vboxHover(e, v)}
|
||||
onClick={onClick}
|
||||
onMouseDown={onClick}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onDblClick={onDblClick} >
|
||||
{shapes[v]()}
|
||||
</button>
|
||||
@ -213,7 +215,8 @@ function Vbox(args) {
|
||||
return (
|
||||
<button
|
||||
class={classes}
|
||||
onClick={onClick}
|
||||
onMouseDown={onClick}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onDblClick={onDblClick}
|
||||
onMouseOver={e => vboxHover(e, v)}>
|
||||
{v}
|
||||
@ -225,7 +228,8 @@ function Vbox(args) {
|
||||
function vboxElement() {
|
||||
return (
|
||||
<div class='vbox-vbox'
|
||||
onClick={() => setReclaiming(false)}
|
||||
onMouseDown={() => setReclaiming(false)}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onMouseOver={e => hoverInfo(e, 'vbox')}>
|
||||
<div class="vbox-hdr">
|
||||
<h3 onTouchStart={e => e.target.scrollIntoView(true)}>VBOX</h3>
|
||||
@ -241,7 +245,8 @@ function Vbox(args) {
|
||||
<button
|
||||
class='vbox-btn'
|
||||
onMouseOver={e => hoverInfo(e, 'refill')}
|
||||
onClick={() => sendVboxDiscard()}>
|
||||
onClick={e => e.stopPropagation()}
|
||||
onMouseDown={() => sendVboxDiscard()}>
|
||||
refill - 2b
|
||||
</button>
|
||||
</div>
|
||||
@ -251,32 +256,6 @@ function Vbox(args) {
|
||||
//
|
||||
// INVENTORY
|
||||
//
|
||||
|
||||
// const boundTds = range(0, 9).map(i => {
|
||||
// const value = vbox.bound[i];
|
||||
// if (combiner.indexOf(i) > -1) {
|
||||
// return (
|
||||
// <td
|
||||
// key={i}>
|
||||
//
|
||||
// </td>
|
||||
// );
|
||||
// }
|
||||
|
||||
// const highlighted = value && vboxHighlight.includes(value);
|
||||
|
||||
// return (
|
||||
// <td
|
||||
// key={i}
|
||||
// class={`${highlighted ? 'highlight' : ''}`}
|
||||
// onMouseOver={(e) => vboxHover(e, value)}
|
||||
// onClick={e => boundClick(e, i, highlighted) }>
|
||||
// {convertItem(value)}
|
||||
// </td>
|
||||
// );
|
||||
// });
|
||||
|
||||
|
||||
function reclaimClick(e) {
|
||||
e.stopPropagation();
|
||||
return setReclaiming(!reclaiming);
|
||||
@ -292,6 +271,7 @@ function Vbox(args) {
|
||||
}
|
||||
|
||||
function onClick(e) {
|
||||
if (vboxSelecting) clearVboxSelected();
|
||||
if (reclaiming) return sendVboxReclaim(i);
|
||||
|
||||
const combinerIndex = combiner.indexOf(i);
|
||||
@ -310,7 +290,8 @@ function Vbox(args) {
|
||||
<button
|
||||
class={classes}
|
||||
onMouseOver={e => vboxHover(e, v)}
|
||||
onClick={onClick}>
|
||||
onClick={e => e.stopPropagation()}
|
||||
onMouseDown={onClick}>
|
||||
{shapes[v]()}
|
||||
</button>
|
||||
);
|
||||
@ -319,7 +300,8 @@ function Vbox(args) {
|
||||
return (
|
||||
<button
|
||||
class={classes}
|
||||
onClick={onClick}
|
||||
onMouseDown={onClick}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onMouseOver={e => vboxHover(e, v)}>
|
||||
{v}
|
||||
</button>
|
||||
@ -346,7 +328,8 @@ function Vbox(args) {
|
||||
class='vbox-btn'
|
||||
disabled={combiner.length !== 3}
|
||||
onMouseOver={e => hoverInfo(e, 'refine')}
|
||||
onClick={() => sendVboxCombine()}>
|
||||
onClick={e => e.stopPropagation()}
|
||||
onMouseDown={() => sendVboxCombine()}>
|
||||
{text}
|
||||
</button>
|
||||
);
|
||||
@ -363,7 +346,8 @@ function Vbox(args) {
|
||||
|
||||
return (
|
||||
<div class={inventoryClass}
|
||||
onClick={inventoryClick}
|
||||
onMouseDown={inventoryClick}
|
||||
onClick={e => e.stopPropagation()}
|
||||
style={vboxSelecting || itemUnequip.length ? { cursor: 'pointer' } : null}
|
||||
onMouseOver={e => hoverInfo(e, 'inventory')}>
|
||||
<div class="vbox-hdr">
|
||||
@ -371,7 +355,8 @@ function Vbox(args) {
|
||||
<button
|
||||
class='vbox-btn reclaim'
|
||||
onMouseOver={e => hoverInfo(e, 'reclaim')}
|
||||
onClick={reclaimClick}>
|
||||
onClick={e => e.stopPropagation()}
|
||||
onMouseDown={reclaimClick}>
|
||||
reclaim
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -101,7 +101,7 @@
|
||||
## urls will be written to each interval.
|
||||
# urls = ["unix:///var/run/influxdb.sock"]
|
||||
# urls = ["udp://127.0.0.1:8089"]
|
||||
urls = ["http://mnml-prod-elk:8086"]
|
||||
urls = ["http://mnml-prod-mn:8086"]
|
||||
|
||||
## The target database for metrics; will be created as needed.
|
||||
## For UDP url endpoint database needs to be configured on server side.
|
||||
|
||||
@ -53,16 +53,15 @@ pub fn invader_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
colours.push("none".to_string());
|
||||
|
||||
// add up to 100 for %
|
||||
// [3] is the transparent colour
|
||||
let weights = [
|
||||
5,
|
||||
5,
|
||||
65,
|
||||
25,
|
||||
25, // the transparent colour
|
||||
];
|
||||
let colour_dist = WeightedIndex::new(&weights)?;
|
||||
|
||||
write!(&mut svg, "<svg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='-250 -250 1000 1000' width='500' height='500'><g>")?;
|
||||
write!(&mut svg, "<svg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='-250 -250 1000 1000' width='375' height='375'><g>")?;
|
||||
for i in 0..50 {
|
||||
let x = (i % 5) * 50;
|
||||
let y = (i / 5) * 50;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user