This commit is contained in:
ntr
2019-04-25 19:34:53 +10:00
parent 2f4944db10
commit f37cb4a7e4
16 changed files with 417 additions and 245 deletions
+5
View File
@@ -340,6 +340,11 @@ header {
margin: 0;
}
.instance-ui-btn[disabled] {
color: #333;
border-color: #333;
}
.vbox-btn:active, .vbox-btn:hover, .vbox-btn:focus {
color: black;
}
+1
View File
@@ -57,6 +57,7 @@ function GamePanel(props) {
<div className="instance-hdr">
<button
className="game-back-btn instance-btn instance-ui-btn left"
disabled={game.phase !== 'Finish'}
onClick={backClick}>
Back
</button>
+23 -3
View File
@@ -10,12 +10,13 @@ function Info(args) {
info,
sendUnequip,
instance,
player,
setInfo,
} = args;
function infoVar([type, value]) {
let red = 0; let blue = 0; let green = 0;
instance.cryps.forEach(cryp => {
player.cryps.forEach(cryp => {
red += cryp.colours.red;
blue += cryp.colours.blue;
green += cryp.colours.green;
@@ -152,18 +153,37 @@ function Info(args) {
);
}
function scoreBoard() {
const players = instance.players.map((p, i) =>
<tr key={i} >
<td>{p.name}</td>
<td>{p.score.wins} / {p.score.losses}</td>
<td>{p.ready ? 'ready' : ''}</td>
</tr>
);
return (
<table className="vbox-table">
<tbody>
{players}
</tbody>
</table>
);
}
const infoCryp = activeCryp
? infoCrypElement(instance.cryps.find(c => c.id === activeCryp.id))
? infoCrypElement(player.cryps.find(c => c.id === activeCryp.id))
: null;
const otherInfo = info.length
? infoVar(info)
: null;
const instanceInfoClass = `instance-info ${activeCryp ? '' : 'hidden'}`;
const instanceInfoClass = `instance-info ${info.length ? '' : 'hidden'}`;
return (
<div className={instanceInfoClass} >
{scoreBoard()}
{infoCryp}
{otherInfo}
</div>
+3 -1
View File
@@ -10,10 +10,11 @@ const addState = connect(
info,
ws,
instance,
player,
} = state;
function sendUnequip(crypId, item) {
return ws.sendVboxUnequip(instance.instance, crypId, item);
return ws.sendVboxUnequip(instance.id, crypId, item);
}
return {
@@ -21,6 +22,7 @@ const addState = connect(
info,
sendUnequip,
instance,
player,
};
},
+15 -122
View File
@@ -1,120 +1,16 @@
const preact = require('preact');
// const key = require('keymaster');
const range = require('lodash/range');
const mapValues = require('lodash/mapValues');
const VboxContainer = require('./vbox.container');
const InfoContainer = require('./info.container');
const molecule = require('./molecule');
const { SPECS } = require('../utils');
function Cryp(props) {
const {
cryp,
sendVboxApply,
setInfo,
activeVar,
setActiveCryp,
} = props;
const skills = range(0, 3).map(i => {
const skill = cryp.skills[i];
const s = skill
? skill.skill
: (<span>&nbsp;</span>);
function skillClick() {
if (!skill) return false;
setInfo('skill', { skill: skill.skill, cryp });
return setActiveCryp(cryp);
}
return <button key={i} className="cryp-skill-btn right" onClick={skillClick} >{s}</button>;
});
// needed for ondrop to fire
function onDragOver(e) {
e.preventDefault();
return false;
}
function onDrop(e) {
e.stopPropagation();
e.preventDefault();
const item = parseInt(e.dataTransfer.getData('text'), 10);
return sendVboxApply(cryp.id, item);
}
function onClick(e) {
e.stopPropagation();
e.preventDefault();
if (activeVar !== null) return sendVboxApply(cryp.id, activeVar);
setInfo(null);
return setActiveCryp(cryp);
}
const specs = cryp.specs.map((s, i) => {
function specClick() {
setActiveCryp(cryp);
setInfo('spec', { spec: s, cryp });
}
return (
<figure key={i} onClick={specClick}>
{SPECS[s].svg(`stat-icon ${SPECS[s].colour}`)}
<figcaption>{SPECS[s].caption}</figcaption>
</figure>
);
});
const cTotal = cryp.colours.red + cryp.colours.blue + cryp.colours.green;
const colours = mapValues(cryp.colours, c => {
if (cTotal === 0) return 245;
return Math.floor(c / cTotal * 255);
});
const alpha = cTotal === 0 ? 1 : 0.75;
const thickness = total => {
if (total < 3) return 1;
if (total < 6) return 2;
if (total < 9) return 3;
return 4;
};
const border = { border: `${thickness(cTotal)}px solid rgba(${colours.red}, ${colours.green}, ${colours.blue}, ${alpha})` };
return (
<div
key={cryp.id}
className="cryp-box"
onDragOver={onDragOver}
onDrop={onDrop}
style={border}
>
<div className="cryp-box-top">
<figure className="img" onClick={onClick}>
{molecule()}
<figcaption>{cryp.name}</figcaption>
</figure>
<div className="skills">
{skills}
</div>
</div>
<div className="stats">
{specs}
</div>
</div>
);
}
const InstanceCrypsContainer = require('./instance.cryps');
function InstanceComponent(args) {
const {
account,
instance,
player,
quit,
// clearInfo,
sendInstanceReady,
sendVboxApply,
setInfo,
activeVar,
activeCryp,
setActiveVar,
@@ -123,12 +19,6 @@ function InstanceComponent(args) {
if (!instance) return <div>...</div>;
const player = instance.players.find(p => p.account === account.id);
const cryps = player.cryps.map((c, i) => Cryp({
cryp: c, sendVboxApply, setInfo, activeVar, setActiveCryp,
}));
function showVbox(e) {
setActiveVar(null);
setActiveCryp(null);
@@ -162,8 +52,6 @@ function InstanceComponent(args) {
? vboxBtn
: teamBtn;
const crypListClass = `cryp-list ${infoSelected ? '' : 'hidden'}`;
const menuBtn = (
<button
className="instance-btn instance-ui-btn menu-btn left"
@@ -172,6 +60,17 @@ function InstanceComponent(args) {
</button>
);
const readyBtn = (
<button
className="instance-btn instance-ui-btn ready-btn"
onClick={() => sendInstanceReady()}>
Ready
</button>
);
const actionBtn = player
? readyBtn
: null;
return (
<main className="instance" >
@@ -181,16 +80,10 @@ function InstanceComponent(args) {
<div className="spacer">
<div>&nbsp;</div>
</div>
<button
className="instance-btn instance-ui-btn ready-btn"
onClick={() => sendInstanceReady()}>
Ready
</button>
{actionBtn}
</div>
<VboxContainer />
<div className={crypListClass}>
{cryps}
</div>
<InstanceCrypsContainer />
<InfoContainer />
</main>
);
+2 -2
View File
@@ -6,7 +6,7 @@ const Instance = require('./instance.component');
const addState = connect(
function receiveState(state) {
const { ws, instance, account, activeVar, activeCryp } = state;
const { ws, instance, player, account, activeVar, activeCryp } = state;
function sendInstanceReady() {
return ws.sendInstanceReady(instance.id);
@@ -16,7 +16,7 @@ const addState = connect(
return ws.sendVboxApply(instance.id, crypId, i);
}
return { instance, account, sendInstanceReady, sendVboxApply, activeVar, activeCryp };
return { instance, player, account, sendInstanceReady, sendVboxApply, activeVar, activeCryp };
},
function receiveDispatch(dispatch) {
+178
View File
@@ -0,0 +1,178 @@
const { connect } = require('preact-redux');
const preact = require('preact');
const range = require('lodash/range');
const mapValues = require('lodash/mapValues');
const molecule = require('./molecule');
const { SPECS } = require('../utils');
const actions = require('../actions');
const SkillBtn = require('./skill.btn');
const addState = connect(
function receiveState(state) {
const { ws, instance, player, account, activeVar, activeCryp } = state;
function sendInstanceReady() {
return ws.sendInstanceReady(instance.id);
}
function sendVboxApply(crypId, i) {
return ws.sendVboxApply(instance.id, crypId, i);
}
return { instance, player, account, sendInstanceReady, sendVboxApply, activeVar, activeCryp };
},
function receiveDispatch(dispatch) {
function quit() {
dispatch(actions.setInstance(null));
}
function setInfo(item, value) {
dispatch(actions.setInfo([item, value]));
}
function setActiveVar(value) {
dispatch(actions.setActiveVar(value));
}
function setActiveCryp(value) {
dispatch(actions.setActiveCryp(value));
}
function clearInfo() {
return dispatch(actions.setInfo([]));
}
return { quit, clearInfo, setInfo, setActiveVar, setActiveCryp };
}
);
function Cryp(props) {
const {
cryp,
sendVboxApply,
setInfo,
activeVar,
setActiveCryp,
} = props;
const skills = range(0, 3).map(i => {
const skill = cryp.skills[i];
const s = skill
? skill.skill
: (<span>&nbsp;</span>);
function skillClick() {
if (!skill) return false;
setInfo('skill', { skill: skill.skill, cryp });
return setActiveCryp(cryp);
}
return <button key={i} className="cryp-skill-btn right" onClick={skillClick} >{s}</button>;
});
// needed for ondrop to fire
function onDragOver(e) {
e.preventDefault();
return false;
}
function onDrop(e) {
e.stopPropagation();
e.preventDefault();
const item = parseInt(e.dataTransfer.getData('text'), 10);
return sendVboxApply(cryp.id, item);
}
function onClick(e) {
e.stopPropagation();
e.preventDefault();
if (activeVar !== null) return sendVboxApply(cryp.id, activeVar);
setInfo(null);
return setActiveCryp(cryp);
}
const specs = cryp.specs.map((s, i) => {
function specClick() {
setActiveCryp(cryp);
setInfo('spec', { spec: s, cryp });
}
return (
<figure key={i} onClick={specClick}>
{SPECS[s].svg(`stat-icon ${SPECS[s].colour}`)}
<figcaption>{SPECS[s].caption}</figcaption>
</figure>
);
});
const cTotal = cryp.colours.red + cryp.colours.blue + cryp.colours.green;
const colours = mapValues(cryp.colours, c => {
if (cTotal === 0) return 245;
return Math.floor(c / cTotal * 255);
});
const alpha = cTotal === 0 ? 1 : 0.75;
const thickness = total => {
if (total < 3) return 1;
if (total < 6) return 2;
if (total < 9) return 3;
return 4;
};
const border = { border: `${thickness(cTotal)}px solid rgba(${colours.red}, ${colours.green}, ${colours.blue}, ${alpha})` };
return (
<div
key={cryp.id}
className="cryp-box"
onDragOver={onDragOver}
onDrop={onDrop}
style={border}
>
<div className="cryp-box-top">
<figure className="img" onClick={onClick}>
{molecule()}
<figcaption>{cryp.name}</figcaption>
</figure>
<div className="skills">
{skills}
</div>
</div>
<div className="stats">
{specs}
</div>
</div>
);
}
function InstanceCryps(props) {
const {
player,
activeCryp,
activeVar,
// clearInfo,
setInfo,
setActiveCryp,
sendVboxApply,
} = props;
if (!player) return false;
const infoSelected = activeVar !== null || activeCryp;
const crypListClass = `cryp-list ${infoSelected ? '' : 'hidden'}`;
const cryps = player.cryps.map((c, i) => Cryp({
cryp: c, sendVboxApply, setInfo, activeVar, setActiveCryp,
}));
return (
<div className={crypListClass}>
{cryps}
</div>
);
}
module.exports = addState(InstanceCryps);
+14 -5
View File
@@ -24,6 +24,7 @@ function Menu(args) {
sendInstanceState,
sendPlayerMmCrypsSet,
sendInstanceJoin,
sendInstanceNew,
sendCrypSpawn,
instances,
} = args;
@@ -32,14 +33,22 @@ function Menu(args) {
if (!instances) return <div>...</div>;
const instancePanels = instances.map(instance => {
const player = instance.players.find(p => p.account === account.id);
const name = `${instance.name} | ${player.score.wins} : ${player.score.losses}`;
const player = instance.players.find(p => p.id === account.id);
const scoreText = player
? `| ${player.score.wins} : ${player.score.losses}`
: '';
const name = `${instance.name} ${scoreText}`;
function instanceClick() {
if (!player) return sendInstanceJoin(instance);
return sendInstanceState(instance);
}
return (
<button
className={'menu-instance-btn right'}
key={instance.id}
onClick={() => sendInstanceState(instance)}>
onClick={instanceClick}>
{name}
</button>
);
@@ -59,8 +68,8 @@ function Menu(args) {
<button
className={`menu-instance-btn right ${instanceJoinHidden ? 'hidden' : ''}`}
disabled={instanceJoinHidden}
onClick={() => sendInstanceJoin()}>
Join New Instance
onClick={() => sendInstanceNew()}>
Create New Instance
</button>
);
+10 -2
View File
@@ -7,9 +7,16 @@ const addState = connect(
function receiveState(state) {
const { ws, cryps, selectedCryps, instances, account } = state;
function sendInstanceJoin() {
function sendInstanceJoin(instance) {
if (selectedCryps.length) {
return ws.sendInstanceLobby(selectedCryps);
return ws.sendInstanceJoin(instance.id, selectedCryps);
}
return false;
}
function sendInstanceNew() {
if (selectedCryps.length) {
return ws.sendInstanceNew(selectedCryps);
}
return false;
}
@@ -34,6 +41,7 @@ const addState = connect(
cryps,
selectedCryps,
sendInstanceJoin,
sendInstanceNew,
sendInstanceState,
sendCrypSpawn,
sendPlayerMmCrypsSet,
+5 -3
View File
@@ -93,9 +93,11 @@ function registerEvents(store) {
}
function setInstance(v) {
const { account } = store.getState();
const player = v.players.find(p => p.account === account.id);
store.dispatch(actions.setPlayer(player));
const { account, ws } = store.getState();
const player = v.players.find(p => p.id === account.id);
if (player) store.dispatch(actions.setPlayer(player));
if (!v) ws.clearInstanceStateTimeout();
return store.dispatch(actions.setInstance(v));
}
+1
View File
@@ -7,6 +7,7 @@ function setupKeys(store) {
key('esc', () => store.dispatch(actions.setCombiner([null, null, null])));
key('esc', () => store.dispatch(actions.setReclaiming(false)));
key('esc', () => store.dispatch(actions.setActiveSkill(null)));
key('esc', () => store.dispatch(actions.setActiveCryp(null)));
}
module.exports = setupKeys;
+14 -6
View File
@@ -144,12 +144,12 @@ function createSocket(events) {
send({ method: 'zone_close', params: { zone_id: zoneId } });
}
function sendInstanceJoin(cryps) {
send({ method: 'instance_join', params: { cryp_ids: cryps, pve: true } });
function sendInstanceJoin(instanceId, cryps) {
send({ method: 'instance_join', params: { instance_id: instanceId, cryp_ids: cryps } });
}
function sendInstanceLobby(cryps) {
send({ method: 'instance_lobby', params: { cryp_ids: cryps, name: 'dota apem', players: 2 } });
function sendInstanceNew(cryps) {
send({ method: 'instance_new', params: { cryp_ids: cryps, name: 'dota pros onli', players: 2 } });
}
function sendInstanceReady(instanceId) {
@@ -187,7 +187,7 @@ function createSocket(events) {
let gameStateTimeout;
function gameState(response) {
const [structName, game] = response;
clearInterval(gameStateTimeout);
clearTimeout(gameStateTimeout);
gameStateTimeout = setTimeout(() => sendGameState(game.id), 1000);
events.setGame(game);
}
@@ -205,11 +205,19 @@ function createSocket(events) {
events.setZone(zone);
}
let instanceStateTimeout;
function instanceState(response) {
const [structName, i] = response;
clearTimeout(instanceStateTimeout);
instanceStateTimeout = setTimeout(() => sendInstanceState(i.id), 1000);
events.setInstance(i);
}
function clearInstanceStateTimeout() {
clearTimeout(instanceStateTimeout);
}
function instanceScores(response) {
const [structName, scores] = response;
events.setScores(scores);
@@ -334,7 +342,7 @@ function createSocket(events) {
sendZoneClose,
sendInstanceJoin,
sendInstanceReady,
sendInstanceLobby,
sendInstanceNew,
sendInstanceScores,
sendPlayerMmCrypsSet,
sendInstanceState,