Merge branch 'develop' into svt
This commit is contained in:
commit
937fdae92e
@ -8,6 +8,13 @@ minimal studios is ntr & mashy: 2 mates with a friendship forged in the fires of
|
||||
we have both bailed out of the big city life and have dedicated ourselves to growing farm fresh, organic, ethical gaming produce in the rolling hills of brisbane and leaves of melbourne.
|
||||
completely self funded, we're just here to make games that feel good & play it clean.
|
||||
|
||||
## inspiration
|
||||
- peggle
|
||||
- soldat
|
||||
- mini metro
|
||||
- poe
|
||||
- mtg
|
||||
|
||||
|
||||
## Construct Alignments
|
||||
|
||||
|
||||
@ -19,11 +19,8 @@
|
||||
|
||||
* msg pane
|
||||
* game invites
|
||||
* change score to enum
|
||||
|
||||
* pct based translates for combat animation
|
||||
* add speed to descriptions
|
||||
* clear skill (if currently targetted)
|
||||
|
||||
## SOON
|
||||
*SERVER*
|
||||
|
||||
@ -77,6 +77,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.login {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
@ -109,3 +115,59 @@ section {
|
||||
flex-flow: column;
|
||||
}
|
||||
}
|
||||
|
||||
.demo {
|
||||
margin-top: 1em;
|
||||
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"vinfo game"
|
||||
"vcons game";
|
||||
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: min-content 1fr;
|
||||
|
||||
.colour-info {
|
||||
grid-area: vinfo;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
svg {
|
||||
flex: 1;
|
||||
height: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.vbox-demo {
|
||||
grid-area: vinfo;
|
||||
}
|
||||
|
||||
.game-demo {
|
||||
grid-area: game;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
|
||||
.game {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
.game-construct {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.construct-list {
|
||||
grid-area: vcons;
|
||||
height: 100%;
|
||||
|
||||
svg {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,7 +112,7 @@ button, input {
|
||||
flex: 1;
|
||||
|
||||
/*the transitions */
|
||||
transition-property: color, background;
|
||||
transition-property: border-color, color, background;
|
||||
transition-duration: 0.25s;
|
||||
transition-delay: 0;
|
||||
transition-timing-function: ease;
|
||||
@ -195,28 +195,6 @@ button[disabled] {
|
||||
border-color: #222;
|
||||
}
|
||||
|
||||
/*
|
||||
LOGIN
|
||||
*/
|
||||
|
||||
.welcome {
|
||||
.login {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
#mnml input, #mnml select {
|
||||
border-color: #222;
|
||||
background-color: #222;
|
||||
@ -272,14 +250,6 @@ header {
|
||||
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;
|
||||
|
||||
@ -8,6 +8,8 @@ export const setAnimSource = value => ({ type: 'SET_ANIM_SOURCE', value });
|
||||
export const setAnimTarget = value => ({ type: 'SET_ANIM_TARGET', value });
|
||||
export const setAnimText = value => ({ type: 'SET_ANIM_TEXT', value });
|
||||
|
||||
export const setDemo = value => ({ type: 'SET_DEMO', value });
|
||||
|
||||
export const setActiveItem = value => ({ type: 'SET_ACTIVE_VAR', value });
|
||||
export const setActiveSkill = (constructId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: constructId ? { constructId, skill } : null });
|
||||
export const setCombiner = value => ({ type: 'SET_COMBINER', value: Array.from(value) });
|
||||
|
||||
@ -68,6 +68,7 @@ class ConstructAnimation extends Component {
|
||||
const animSkill = removeTier(skill);
|
||||
if (!constructId.includes(construct.id)) return false;
|
||||
|
||||
|
||||
// find target animation
|
||||
const chooseAnim = (animSkill) => {
|
||||
switch (animSkill) {
|
||||
|
||||
@ -90,7 +90,7 @@ class Absorb extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ class Amplify extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ class Attack extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ class Bash extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ class Bash extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ class Blast extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ class Block extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -107,7 +107,7 @@ class Break extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ class Buff extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -69,10 +69,9 @@ class Chaos extends Component {
|
||||
stroke: colour,
|
||||
});
|
||||
});
|
||||
|
||||
anime.set('.skill-anim', {
|
||||
translateY: -300 * this.props.direction.y,
|
||||
translateX: -200 * this.props.direction.x,
|
||||
translateY: -(window.screen.height) * 0.35 * this.props.direction.y,
|
||||
translateX: -(window.screen.width) * 0.15 * this.props.direction.x,
|
||||
opacity: 0,
|
||||
});
|
||||
anime.set('#explosion feDisplacementMap', {
|
||||
@ -120,7 +119,7 @@ class Chaos extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ class Counter extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ class Curse extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ class Debuff extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -68,7 +68,7 @@ class Decay extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ class Electrify extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -101,7 +101,7 @@ class Electrocute extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ class Haste extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ class Heal extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ class Hex extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -153,7 +153,7 @@ class Hybrid extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@ class Intercept extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ class Link extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ class Purge extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ class Purify extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ class Recharge extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ class Block extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -82,7 +82,7 @@ class Intercept extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ class Refl extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -102,7 +102,7 @@ class Restrict extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ class Ruin extends Component {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
try {
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ class Silence extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -69,9 +69,8 @@ class Siphon extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = addState(Siphon);
|
||||
|
||||
@ -116,7 +116,7 @@ class SiphonTick extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ class Slay extends Component {
|
||||
});
|
||||
|
||||
anime.set('#slay', {
|
||||
translateY: -400,
|
||||
translateY: (window.screen.height) * 0.35 * this.props.direction.y,
|
||||
translateX: 0,
|
||||
});
|
||||
anime.set('#explosion feDisplacementMap', {
|
||||
@ -152,7 +152,7 @@ class Slay extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ class Sleep extends Component {
|
||||
version="1.1"
|
||||
id="sleep"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="-291 -191 582 582">
|
||||
viewBox="-291 -291 582 582">
|
||||
<defs>
|
||||
<filter id="sleepFilter">
|
||||
<feGaussianBlur stdDeviation="3"/>
|
||||
@ -140,7 +140,7 @@ class Sleep extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ class Strike extends Component {
|
||||
});
|
||||
|
||||
anime.set('#strike', {
|
||||
translateY: -400,
|
||||
translateY: (window.screen.height) * 0.35 * this.props.direction.y,
|
||||
translateX: 0,
|
||||
});
|
||||
|
||||
@ -120,7 +120,7 @@ class Strike extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ class Stun extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@ class Sustain extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ class Triage extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ class TriageTick extends Component {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
this.props.animCb();
|
||||
this.props.animCb && this.props.animCb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
179
client/src/components/demo.jsx
Normal file
179
client/src/components/demo.jsx
Normal file
@ -0,0 +1,179 @@
|
||||
const { connect } = require('preact-redux');
|
||||
const preact = require('preact');
|
||||
|
||||
const actions = require('../actions');
|
||||
const shapes = require('./shapes');
|
||||
|
||||
const { ConstructAvatar } = require('./construct');
|
||||
const { ConstructAnimation } = require('./animations');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
account,
|
||||
itemInfo,
|
||||
demo,
|
||||
} = state;
|
||||
|
||||
return {
|
||||
account,
|
||||
itemInfo,
|
||||
demo,
|
||||
};
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setAnimTarget(anim) {
|
||||
dispatch(actions.setAnimTarget(anim));
|
||||
}
|
||||
|
||||
return { setAnimTarget };
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
function Demo(args) {
|
||||
const {
|
||||
demo,
|
||||
itemInfo,
|
||||
account,
|
||||
|
||||
setAnimTarget,
|
||||
} = args;
|
||||
|
||||
if (!demo || !itemInfo.items.length || account) return false;
|
||||
|
||||
const { combiner, items, equipping, equipped, players } = demo;
|
||||
|
||||
console.log(items);
|
||||
|
||||
const vboxDemo = () => {
|
||||
function inventoryBtn(i, j) {
|
||||
if (!i) return <button disabled class='empty' > </button>;
|
||||
const highlighted = combiner.indexOf(j) > -1;
|
||||
const classes = `${highlighted ? 'highlight' : ''}`;
|
||||
|
||||
if (shapes[i]) {
|
||||
return <button class={classes} key={j}>{shapes[i]()}</button>;
|
||||
}
|
||||
|
||||
return <button class={classes}>{i}</button>;
|
||||
}
|
||||
|
||||
function combinerBtn() {
|
||||
let text = '';
|
||||
|
||||
if (combiner.length < 3) {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (combiner.length > i) {
|
||||
text += '■ ';
|
||||
} else {
|
||||
text += '▫ ';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
text = 'combine';
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
class='vbox-btn'
|
||||
disabled={combiner.length !== 3}>
|
||||
{text}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function inventoryElement() {
|
||||
return (
|
||||
<div class="vbox">
|
||||
<div class='vbox-section'>
|
||||
<h2 class='colour-info'>
|
||||
VBOX PHASE {shapes.Red()} {shapes.Green()} {shapes.Blue()}
|
||||
</h2>
|
||||
<p>
|
||||
Combine the colour base items with an array of skills and specialisations to build powerful variants.
|
||||
</p>
|
||||
</div>
|
||||
<div> </div>
|
||||
<div class='vbox-section'>
|
||||
<div class='vbox-items'>
|
||||
{items.map((i, j) => inventoryBtn(i, j))}
|
||||
</div>
|
||||
{combinerBtn()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="news vbox-demo">
|
||||
{inventoryElement()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const vboxConstructs = () => {
|
||||
const btnClass = equipping
|
||||
? 'equipping empty gray'
|
||||
: 'empty gray';
|
||||
|
||||
return (
|
||||
<div class='news construct-list'>
|
||||
{players[0].constructs.map((c, i) => (
|
||||
<div class="instance-construct" key={i}>
|
||||
<h2 class="name" >{c.name}</h2>
|
||||
<ConstructAvatar construct={c} />
|
||||
<div class="skills">
|
||||
{i === 0 && equipped
|
||||
? <button>Strike</button>
|
||||
: <button disabled={!equipping} class={btnClass}>SKILL</button>
|
||||
}
|
||||
<button disabled={!equipping} class={btnClass}>SKILL</button>
|
||||
<button disabled={!equipping} class={btnClass}>SKILL</button>
|
||||
</div>
|
||||
<div class="specs">
|
||||
</div>
|
||||
<div class="stats">
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const gameDemo = () => {
|
||||
return (
|
||||
<div class="game-demo">
|
||||
<div>
|
||||
<h2>COMBAT PHASE</h2>
|
||||
<p>Battle your opponent using dynamic team builds from the VBOX phase.</p>
|
||||
<p>Crafted skills can be used to damage the opponent or support your team.</p>
|
||||
<p>Turn based combat, each team picks targets for their skills during this phase.</p>
|
||||
<p>The damage dealt by skills, cast order and construct life depend on your decisions in the VBOX phase. </p>
|
||||
</div>
|
||||
<div class="game">
|
||||
<div class="game-construct">
|
||||
<ConstructAvatar construct={players[1].constructs[0]} />
|
||||
<ConstructAnimation construct={players[1].constructs[0]} />
|
||||
</div>
|
||||
<div></div>
|
||||
<div class="game-construct">
|
||||
<ConstructAvatar construct={players[1].constructs[1]} />
|
||||
<ConstructAnimation construct={players[1].constructs[1]} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<section class='demo news'>
|
||||
{vboxDemo()}
|
||||
{vboxConstructs()}
|
||||
{gameDemo()}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(Demo);
|
||||
@ -27,8 +27,13 @@ const addState = connect(
|
||||
return ws.sendGameSkillClear(game.id);
|
||||
}
|
||||
|
||||
function sendAbandon() {
|
||||
return ws.sendInstanceAbandon(game.instance);
|
||||
}
|
||||
|
||||
return {
|
||||
game,
|
||||
sendAbandon,
|
||||
sendGameSkillClear,
|
||||
sendReady,
|
||||
account,
|
||||
@ -51,6 +56,7 @@ const addState = connect(
|
||||
function Controls(args) {
|
||||
const {
|
||||
account,
|
||||
sendAbandon,
|
||||
game,
|
||||
animating,
|
||||
sendGameSkillClear,
|
||||
@ -104,7 +110,7 @@ function Controls(args) {
|
||||
<div class="controls">
|
||||
<PlayerBox player={opponent}/>
|
||||
{game.phase === 'Finish' ? quitBtn : readyBtn}
|
||||
<PlayerBox player={player} isPlayer={true} isGame={true} clear={sendGameSkillClear}/>
|
||||
<PlayerBox player={player} isPlayer={true} isGame={true} clear={sendGameSkillClear} abandon={sendAbandon}/>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
|
||||
@ -42,7 +42,6 @@ const addState = connect(
|
||||
function receiveDispatch(dispatch) {
|
||||
function setActiveSkill(constructId, skill) {
|
||||
dispatch(actions.setActiveSkill(constructId, skill));
|
||||
// particlesJS(`particles-${constructId}`, config);
|
||||
}
|
||||
|
||||
function setActiveConstruct(construct) {
|
||||
|
||||
@ -21,15 +21,14 @@ function InfoComponent(args) {
|
||||
return (
|
||||
<div>
|
||||
<h2>VBOX phase</h2>
|
||||
<p>in this phase you strengthen and specialise your constructs by equipping items to them.</p>
|
||||
<p>double clicking items in the <b>VBOX</b> will purchase and move them to your <b>INVENTORY</b>.</p>
|
||||
<p>strengthen and specialise your constructs by equipping items to them.</p>
|
||||
<p>double click to purchase items in the <b>VBOX</b> and move them to your <b>INVENTORY</b>.</p>
|
||||
<p>
|
||||
hover over an item to see its effects and combinations.<br />
|
||||
combine a <b>SKILL</b> or <b>SPEC</b> with 2 <b>COLOURS</b> to create an item.<br />
|
||||
combine 3 of the same item to upgrade it.<br />
|
||||
click an item and then click a construct to equip that item to it.<br />
|
||||
combine <b>3 of the same item</b> to upgrade it.<br />
|
||||
click an item and then click a construct to <b>equip</b> 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>
|
||||
<p>click the <b>READY</b> button for the <b>GAME PHASE</b>.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ function Construct(props) {
|
||||
const stats = Object.keys(STATS).map(s => {
|
||||
const stat = STATS[s];
|
||||
|
||||
const info = (s === 'Speed' && 'Speed')
|
||||
const info = (s === 'SpeedStat' && 'Speed')
|
||||
|| (s.includes('Power') && 'Power')
|
||||
|| (s.includes('Life') && 'Life');
|
||||
|
||||
|
||||
@ -15,12 +15,16 @@ const addState = connect(
|
||||
} = state;
|
||||
|
||||
function sendReady() {
|
||||
document.activeElement.blur()
|
||||
document.activeElement.blur();
|
||||
return ws.sendInstanceReady(instance.id);
|
||||
return false;
|
||||
}
|
||||
|
||||
function sendAbandon() {
|
||||
return ws.sendInstanceAbandon(instance.id);
|
||||
}
|
||||
|
||||
return {
|
||||
sendAbandon,
|
||||
instance,
|
||||
sendReady,
|
||||
account,
|
||||
@ -41,6 +45,7 @@ const addState = connect(
|
||||
function Controls(args) {
|
||||
const {
|
||||
account,
|
||||
sendAbandon,
|
||||
instance,
|
||||
sendReady,
|
||||
leave,
|
||||
@ -77,13 +82,18 @@ function Controls(args) {
|
||||
</div>
|
||||
);
|
||||
|
||||
const ready = instance.phase !== 'Finished'
|
||||
? <button class="ready" onClick={() => sendReady()}>Ready</button>
|
||||
: <button class="ready" onClick={leave}>Leave</button>
|
||||
|
||||
const abandon = instance.phase !== 'Finished' ? sendAbandon : false;
|
||||
return (
|
||||
<aside>
|
||||
{timer}
|
||||
<div class="controls">
|
||||
<PlayerBox player={opponent} />
|
||||
<button class="ready" onClick={() => sendReady()}>Ready</button>
|
||||
<PlayerBox player={player} isPlayer={true} leave={leave}/>
|
||||
{ready}
|
||||
<PlayerBox player={player} isPlayer={true} abandon={abandon}/>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
|
||||
@ -1,18 +1,11 @@
|
||||
const preact = require('preact');
|
||||
|
||||
module.exports = function molecule(combatText) {
|
||||
const text = combatText
|
||||
? <text x="0" y="400" class="combat-text">
|
||||
{combatText}
|
||||
<animate attributeType="XML" attributeName="y" from="300" to="200" dur="2s" repeatCount="1"/>
|
||||
<animate attributeType="XML" attributeName="opacity" from="1" to="0" dur="2s" repeatCount="1"/>
|
||||
</text>
|
||||
: '';
|
||||
|
||||
return (<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 500 500">
|
||||
<rect style="fill: none;"></rect>
|
||||
<g transform="translate(-133.97462520598594, -116.025374794014) "><g><line x1="325.9602631261639" x2="296.95475676906796" y1="332.53171849251754" y2="315.78489034176926" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="267.949250411972" x2="296.95475676906796" y1="299.038062191021" y2="315.78489034176926" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="383.9712758403558" x2="383.9712758403558" y1="433.01268739700697" y2="466.5063436985035" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="383.9712758403558" x2="383.9712758403558" y1="500" y2="466.5063436985035" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="383.9712758403558" x2="383.9712758403558" y1="299.038062191021" y2="265.5444058895245" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="383.9712758403558" x2="383.9712758403558" y1="232.050749588028" y2="265.5444058895245" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="500" x2="470.994493642904" y1="433.01268739700697" y2="416.26585924625874" transform="" style="stroke: #1FF01F; stroke-width: 3; stroke-linecap: butt;"></line><line x1="441.98898728580804" x2="470.994493642904" y1="399.5190310955105" y2="416.26585924625874" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="441.98898728580804" x2="470.994493642904" y1="332.53171849251754" y2="315.78489034176926" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="500" x2="470.994493642904" y1="299.038062191021" y2="315.78489034176926" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="325.9602631261639" x2="296.95475676906796" y1="399.5190310955105" y2="416.26585924625874" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="267.949250411972" x2="296.95475676906796" y1="433.01268739700697" y2="416.26585924625874" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="383.9712758403558" x2="354.96576948325986" y1="299.038062191021" y2="315.78489034176926" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="325.9602631261639" x2="354.96576948325986" y1="332.53171849251754" y2="315.78489034176926" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="441.98898728580804" x2="412.98013156308195" y1="332.53171849251754" y2="315.78489034176926" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="383.9712758403558" x2="412.98013156308195" y1="299.038062191021" y2="315.78489034176926" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="325.9602631261639" x2="325.9602631261639" y1="332.53171849251754" y2="366.02537479401406" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="325.9602631261639" x2="325.9602631261639" y1="399.5190310955105" y2="366.02537479401406" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="383.9712758403558" x2="412.98013156308195" y1="433.01268739700697" y2="416.26585924625874" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="441.98898728580804" x2="412.98013156308195" y1="399.5190310955105" y2="416.26585924625874" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="325.9602631261639" x2="354.96576948325986" y1="399.5190310955105" y2="416.26585924625874" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="383.9712758403558" x2="354.96576948325986" y1="433.01268739700697" y2="416.26585924625874" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="441.98898728580804" x2="441.98898728580804" y1="399.5190310955105" y2="366.02537479401406" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="441.98898728580804" x2="441.98898728580804" y1="332.53171849251754" y2="366.02537479401406" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g class="atom" transform="translate(267.949250411972, 299.038062191021) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(383.9712758403558, 500) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(383.9712758403558, 232.050749588028) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(500, 433.01268739700697) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(500, 299.038062191021) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(267.949250411972, 433.01268739700697) "><circle r="8" style="fill: #1FF01F;"></circle></g>
|
||||
</g>
|
||||
{text}
|
||||
</svg>);
|
||||
module.exports = function molecule() {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 500 500">
|
||||
<rect style="fill: none;"></rect>
|
||||
<g transform="translate(-133.97462520598594, -116.025374794014) "><g><line x1="325.9602631261639" x2="296.95475676906796" y1="332.53171849251754" y2="315.78489034176926" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="267.949250411972" x2="296.95475676906796" y1="299.038062191021" y2="315.78489034176926" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="383.9712758403558" x2="383.9712758403558" y1="433.01268739700697" y2="466.5063436985035" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="383.9712758403558" x2="383.9712758403558" y1="500" y2="466.5063436985035" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="383.9712758403558" x2="383.9712758403558" y1="299.038062191021" y2="265.5444058895245" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="383.9712758403558" x2="383.9712758403558" y1="232.050749588028" y2="265.5444058895245" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="500" x2="470.994493642904" y1="433.01268739700697" y2="416.26585924625874" transform="" style="stroke: #1FF01F; stroke-width: 3; stroke-linecap: butt;"></line><line x1="441.98898728580804" x2="470.994493642904" y1="399.5190310955105" y2="416.26585924625874" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="441.98898728580804" x2="470.994493642904" y1="332.53171849251754" y2="315.78489034176926" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="500" x2="470.994493642904" y1="299.038062191021" y2="315.78489034176926" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="325.9602631261639" x2="296.95475676906796" y1="399.5190310955105" y2="416.26585924625874" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: butt;"></line><line x1="267.949250411972" x2="296.95475676906796" y1="433.01268739700697" y2="416.26585924625874" transform="" style="stroke-width: 3; stroke: #1FF01F;"></line></g><g><line x1="383.9712758403558" x2="354.96576948325986" y1="299.038062191021" y2="315.78489034176926" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="325.9602631261639" x2="354.96576948325986" y1="332.53171849251754" y2="315.78489034176926" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="441.98898728580804" x2="412.98013156308195" y1="332.53171849251754" y2="315.78489034176926" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="383.9712758403558" x2="412.98013156308195" y1="299.038062191021" y2="315.78489034176926" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="325.9602631261639" x2="325.9602631261639" y1="332.53171849251754" y2="366.02537479401406" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="325.9602631261639" x2="325.9602631261639" y1="399.5190310955105" y2="366.02537479401406" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="383.9712758403558" x2="412.98013156308195" y1="433.01268739700697" y2="416.26585924625874" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="441.98898728580804" x2="412.98013156308195" y1="399.5190310955105" y2="416.26585924625874" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="325.9602631261639" x2="354.96576948325986" y1="399.5190310955105" y2="416.26585924625874" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="383.9712758403558" x2="354.96576948325986" y1="433.01268739700697" y2="416.26585924625874" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g><line x1="441.98898728580804" x2="441.98898728580804" y1="399.5190310955105" y2="366.02537479401406" transform="" style="stroke: #909090; stroke-width: 3; stroke-linecap: round;"></line><line x1="441.98898728580804" x2="441.98898728580804" y1="332.53171849251754" y2="366.02537479401406" transform="" style="stroke-width: 3; stroke: #909090;"></line></g><g class="atom" transform="translate(267.949250411972, 299.038062191021) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(383.9712758403558, 500) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(383.9712758403558, 232.050749588028) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(500, 433.01268739700697) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(500, 299.038062191021) "><circle r="8" style="fill: #1FF01F;"></circle></g><g class="atom" transform="translate(267.949250411972, 433.01268739700697) "><circle r="8" style="fill: #1FF01F;"></circle></g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,15 +1,24 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { animating } = state;
|
||||
return { animating };
|
||||
}
|
||||
);
|
||||
|
||||
function Scoreboard(args) {
|
||||
const {
|
||||
abandon,
|
||||
animating,
|
||||
isPlayer,
|
||||
player,
|
||||
isGame,
|
||||
clear,
|
||||
leave,
|
||||
} = args;
|
||||
|
||||
let scoreText = () => {
|
||||
const scoreText = () => {
|
||||
if (player.score === 'Zero') return '▫▫▫▫';
|
||||
if (player.score === 'One') return '■▫▫▫';
|
||||
if (player.score === 'Two') return '■■▫▫';
|
||||
@ -37,14 +46,10 @@ function Scoreboard(args) {
|
||||
<div class="img">
|
||||
<div>{player.name}</div>
|
||||
</div>
|
||||
<div>
|
||||
{(isPlayer && isGame) ? <button onClick={clear}>Clear</button> : null}
|
||||
</div>
|
||||
<div>
|
||||
{leave ? <button onClick={leave}>Leave</button> : null}
|
||||
</div>
|
||||
{(isPlayer && isGame) ? <button disabled={animating} onClick={clear}>Clear</button> : null}
|
||||
{(abandon) ? <button disabled={animating} onClick={abandon}>Abandon</button> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = Scoreboard;
|
||||
module.exports = addState(Scoreboard);
|
||||
|
||||
@ -5,6 +5,7 @@ const Login = require('./welcome.login');
|
||||
const Register = require('./welcome.register');
|
||||
const Help = require('./welcome.help');
|
||||
const About = require('./welcome.about');
|
||||
const Demo = require('./demo');
|
||||
|
||||
function Welcome() {
|
||||
const page = this.state.page || 'login';
|
||||
@ -19,41 +20,57 @@ function Welcome() {
|
||||
};
|
||||
|
||||
return (
|
||||
<main class="welcome">
|
||||
<h1>mnml.gg</h1>
|
||||
<div class="login">
|
||||
<div>mnml is an abstract turn based strategy game</div>
|
||||
<div>free to play</div>
|
||||
<div>no email required</div>
|
||||
<div>glhf</div>
|
||||
<main class="menu">
|
||||
<header>
|
||||
<div class="options">
|
||||
<button
|
||||
class={`login-btn ${page === 'login' ? 'highlight' : ''}`}
|
||||
disabled={page === 'login'}
|
||||
onClick={() => this.setState({ page: 'login' })}>
|
||||
Login
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'register' ? 'highlight' : ''}`}
|
||||
disabled={page === 'register'}
|
||||
onClick={() => this.setState({ page: 'register' })}>
|
||||
Register
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'about' ? 'highlight' : ''}`}
|
||||
disabled={page === 'about'}
|
||||
onClick={() => this.setState({ page: 'about' })}>
|
||||
About
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'help' ? 'highlight' : ''}`}
|
||||
disabled={page === 'help'}
|
||||
onClick={() => this.setState({ page: 'help' })}>
|
||||
Help
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<div class="top">
|
||||
<section>
|
||||
<div class="news">
|
||||
<h1>mnml.gg</h1>
|
||||
<p>
|
||||
mnml is a turn-based 1v1 strategy game in an abstract setting.<br />
|
||||
outplay your opponents by building your team of 3 constructs from a shifting meta of skills, effects and specialisations.<br />
|
||||
</p>
|
||||
<p>
|
||||
simple rules, complex interactions, simultaneous turns to increase the pace, and a unique speed mechanic;<br />
|
||||
mnml is a tactical game unlike any other.
|
||||
</p>
|
||||
<p>
|
||||
free to play<br />
|
||||
no email required<br />
|
||||
glhf
|
||||
</p>
|
||||
</div>
|
||||
{pageEl()}
|
||||
</section>
|
||||
</div>
|
||||
<div class="options">
|
||||
<button
|
||||
class={`login-btn ${page === 'login' ? 'highlight' : ''}`}
|
||||
disabled={page === 'login'}
|
||||
onClick={() => this.setState({ page: 'login' })}>
|
||||
Login
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'register' ? 'highlight' : ''}`}
|
||||
disabled={page === 'register'}
|
||||
onClick={() => this.setState({ page: 'register' })}>
|
||||
Register
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'about' ? 'highlight' : ''}`}
|
||||
disabled={page === 'about'}
|
||||
onClick={() => this.setState({ page: 'about' })}>
|
||||
About
|
||||
</button>
|
||||
<button
|
||||
class={`login-btn ${page === 'help' ? 'highlight' : ''}`}
|
||||
disabled={page === 'help'}
|
||||
onClick={() => this.setState({ page: 'help' })}>
|
||||
Help
|
||||
</button>
|
||||
</div>
|
||||
{pageEl()}
|
||||
<Demo />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@ const addState = connect(
|
||||
ws
|
||||
} = state;
|
||||
|
||||
function submitRegister(name, password, code) {
|
||||
postData('/account/register', { name, password, code })
|
||||
function submitRegister(name, password) {
|
||||
postData('/account/register', { name, password })
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.error) return errorToast(data.error);
|
||||
@ -34,19 +34,18 @@ function Register(args) {
|
||||
submitRegister,
|
||||
} = args;
|
||||
|
||||
const { password, confirm, name, code } = this.state;
|
||||
const { password, confirm, name } = this.state;
|
||||
|
||||
const registerSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
submitRegister(name, password, code);
|
||||
// this.setState({ name: '', password: '', confirm: '', code: ''});
|
||||
submitRegister(name, password);
|
||||
}
|
||||
|
||||
const registerConfirm = () =>
|
||||
password === confirm;
|
||||
|
||||
const registerDisabled = () => {
|
||||
return !(registerConfirm() && password && name && code);
|
||||
return !(registerConfirm() && password && name);
|
||||
}
|
||||
|
||||
return (
|
||||
@ -75,14 +74,6 @@ function Register(args) {
|
||||
value={this.state.confirm}
|
||||
onInput={linkState(this, 'confirm')}
|
||||
/>
|
||||
<label for="code">Access Code</label>
|
||||
<input
|
||||
class="login-input"
|
||||
type="text"
|
||||
placeholder="code"
|
||||
value={this.state.code}
|
||||
onInput={linkState(this, 'code')}
|
||||
/>
|
||||
<button
|
||||
class="login-btn"
|
||||
disabled={registerDisabled()}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
const preact = require('preact');
|
||||
|
||||
const SOURCE_DURATION_MS = 1000;
|
||||
const TARGET_DELAY_MS = 500;
|
||||
const TARGET_DURATION_MS = 1500;
|
||||
@ -24,15 +26,11 @@ module.exports = {
|
||||
INFO: {
|
||||
vbox: {
|
||||
item: 'VBOX',
|
||||
description: 'Contains ITEMS that are available for you to buy.\nDouble-click to purchase.',
|
||||
description: <p><b>ITEMS</b> that are available to buy.<br />the <b>VBOX</b> is refilled every round.<br />click <b>REFILL</b> at the bottom to purchase a refill. </p>,
|
||||
},
|
||||
inventory: {
|
||||
item: 'INVENTORY',
|
||||
description: 'Holds purchased ITEMS.\nClick to add ITEM to I-COMBINATOR.',
|
||||
},
|
||||
combiner: {
|
||||
item: 'I-COMBINATOR',
|
||||
description: 'Combines purchased ITEMS into more powerful variants. Hover over an ITEM to see recipes.',
|
||||
description: <p>holds <b>ITEMS</b><br /><b>ITEMS</b> carry over each round.</p>,
|
||||
},
|
||||
bits: {
|
||||
item: 'BITS',
|
||||
@ -51,12 +49,12 @@ module.exports = {
|
||||
description: 'Reclaim ITEMS for half the purchase cost of their combined ITEMS.\nClick to enable and click ITEM to reclaim.',
|
||||
},
|
||||
refine: {
|
||||
item: 'REFINE',
|
||||
description: 'Refine ITEMS currently in I-COMBINATOR into more powerful variants',
|
||||
item: 'COMBINE',
|
||||
description: <p>combine the selected items.<br />hover over an item to see <b>RECIPES</b>.</p>,
|
||||
},
|
||||
refill: {
|
||||
item: 'REFILL',
|
||||
description: 'Refill the VBOX with new ITEMS.',
|
||||
description: 'Refill the VBOX with new items.',
|
||||
},
|
||||
equipSkills: {
|
||||
item: 'QUICK ACCESS - SKILLS',
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const eachSeries = require('async/eachSeries');
|
||||
const sample = require('lodash/sample');
|
||||
|
||||
const actions = require('./actions');
|
||||
const { TIMES } = require('./constants');
|
||||
@ -179,6 +180,7 @@ function registerEvents(store) {
|
||||
store.dispatch(actions.setActiveConstruct(first));
|
||||
}
|
||||
}
|
||||
if (v.phase === 'Finished') setGame(null);
|
||||
return store.dispatch(actions.setInstance(v));
|
||||
}
|
||||
|
||||
@ -186,6 +188,53 @@ function registerEvents(store) {
|
||||
return store.dispatch(actions.setItemInfo(v));
|
||||
}
|
||||
|
||||
function setDemo(d) {
|
||||
const initial = {
|
||||
players: d,
|
||||
combiner: [],
|
||||
items: ['Red', 'Red', 'Attack'],
|
||||
equipped: false,
|
||||
equipping: false,
|
||||
};
|
||||
|
||||
const startDemo = () => {
|
||||
console.log(initial);
|
||||
store.dispatch(actions.setDemo(initial));
|
||||
store.dispatch(actions.setAnimTarget(null));
|
||||
setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { combiner: [0] }))), 2000);
|
||||
setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { combiner: [0, 1] }))), 4000);
|
||||
setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { combiner: [0, 1, 2] }))), 6000);
|
||||
setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { combiner: [], items: ['Strike', '', ''] }))), 8000);
|
||||
setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { combiner: [0], items: ['Strike', '', ''], equipping: true }))), 10000);
|
||||
setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { combiner: [], items: ['', '', ''], equipped: true, equipping: false }))), 12000);
|
||||
setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { items: ['', '', ''], equipped: true, equipping: false }))), 12000);
|
||||
|
||||
setTimeout(() => {
|
||||
const { itemInfo } = store.getState();
|
||||
return store.dispatch(actions.setAnimTarget({
|
||||
skill: sample(itemInfo.items.filter(i => i.skill)).item,
|
||||
constructId: d[1].constructs[0].id,
|
||||
player: false,
|
||||
direction: 0,
|
||||
}));
|
||||
}, 14000);
|
||||
|
||||
setTimeout(() => {
|
||||
const { itemInfo } = store.getState();
|
||||
return store.dispatch(actions.setAnimTarget({
|
||||
skill: sample(itemInfo.items.filter(i => i.skill)).item,
|
||||
constructId: d[1].constructs[1].id,
|
||||
player: true,
|
||||
direction: 0,
|
||||
}));
|
||||
}, 16000);
|
||||
|
||||
setTimeout(startDemo, 20000);
|
||||
};
|
||||
|
||||
startDemo();
|
||||
}
|
||||
|
||||
// events.on('SET_PLAYER', setInstance);
|
||||
|
||||
// events.on('SEND_SKILL', function skillActive(gameId, constructId, targetConstructId, skill) {
|
||||
@ -229,6 +278,7 @@ function registerEvents(store) {
|
||||
setAccountInstances,
|
||||
setActiveItem,
|
||||
setActiveSkill,
|
||||
setDemo,
|
||||
setConstructList,
|
||||
setNewConstruct,
|
||||
setGame,
|
||||
|
||||
@ -23,6 +23,8 @@ module.exports = {
|
||||
animTarget: createReducer(null, 'SET_ANIM_TARGET'),
|
||||
animText: createReducer(null, 'SET_ANIM_TEXT'),
|
||||
|
||||
demo: createReducer(null, 'SET_DEMO'),
|
||||
|
||||
combiner: createReducer([], 'SET_COMBINER'),
|
||||
constructs: createReducer([], 'SET_CONSTRUCTS'),
|
||||
constructEditId: createReducer(null, 'SET_CONSTRUCT_EDIT_ID'),
|
||||
|
||||
@ -130,6 +130,10 @@ function createSocket(events) {
|
||||
send(['InstanceReady', { instance_id: instanceId }]);
|
||||
}
|
||||
|
||||
function sendInstanceAbandon(instanceId) {
|
||||
send(['InstanceAbandon', { instance_id: instanceId }]);
|
||||
}
|
||||
|
||||
function sendMtxApply(constructId, mtx, name) {
|
||||
send(['MtxConstructApply', { construct_id: constructId, mtx, name }]);
|
||||
if (mtx === 'Rename') {
|
||||
@ -202,10 +206,14 @@ function createSocket(events) {
|
||||
events.setItemInfo(info);
|
||||
}
|
||||
|
||||
function onDemo(v) {
|
||||
events.setDemo(v);
|
||||
}
|
||||
|
||||
let pongTimeout;
|
||||
function onPong() {
|
||||
events.setPing(Date.now() - ping);
|
||||
// pongTimeout = setTimeout(sendPing, 1000);
|
||||
pongTimeout = setTimeout(sendPing, 10000);
|
||||
}
|
||||
|
||||
// -------------
|
||||
@ -227,6 +235,7 @@ function createSocket(events) {
|
||||
InstanceState: onInstanceState,
|
||||
ItemInfo: onItemInfo,
|
||||
Pong: onPong,
|
||||
Demo: onDemo,
|
||||
|
||||
QueueRequested: () => events.notify('pvp queue request received'),
|
||||
QueueJoined: () => events.notify('you have joined the pvp queue'),
|
||||
@ -324,6 +333,7 @@ function createSocket(events) {
|
||||
sendGameSkillClear,
|
||||
sendGameTarget,
|
||||
|
||||
sendInstanceAbandon,
|
||||
sendInstanceReady,
|
||||
sendInstancePractice,
|
||||
sendInstanceQueue,
|
||||
|
||||
@ -288,15 +288,11 @@ pub fn set_subscribed(tx: &mut Transaction, id: Uuid, subscribed: bool) -> Resul
|
||||
Ok(name)
|
||||
}
|
||||
|
||||
pub fn create(name: &String, password: &String, code: &String, tx: &mut Transaction) -> Result<String, MnmlHttpError> {
|
||||
pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result<String, MnmlHttpError> {
|
||||
if password.len() < PASSWORD_MIN_LEN {
|
||||
return Err(MnmlHttpError::PasswordUnacceptable);
|
||||
}
|
||||
|
||||
if code.to_lowercase() != "grep842" {
|
||||
return Err(MnmlHttpError::InvalidCode);
|
||||
}
|
||||
|
||||
if name.len() == 0 {
|
||||
return Err(MnmlHttpError::AccountNameNotProvided);
|
||||
}
|
||||
|
||||
@ -52,8 +52,6 @@ pub enum MnmlHttpError {
|
||||
PasswordUnacceptable,
|
||||
#[fail(display="incorrect token. refresh or logout of existing sessions")]
|
||||
TokenDoesNotMatch,
|
||||
#[fail(display="invalid code. https://discord.gg/YJJgurM")]
|
||||
InvalidCode,
|
||||
}
|
||||
|
||||
impl From<bcrypt::BcryptError> for MnmlHttpError {
|
||||
@ -129,7 +127,6 @@ impl From<MnmlHttpError> for IronError {
|
||||
MnmlHttpError::PasswordUnacceptable => (m_err.compat(), status::BadRequest),
|
||||
|
||||
MnmlHttpError::PasswordNotMatch |
|
||||
MnmlHttpError::InvalidCode |
|
||||
MnmlHttpError::TokenDoesNotMatch |
|
||||
MnmlHttpError::Unauthorized => (m_err.compat(), status::Unauthorized),
|
||||
|
||||
@ -211,7 +208,6 @@ fn token_res(token: String) -> Response {
|
||||
struct RegisterBody {
|
||||
name: String,
|
||||
password: String,
|
||||
code: String,
|
||||
}
|
||||
|
||||
fn register(req: &mut Request) -> IronResult<Response> {
|
||||
@ -224,7 +220,7 @@ fn register(req: &mut Request) -> IronResult<Response> {
|
||||
let db = state.pool.get().or(Err(MnmlHttpError::DbError))?;
|
||||
let mut tx = db.transaction().or(Err(MnmlHttpError::DbError))?;
|
||||
|
||||
match account::create(¶ms.name, ¶ms.password, ¶ms.code, &mut tx) {
|
||||
match account::create(¶ms.name, ¶ms.password, &mut tx) {
|
||||
Ok(token) => {
|
||||
tx.commit().or(Err(MnmlHttpError::ServerError))?;
|
||||
Ok(token_res(token))
|
||||
|
||||
@ -316,10 +316,6 @@ impl Instance {
|
||||
}
|
||||
|
||||
fn finish_condition(&mut self) -> bool {
|
||||
if self.rounds.len() < 4 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// tennis
|
||||
for player in self.players.iter() {
|
||||
if player.score == Score::Win {
|
||||
@ -327,6 +323,10 @@ impl Instance {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Game defaults to lose otherwise
|
||||
if self.rounds.len() < 4 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// both players afk
|
||||
if self.players.iter().all(|p| p.score == Score::Zero) {
|
||||
@ -458,6 +458,13 @@ impl Instance {
|
||||
.ok_or(err_msg("account not in instance"))
|
||||
}
|
||||
|
||||
fn account_opponent(&mut self, account: Uuid) -> Result<&mut Player, Error> {
|
||||
self.players
|
||||
.iter_mut()
|
||||
.find(|p| p.id != account)
|
||||
.ok_or(err_msg("opponent not in instance"))
|
||||
}
|
||||
|
||||
pub fn vbox_action_allowed(&self, account: Uuid) -> Result<(), Error> {
|
||||
if self.players.iter().find(|p| p.id == account).is_none() {
|
||||
return Err(err_msg("player not in this instance"));
|
||||
@ -739,6 +746,14 @@ pub fn pvp(tx: &mut Transaction, a: &Account, b: &Account) -> Result<Instance, E
|
||||
instance_update(tx, instance)
|
||||
}
|
||||
|
||||
pub fn instance_abandon(tx: &mut Transaction, account: &Account, instance_id: Uuid) -> Result<RpcMessage, Error> {
|
||||
let mut instance = instance_get(tx, instance_id)?;
|
||||
instance.account_player(account.id)?.set_lose();
|
||||
instance.account_opponent(account.id)?.set_win();
|
||||
instance.next_round();
|
||||
|
||||
Ok(RpcMessage::InstanceState(instance_update(tx, instance)?))
|
||||
}
|
||||
|
||||
pub fn instance_ready(tx: &mut Transaction, account: &Account, instance_id: Uuid) -> Result<RpcMessage, Error> {
|
||||
let mut instance = instance_get(tx, instance_id)?;
|
||||
@ -800,6 +815,25 @@ pub fn bot_instance() -> Instance {
|
||||
return instance;
|
||||
}
|
||||
|
||||
pub fn demo() -> Result<Vec<Player>, Error> {
|
||||
let bot = bot_player();
|
||||
|
||||
// generate bot imgs for the client to see
|
||||
for c in bot.constructs.iter() {
|
||||
img::molecular_write(c.img)?;
|
||||
};
|
||||
|
||||
let bot2 = bot_player();
|
||||
|
||||
// generate bot imgs for the client to see
|
||||
for c in bot2.constructs.iter() {
|
||||
img::molecular_write(c.img)?;
|
||||
};
|
||||
|
||||
|
||||
Ok(vec![bot, bot2])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@ -27,3 +27,4 @@ pub fn bot_player() -> Player {
|
||||
let constructs = instance_mobs(bot_id);
|
||||
Player::new(bot_id, &name(), constructs).set_bot(true)
|
||||
}
|
||||
|
||||
|
||||
@ -99,6 +99,16 @@ impl Player {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_win(&mut self) -> &mut Player {
|
||||
self.score = Score::Win;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_lose(&mut self) -> &mut Player {
|
||||
self.score = Score::Lose;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn construct_get(&mut self, id: Uuid) -> Result<&mut Construct, Error> {
|
||||
self.constructs.iter_mut().find(|c| c.id == id).ok_or(err_msg("construct not found"))
|
||||
}
|
||||
|
||||
@ -21,10 +21,12 @@ use account;
|
||||
use construct::{Construct};
|
||||
use events::{Event};
|
||||
use game::{Game, game_state, game_skill, game_skill_clear, game_ready};
|
||||
use instance::{Instance, instance_state, instance_practice, instance_ready};
|
||||
use instance::{Instance, instance_state, instance_practice, instance_ready, instance_abandon, demo};
|
||||
use item::{Item, ItemInfoCtr, item_info};
|
||||
use mtx;
|
||||
use mail;
|
||||
|
||||
use player::{Player};
|
||||
use payments;
|
||||
use mail::Email;
|
||||
use pg::{Db};
|
||||
@ -41,6 +43,8 @@ pub enum RpcMessage {
|
||||
AccountInstances(Vec<Instance>),
|
||||
AccountShop(mtx::Shop),
|
||||
|
||||
Demo(Vec<Player>),
|
||||
|
||||
ConstructSpawn(Construct),
|
||||
GameState(Game),
|
||||
ItemInfo(ItemInfoCtr),
|
||||
@ -88,6 +92,7 @@ enum RpcRequest {
|
||||
|
||||
InstanceQueue {},
|
||||
InstancePractice {},
|
||||
InstanceAbandon { instance_id: Uuid },
|
||||
InstanceReady { instance_id: Uuid },
|
||||
InstanceState { instance_id: Uuid },
|
||||
|
||||
@ -184,6 +189,8 @@ impl Connection {
|
||||
Ok(instance_ready(&mut tx, account, instance_id)?),
|
||||
RpcRequest::InstanceState { instance_id } =>
|
||||
Ok(instance_state(&mut tx, instance_id)?),
|
||||
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)?)),
|
||||
@ -268,6 +275,8 @@ impl Handler for Connection {
|
||||
|
||||
// tx should do nothing
|
||||
tx.commit().unwrap();
|
||||
} else {
|
||||
self.ws.send(RpcMessage::Demo(demo().unwrap())).unwrap();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user