lobbiez
This commit is contained in:
parent
2f4944db10
commit
f37cb4a7e4
@ -340,6 +340,11 @@ header {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.instance-ui-btn[disabled] {
|
||||||
|
color: #333;
|
||||||
|
border-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
.vbox-btn:active, .vbox-btn:hover, .vbox-btn:focus {
|
.vbox-btn:active, .vbox-btn:hover, .vbox-btn:focus {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,6 +57,7 @@ function GamePanel(props) {
|
|||||||
<div className="instance-hdr">
|
<div className="instance-hdr">
|
||||||
<button
|
<button
|
||||||
className="game-back-btn instance-btn instance-ui-btn left"
|
className="game-back-btn instance-btn instance-ui-btn left"
|
||||||
|
disabled={game.phase !== 'Finish'}
|
||||||
onClick={backClick}>
|
onClick={backClick}>
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -10,12 +10,13 @@ function Info(args) {
|
|||||||
info,
|
info,
|
||||||
sendUnequip,
|
sendUnequip,
|
||||||
instance,
|
instance,
|
||||||
|
player,
|
||||||
setInfo,
|
setInfo,
|
||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
function infoVar([type, value]) {
|
function infoVar([type, value]) {
|
||||||
let red = 0; let blue = 0; let green = 0;
|
let red = 0; let blue = 0; let green = 0;
|
||||||
instance.cryps.forEach(cryp => {
|
player.cryps.forEach(cryp => {
|
||||||
red += cryp.colours.red;
|
red += cryp.colours.red;
|
||||||
blue += cryp.colours.blue;
|
blue += cryp.colours.blue;
|
||||||
green += cryp.colours.green;
|
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
|
const infoCryp = activeCryp
|
||||||
? infoCrypElement(instance.cryps.find(c => c.id === activeCryp.id))
|
? infoCrypElement(player.cryps.find(c => c.id === activeCryp.id))
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const otherInfo = info.length
|
const otherInfo = info.length
|
||||||
? infoVar(info)
|
? infoVar(info)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const instanceInfoClass = `instance-info ${activeCryp ? '' : 'hidden'}`;
|
const instanceInfoClass = `instance-info ${info.length ? '' : 'hidden'}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={instanceInfoClass} >
|
<div className={instanceInfoClass} >
|
||||||
|
{scoreBoard()}
|
||||||
{infoCryp}
|
{infoCryp}
|
||||||
{otherInfo}
|
{otherInfo}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -10,10 +10,11 @@ const addState = connect(
|
|||||||
info,
|
info,
|
||||||
ws,
|
ws,
|
||||||
instance,
|
instance,
|
||||||
|
player,
|
||||||
} = state;
|
} = state;
|
||||||
|
|
||||||
function sendUnequip(crypId, item) {
|
function sendUnequip(crypId, item) {
|
||||||
return ws.sendVboxUnequip(instance.instance, crypId, item);
|
return ws.sendVboxUnequip(instance.id, crypId, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -21,6 +22,7 @@ const addState = connect(
|
|||||||
info,
|
info,
|
||||||
sendUnequip,
|
sendUnequip,
|
||||||
instance,
|
instance,
|
||||||
|
player,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -1,120 +1,16 @@
|
|||||||
const preact = require('preact');
|
const preact = require('preact');
|
||||||
// const key = require('keymaster');
|
|
||||||
const range = require('lodash/range');
|
|
||||||
const mapValues = require('lodash/mapValues');
|
|
||||||
|
|
||||||
const VboxContainer = require('./vbox.container');
|
const VboxContainer = require('./vbox.container');
|
||||||
const InfoContainer = require('./info.container');
|
const InfoContainer = require('./info.container');
|
||||||
const molecule = require('./molecule');
|
const InstanceCrypsContainer = require('./instance.cryps');
|
||||||
|
|
||||||
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> </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 InstanceComponent(args) {
|
function InstanceComponent(args) {
|
||||||
const {
|
const {
|
||||||
account,
|
|
||||||
instance,
|
instance,
|
||||||
|
player,
|
||||||
quit,
|
quit,
|
||||||
// clearInfo,
|
// clearInfo,
|
||||||
sendInstanceReady,
|
sendInstanceReady,
|
||||||
sendVboxApply,
|
|
||||||
setInfo,
|
|
||||||
activeVar,
|
activeVar,
|
||||||
activeCryp,
|
activeCryp,
|
||||||
setActiveVar,
|
setActiveVar,
|
||||||
@ -123,12 +19,6 @@ function InstanceComponent(args) {
|
|||||||
|
|
||||||
if (!instance) return <div>...</div>;
|
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) {
|
function showVbox(e) {
|
||||||
setActiveVar(null);
|
setActiveVar(null);
|
||||||
setActiveCryp(null);
|
setActiveCryp(null);
|
||||||
@ -162,8 +52,6 @@ function InstanceComponent(args) {
|
|||||||
? vboxBtn
|
? vboxBtn
|
||||||
: teamBtn;
|
: teamBtn;
|
||||||
|
|
||||||
const crypListClass = `cryp-list ${infoSelected ? '' : 'hidden'}`;
|
|
||||||
|
|
||||||
const menuBtn = (
|
const menuBtn = (
|
||||||
<button
|
<button
|
||||||
className="instance-btn instance-ui-btn menu-btn left"
|
className="instance-btn instance-ui-btn menu-btn left"
|
||||||
@ -172,6 +60,17 @@ function InstanceComponent(args) {
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const readyBtn = (
|
||||||
|
<button
|
||||||
|
className="instance-btn instance-ui-btn ready-btn"
|
||||||
|
onClick={() => sendInstanceReady()}>
|
||||||
|
Ready
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
const actionBtn = player
|
||||||
|
? readyBtn
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="instance" >
|
<main className="instance" >
|
||||||
@ -181,16 +80,10 @@ function InstanceComponent(args) {
|
|||||||
<div className="spacer">
|
<div className="spacer">
|
||||||
<div> </div>
|
<div> </div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
{actionBtn}
|
||||||
className="instance-btn instance-ui-btn ready-btn"
|
|
||||||
onClick={() => sendInstanceReady()}>
|
|
||||||
Ready
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<VboxContainer />
|
<VboxContainer />
|
||||||
<div className={crypListClass}>
|
<InstanceCrypsContainer />
|
||||||
{cryps}
|
|
||||||
</div>
|
|
||||||
<InfoContainer />
|
<InfoContainer />
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,7 +6,7 @@ const Instance = require('./instance.component');
|
|||||||
|
|
||||||
const addState = connect(
|
const addState = connect(
|
||||||
function receiveState(state) {
|
function receiveState(state) {
|
||||||
const { ws, instance, account, activeVar, activeCryp } = state;
|
const { ws, instance, player, account, activeVar, activeCryp } = state;
|
||||||
|
|
||||||
function sendInstanceReady() {
|
function sendInstanceReady() {
|
||||||
return ws.sendInstanceReady(instance.id);
|
return ws.sendInstanceReady(instance.id);
|
||||||
@ -16,7 +16,7 @@ const addState = connect(
|
|||||||
return ws.sendVboxApply(instance.id, crypId, i);
|
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) {
|
function receiveDispatch(dispatch) {
|
||||||
|
|||||||
178
client/src/components/instance.cryps.jsx
Normal file
178
client/src/components/instance.cryps.jsx
Normal 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> </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);
|
||||||
@ -24,6 +24,7 @@ function Menu(args) {
|
|||||||
sendInstanceState,
|
sendInstanceState,
|
||||||
sendPlayerMmCrypsSet,
|
sendPlayerMmCrypsSet,
|
||||||
sendInstanceJoin,
|
sendInstanceJoin,
|
||||||
|
sendInstanceNew,
|
||||||
sendCrypSpawn,
|
sendCrypSpawn,
|
||||||
instances,
|
instances,
|
||||||
} = args;
|
} = args;
|
||||||
@ -32,14 +33,22 @@ function Menu(args) {
|
|||||||
if (!instances) return <div>...</div>;
|
if (!instances) return <div>...</div>;
|
||||||
|
|
||||||
const instancePanels = instances.map(instance => {
|
const instancePanels = instances.map(instance => {
|
||||||
const player = instance.players.find(p => p.account === account.id);
|
const player = instance.players.find(p => p.id === account.id);
|
||||||
const name = `${instance.name} | ${player.score.wins} : ${player.score.losses}`;
|
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 (
|
return (
|
||||||
<button
|
<button
|
||||||
className={'menu-instance-btn right'}
|
className={'menu-instance-btn right'}
|
||||||
key={instance.id}
|
key={instance.id}
|
||||||
onClick={() => sendInstanceState(instance)}>
|
onClick={instanceClick}>
|
||||||
{name}
|
{name}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
@ -59,8 +68,8 @@ function Menu(args) {
|
|||||||
<button
|
<button
|
||||||
className={`menu-instance-btn right ${instanceJoinHidden ? 'hidden' : ''}`}
|
className={`menu-instance-btn right ${instanceJoinHidden ? 'hidden' : ''}`}
|
||||||
disabled={instanceJoinHidden}
|
disabled={instanceJoinHidden}
|
||||||
onClick={() => sendInstanceJoin()}>
|
onClick={() => sendInstanceNew()}>
|
||||||
Join New Instance
|
Create New Instance
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -7,9 +7,16 @@ const addState = connect(
|
|||||||
function receiveState(state) {
|
function receiveState(state) {
|
||||||
const { ws, cryps, selectedCryps, instances, account } = state;
|
const { ws, cryps, selectedCryps, instances, account } = state;
|
||||||
|
|
||||||
function sendInstanceJoin() {
|
function sendInstanceJoin(instance) {
|
||||||
if (selectedCryps.length) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
@ -34,6 +41,7 @@ const addState = connect(
|
|||||||
cryps,
|
cryps,
|
||||||
selectedCryps,
|
selectedCryps,
|
||||||
sendInstanceJoin,
|
sendInstanceJoin,
|
||||||
|
sendInstanceNew,
|
||||||
sendInstanceState,
|
sendInstanceState,
|
||||||
sendCrypSpawn,
|
sendCrypSpawn,
|
||||||
sendPlayerMmCrypsSet,
|
sendPlayerMmCrypsSet,
|
||||||
|
|||||||
@ -93,9 +93,11 @@ function registerEvents(store) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setInstance(v) {
|
function setInstance(v) {
|
||||||
const { account } = store.getState();
|
const { account, ws } = store.getState();
|
||||||
const player = v.players.find(p => p.account === account.id);
|
const player = v.players.find(p => p.id === account.id);
|
||||||
store.dispatch(actions.setPlayer(player));
|
if (player) store.dispatch(actions.setPlayer(player));
|
||||||
|
|
||||||
|
if (!v) ws.clearInstanceStateTimeout();
|
||||||
return store.dispatch(actions.setInstance(v));
|
return store.dispatch(actions.setInstance(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ function setupKeys(store) {
|
|||||||
key('esc', () => store.dispatch(actions.setCombiner([null, null, null])));
|
key('esc', () => store.dispatch(actions.setCombiner([null, null, null])));
|
||||||
key('esc', () => store.dispatch(actions.setReclaiming(false)));
|
key('esc', () => store.dispatch(actions.setReclaiming(false)));
|
||||||
key('esc', () => store.dispatch(actions.setActiveSkill(null)));
|
key('esc', () => store.dispatch(actions.setActiveSkill(null)));
|
||||||
|
key('esc', () => store.dispatch(actions.setActiveCryp(null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = setupKeys;
|
module.exports = setupKeys;
|
||||||
|
|||||||
@ -144,12 +144,12 @@ function createSocket(events) {
|
|||||||
send({ method: 'zone_close', params: { zone_id: zoneId } });
|
send({ method: 'zone_close', params: { zone_id: zoneId } });
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendInstanceJoin(cryps) {
|
function sendInstanceJoin(instanceId, cryps) {
|
||||||
send({ method: 'instance_join', params: { cryp_ids: cryps, pve: true } });
|
send({ method: 'instance_join', params: { instance_id: instanceId, cryp_ids: cryps } });
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendInstanceLobby(cryps) {
|
function sendInstanceNew(cryps) {
|
||||||
send({ method: 'instance_lobby', params: { cryp_ids: cryps, name: 'dota apem', players: 2 } });
|
send({ method: 'instance_new', params: { cryp_ids: cryps, name: 'dota pros onli', players: 2 } });
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendInstanceReady(instanceId) {
|
function sendInstanceReady(instanceId) {
|
||||||
@ -187,7 +187,7 @@ function createSocket(events) {
|
|||||||
let gameStateTimeout;
|
let gameStateTimeout;
|
||||||
function gameState(response) {
|
function gameState(response) {
|
||||||
const [structName, game] = response;
|
const [structName, game] = response;
|
||||||
clearInterval(gameStateTimeout);
|
clearTimeout(gameStateTimeout);
|
||||||
gameStateTimeout = setTimeout(() => sendGameState(game.id), 1000);
|
gameStateTimeout = setTimeout(() => sendGameState(game.id), 1000);
|
||||||
events.setGame(game);
|
events.setGame(game);
|
||||||
}
|
}
|
||||||
@ -205,11 +205,19 @@ function createSocket(events) {
|
|||||||
events.setZone(zone);
|
events.setZone(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let instanceStateTimeout;
|
||||||
function instanceState(response) {
|
function instanceState(response) {
|
||||||
const [structName, i] = response;
|
const [structName, i] = response;
|
||||||
|
clearTimeout(instanceStateTimeout);
|
||||||
|
instanceStateTimeout = setTimeout(() => sendInstanceState(i.id), 1000);
|
||||||
events.setInstance(i);
|
events.setInstance(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearInstanceStateTimeout() {
|
||||||
|
clearTimeout(instanceStateTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function instanceScores(response) {
|
function instanceScores(response) {
|
||||||
const [structName, scores] = response;
|
const [structName, scores] = response;
|
||||||
events.setScores(scores);
|
events.setScores(scores);
|
||||||
@ -334,7 +342,7 @@ function createSocket(events) {
|
|||||||
sendZoneClose,
|
sendZoneClose,
|
||||||
sendInstanceJoin,
|
sendInstanceJoin,
|
||||||
sendInstanceReady,
|
sendInstanceReady,
|
||||||
sendInstanceLobby,
|
sendInstanceNew,
|
||||||
sendInstanceScores,
|
sendInstanceScores,
|
||||||
sendPlayerMmCrypsSet,
|
sendPlayerMmCrypsSet,
|
||||||
sendInstanceState,
|
sendInstanceState,
|
||||||
|
|||||||
@ -860,7 +860,7 @@ pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> {
|
|||||||
// Ok(game)
|
// Ok(game)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn game_instance_new(tx: &mut Transaction, player: Player, game_id: Uuid) -> Result<Game, Error> {
|
pub fn game_instance_new(tx: &mut Transaction, players: Vec<Player>, game_id: Uuid, instance_id: Uuid) -> Result<Game, Error> {
|
||||||
// create the game
|
// create the game
|
||||||
let mut game = Game::new();
|
let mut game = Game::new();
|
||||||
game.id = game_id;
|
game.id = game_id;
|
||||||
@ -868,14 +868,19 @@ pub fn game_instance_new(tx: &mut Transaction, player: Player, game_id: Uuid) ->
|
|||||||
game
|
game
|
||||||
.set_team_num(2)
|
.set_team_num(2)
|
||||||
.set_team_size(3)
|
.set_team_size(3)
|
||||||
.set_instance(player.instance)
|
.set_instance(instance_id)
|
||||||
.set_mode(GameMode::Pvp);
|
.set_mode(GameMode::Pvp);
|
||||||
|
|
||||||
// create the initiators team
|
// create the initiators team
|
||||||
let mut team = Team::new(player.account);
|
for player in players {
|
||||||
team.set_cryps(player.cryps);
|
let mut team = Team::new(player.id);
|
||||||
|
team.set_cryps(player.cryps);
|
||||||
|
game.team_add(team)?;
|
||||||
|
}
|
||||||
|
|
||||||
game.team_add(team)?;
|
if game.can_start() {
|
||||||
|
game = game.start();
|
||||||
|
}
|
||||||
|
|
||||||
// persist
|
// persist
|
||||||
game_write(&game, tx)?;
|
game_write(&game, tx)?;
|
||||||
@ -886,7 +891,7 @@ pub fn game_instance_new(tx: &mut Transaction, player: Player, game_id: Uuid) ->
|
|||||||
pub fn game_instance_join(tx: &mut Transaction, player: Player, game_id: Uuid) -> Result<Game, Error> {
|
pub fn game_instance_join(tx: &mut Transaction, player: Player, game_id: Uuid) -> Result<Game, Error> {
|
||||||
let mut game = game_get(tx, game_id)?;
|
let mut game = game_get(tx, game_id)?;
|
||||||
|
|
||||||
let mut team = Team::new(player.account);
|
let mut team = Team::new(player.id);
|
||||||
team.set_cryps(player.cryps);
|
team.set_cryps(player.cryps);
|
||||||
game.team_add(team)?;
|
game.team_add(team)?;
|
||||||
|
|
||||||
|
|||||||
@ -14,14 +14,14 @@ use account::Account;
|
|||||||
use player::{Player, Score, player_create, player_get, player_update};
|
use player::{Player, Score, player_create, player_get, player_update};
|
||||||
use cryp::{Cryp, cryp_get};
|
use cryp::{Cryp, cryp_get};
|
||||||
use mob::{instance_mobs};
|
use mob::{instance_mobs};
|
||||||
use game::{Game, Team, game_get, game_write, game_instance_new, game_instance_join, game_global_get, game_global_set};
|
use game::{Game, Phase, Team, game_get, game_write, game_instance_new, game_instance_join, game_global_get, game_global_set};
|
||||||
use vbox::{Var};
|
use vbox::{Var};
|
||||||
|
use rpc::{RpcResult};
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
enum InstancePhase {
|
enum InstancePhase {
|
||||||
Open,
|
Lobby,
|
||||||
Vbox,
|
InProgress,
|
||||||
Games,
|
|
||||||
Finished,
|
Finished,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ impl Instance {
|
|||||||
id: Uuid::new_v4(),
|
id: Uuid::new_v4(),
|
||||||
players: vec![],
|
players: vec![],
|
||||||
rounds: vec![],
|
rounds: vec![],
|
||||||
phase: InstancePhase::Open,
|
phase: InstancePhase::Lobby,
|
||||||
open: true,
|
open: true,
|
||||||
max_players: 2,
|
max_players: 2,
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
@ -63,7 +63,7 @@ impl Instance {
|
|||||||
id: Uuid::nil(),
|
id: Uuid::nil(),
|
||||||
players: vec![player],
|
players: vec![player],
|
||||||
rounds: vec![],
|
rounds: vec![],
|
||||||
phase: InstancePhase::Vbox,
|
phase: InstancePhase::InProgress,
|
||||||
open: false,
|
open: false,
|
||||||
max_players: 0,
|
max_players: 0,
|
||||||
name: "Global Matchmaking".to_string(),
|
name: "Global Matchmaking".to_string(),
|
||||||
@ -103,13 +103,18 @@ impl Instance {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_player(&mut self, player: Player) -> &mut Instance {
|
fn add_player(&mut self, player: Player) -> Result<&mut Instance, Error> {
|
||||||
|
match self.players.iter().find(|p| p.id == player.id) {
|
||||||
|
Some(p) => return Err(err_msg("already joined")),
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
|
||||||
self.players.push(player);
|
self.players.push(player);
|
||||||
self
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn player_update(mut self, player: Player, ignore_phase: bool) -> Result<Instance, Error> {
|
pub fn player_update(mut self, player: Player, ignore_phase: bool) -> Result<Instance, Error> {
|
||||||
if !ignore_phase && self.phase != InstancePhase::Vbox {
|
if !ignore_phase && self.phase != InstancePhase::InProgress {
|
||||||
return Err(format_err!("instance not in vbox phase ({:?})", self.phase));
|
return Err(format_err!("instance not in vbox phase ({:?})", self.phase));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +129,7 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn player_ready(&mut self, player_id: Uuid) -> Result<&mut Instance, Error> {
|
fn player_ready(&mut self, player_id: Uuid) -> Result<&mut Instance, Error> {
|
||||||
if ![InstancePhase::Vbox, InstancePhase::Open].contains(&self.phase) {
|
if ![InstancePhase::InProgress, InstancePhase::Lobby].contains(&self.phase) {
|
||||||
return Err(err_msg("instance not in start or vbox phase"));
|
return Err(err_msg("instance not in start or vbox phase"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,27 +140,17 @@ impl Instance {
|
|||||||
|
|
||||||
self.players[i].set_ready(true);
|
self.players[i].set_ready(true);
|
||||||
|
|
||||||
match self.phase {
|
if self.phase == InstancePhase::Lobby && self.can_start() {
|
||||||
InstancePhase::Open => {
|
self.start();
|
||||||
if self.can_start() {
|
|
||||||
self.start();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
InstancePhase::Vbox => {
|
|
||||||
if self.all_ready() {
|
|
||||||
self.games_phase_start();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => panic!("unhandled ready phase"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn player_has_pve_game(&self, player: &Player) -> bool {
|
fn player_has_pve_game(&self, player_id: Uuid) -> bool {
|
||||||
let opponent_id = self.current_round(&player).player_ids
|
let opponent_id = self.current_round(player_id).player_ids
|
||||||
.iter()
|
.iter()
|
||||||
.find(|p| **p != player.id)
|
.find(|p| **p != player_id)
|
||||||
.expect("unable to find opponent");
|
.expect("unable to find opponent");
|
||||||
|
|
||||||
return self.players
|
return self.players
|
||||||
@ -165,11 +160,11 @@ impl Instance {
|
|||||||
.bot;
|
.bot;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bot_vs_player_game(&self, player: &Player) -> Result<Game, Error> {
|
fn bot_vs_player_game(&self, player_id: Uuid) -> Result<Game, Error> {
|
||||||
let current_round = self.current_round(player);
|
let current_round = self.current_round(player_id);
|
||||||
let bot_id = current_round.player_ids.iter().find(|id| **id != player.id).unwrap();
|
let bot_id = current_round.player_ids.iter().find(|id| **id != player_id).unwrap();
|
||||||
|
|
||||||
let plr = self.players.clone().into_iter().find(|p| p.id == player.id).unwrap();
|
let plr = self.players.clone().into_iter().find(|p| p.id == player_id).unwrap();
|
||||||
let bot = self.players.clone().into_iter().find(|p| p.id == *bot_id).unwrap();
|
let bot = self.players.clone().into_iter().find(|p| p.id == *bot_id).unwrap();
|
||||||
|
|
||||||
let mut game = Game::new();
|
let mut game = Game::new();
|
||||||
@ -180,10 +175,10 @@ impl Instance {
|
|||||||
.set_instance(self.id);
|
.set_instance(self.id);
|
||||||
|
|
||||||
// add the players
|
// add the players
|
||||||
let mut plr_team = Team::new(plr.account);
|
let mut plr_team = Team::new(plr.id);
|
||||||
plr_team.set_cryps(plr.cryps);
|
plr_team.set_cryps(plr.cryps);
|
||||||
|
|
||||||
let mut bot_team = Team::new(bot.account);
|
let mut bot_team = Team::new(bot.id);
|
||||||
bot_team.set_cryps(bot.cryps);
|
bot_team.set_cryps(bot.cryps);
|
||||||
bot_team.set_bot();
|
bot_team.set_bot();
|
||||||
|
|
||||||
@ -203,18 +198,20 @@ impl Instance {
|
|||||||
fn start(&mut self) -> &mut Instance {
|
fn start(&mut self) -> &mut Instance {
|
||||||
// self.players.sort_unstable_by_key(|p| p.id);
|
// self.players.sort_unstable_by_key(|p| p.id);
|
||||||
self.open = false;
|
self.open = false;
|
||||||
self.vbox_phase_start()
|
self.next_round()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vbox_phase_start(&mut self) -> &mut Instance {
|
fn next_round(&mut self) -> &mut Instance {
|
||||||
self.phase = InstancePhase::Vbox;
|
self.phase = InstancePhase::InProgress;
|
||||||
|
|
||||||
self.players.iter_mut().for_each(|p| {
|
self.players.iter_mut().for_each(|p| {
|
||||||
p.ready = false;
|
p.ready = false;
|
||||||
p.vbox.fill();
|
p.vbox.fill();
|
||||||
});
|
});
|
||||||
|
|
||||||
self.generate_rounds();
|
self.generate_rounds();
|
||||||
self.bot_vbox_phase();
|
self.bot_vbox_phase();
|
||||||
|
self.bot_games_phase();
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -223,21 +220,6 @@ impl Instance {
|
|||||||
self.players.iter().all(|p| p.ready)
|
self.players.iter().all(|p| p.ready)
|
||||||
}
|
}
|
||||||
|
|
||||||
// requires no input
|
|
||||||
// just do it
|
|
||||||
fn games_phase_start(&mut self) -> &mut Instance {
|
|
||||||
if self.phase != InstancePhase::Vbox {
|
|
||||||
panic!("instance not in vbox phase");
|
|
||||||
}
|
|
||||||
assert!(self.all_ready());
|
|
||||||
|
|
||||||
self.phase = InstancePhase::Games;
|
|
||||||
|
|
||||||
self.bot_games_phase();
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn game_finished(&mut self, game: &Game) -> Result<&mut Instance, Error> {
|
fn game_finished(&mut self, game: &Game) -> Result<&mut Instance, Error> {
|
||||||
let round_num = self.rounds.len() - 1;
|
let round_num = self.rounds.len() - 1;
|
||||||
self.rounds[round_num]
|
self.rounds[round_num]
|
||||||
@ -249,7 +231,7 @@ impl Instance {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn games_phase_finished(&self) -> bool {
|
fn all_games_finished(&self) -> bool {
|
||||||
match self.rounds.last() {
|
match self.rounds.last() {
|
||||||
Some(r) => r.iter().all(|g| g.finished),
|
Some(r) => r.iter().all(|g| g.finished),
|
||||||
None => true,
|
None => true,
|
||||||
@ -267,8 +249,8 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn bot_games_phase(&mut self) -> &mut Instance {
|
fn bot_games_phase(&mut self) -> &mut Instance {
|
||||||
if self.phase != InstancePhase::Games {
|
if self.phase != InstancePhase::InProgress {
|
||||||
panic!("instance not in games phase");
|
panic!("instance not in progress phase");
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = self.rounds.len() - 1;
|
let r = self.rounds.len() - 1;
|
||||||
@ -277,7 +259,7 @@ impl Instance {
|
|||||||
for mut round in self.rounds[r].iter_mut() {
|
for mut round in self.rounds[r].iter_mut() {
|
||||||
if self.players
|
if self.players
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| round.player_ids.contains(&p.id) && p.bot)
|
.filter(|p| round.player_ids.contains(&p.id) && p.bot && p.ready)
|
||||||
.count() == 2 {
|
.count() == 2 {
|
||||||
// println!("should play a game between {:?}", round.player_ids);
|
// println!("should play a game between {:?}", round.player_ids);
|
||||||
let a = self.players.clone().into_iter().find(|p| p.id == round.player_ids[0]).unwrap();
|
let a = self.players.clone().into_iter().find(|p| p.id == round.player_ids[0]).unwrap();
|
||||||
@ -291,11 +273,11 @@ impl Instance {
|
|||||||
.set_team_size(3);
|
.set_team_size(3);
|
||||||
|
|
||||||
// add the players
|
// add the players
|
||||||
let mut a_team = Team::new(a.account);
|
let mut a_team = Team::new(a.id);
|
||||||
a_team.set_cryps(a.cryps);
|
a_team.set_cryps(a.cryps);
|
||||||
a_team.set_bot();
|
a_team.set_bot();
|
||||||
|
|
||||||
let mut b_team = Team::new(b.account);
|
let mut b_team = Team::new(b.id);
|
||||||
b_team.set_cryps(b.cryps);
|
b_team.set_cryps(b.cryps);
|
||||||
b_team.set_bot();
|
b_team.set_bot();
|
||||||
|
|
||||||
@ -314,7 +296,7 @@ impl Instance {
|
|||||||
round.finished = true;
|
round.finished = true;
|
||||||
|
|
||||||
for team in game.teams.iter() {
|
for team in game.teams.iter() {
|
||||||
let mut player = self.players.iter_mut().find(|p| p.account == team.id).unwrap();
|
let mut player = self.players.iter_mut().find(|p| p.id == team.id).unwrap();
|
||||||
match team.id == winner.id {
|
match team.id == winner.id {
|
||||||
true => player.add_win(),
|
true => player.add_win(),
|
||||||
false => player.add_loss(),
|
false => player.add_loss(),
|
||||||
@ -358,17 +340,35 @@ impl Instance {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_round(&self, player: &Player) -> &Round {
|
fn current_round(&self, player_id: Uuid) -> &Round {
|
||||||
let round_num = self.rounds.len() - 1;
|
let round_num = self.rounds.len() - 1;
|
||||||
|
|
||||||
let current_round = self.rounds[round_num]
|
let current_round = self.rounds[round_num]
|
||||||
.iter()
|
.iter()
|
||||||
.find(|g| g.player_ids.contains(&player.id))
|
.find(|g| g.player_ids.contains(&player_id))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
current_round
|
current_round
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn current_game(&mut self, player_id: Uuid) -> Option<Uuid> {
|
||||||
|
if self.phase == InstancePhase::Lobby {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_round = self.current_round(player_id);
|
||||||
|
|
||||||
|
let can_start = self.players
|
||||||
|
.iter()
|
||||||
|
.filter(|p| current_round.player_ids.contains(&p.id))
|
||||||
|
.all(|p| p.ready);
|
||||||
|
|
||||||
|
match can_start {
|
||||||
|
true => Some(current_round.game_id),
|
||||||
|
false => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn scores(&self) -> Vec<(String, Score)> {
|
fn scores(&self) -> Vec<(String, Score)> {
|
||||||
let mut scores = self.players.iter()
|
let mut scores = self.players.iter()
|
||||||
.map(|p| (p.name.clone(), p.score))
|
.map(|p| (p.name.clone(), p.score))
|
||||||
@ -383,7 +383,7 @@ impl Instance {
|
|||||||
fn account_player(&mut self, account: Uuid) -> Result<&mut Player, Error> {
|
fn account_player(&mut self, account: Uuid) -> Result<&mut Player, Error> {
|
||||||
self.players
|
self.players
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|p| p.account == account)
|
.find(|p| p.id == account)
|
||||||
.ok_or(err_msg("account not in instance"))
|
.ok_or(err_msg("account not in instance"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +522,7 @@ pub fn instance_get_open(tx: &mut Transaction) -> Result<Instance, Error> {
|
|||||||
return Ok(instance);
|
return Ok(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn instance_lobby(params: InstanceLobbyParams, tx: &mut Transaction, account: &Account) -> Result<Instance, Error> {
|
pub fn instance_new(params: InstanceLobbyParams, tx: &mut Transaction, account: &Account) -> Result<Instance, Error> {
|
||||||
let mut instance = Instance::new()
|
let mut instance = Instance::new()
|
||||||
.set_max_players(params.players)?
|
.set_max_players(params.players)?
|
||||||
.set_name(params.name)?;
|
.set_name(params.name)?;
|
||||||
@ -545,8 +545,9 @@ pub fn instance_join(params: InstanceJoinParams, tx: &mut Transaction, account:
|
|||||||
return Err(format_err!("incorrect team size. ({:})", 3));
|
return Err(format_err!("incorrect team size. ({:})", 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
let player = Player::new(account.id, instance.id, &account.name, cryps);
|
let player = player_create(tx, Player::new(account.id, instance.id, &account.name, cryps), account)?;
|
||||||
instance.add_player(player);
|
|
||||||
|
instance.add_player(player)?;
|
||||||
|
|
||||||
instance_update(tx, instance)
|
instance_update(tx, instance)
|
||||||
}
|
}
|
||||||
@ -560,11 +561,11 @@ pub fn instance_ready_global(tx: &mut Transaction, _account: &Account, player: P
|
|||||||
match game_instance_join(tx, player.clone(), g.id) {
|
match game_instance_join(tx, player.clone(), g.id) {
|
||||||
Ok(g) => g,
|
Ok(g) => g,
|
||||||
// if fails make a new one
|
// if fails make a new one
|
||||||
Err(_e) => game_instance_new(tx, player, Uuid::new_v4())?,
|
Err(_e) => game_instance_new(tx, vec![player], Uuid::new_v4(), Uuid::nil())?,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// if not found make a new one
|
// if not found make a new one
|
||||||
Err(_) => game_instance_new(tx, player, Uuid::new_v4())?,
|
Err(_) => game_instance_new(tx, vec![player], Uuid::new_v4(), Uuid::nil())?,
|
||||||
};
|
};
|
||||||
|
|
||||||
// set the current game
|
// set the current game
|
||||||
@ -582,11 +583,48 @@ pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account
|
|||||||
let player_id = instance.account_player(account.id)?.id;
|
let player_id = instance.account_player(account.id)?.id;
|
||||||
instance.player_ready(player_id)?;
|
instance.player_ready(player_id)?;
|
||||||
|
|
||||||
|
if let Some(game_id) = instance.current_game(player_id) {
|
||||||
|
match instance.player_has_pve_game(player_id) {
|
||||||
|
true => match game_get(tx, game_id) {
|
||||||
|
Ok(g) => g,
|
||||||
|
Err(_) => {
|
||||||
|
let game = instance.bot_vs_player_game(player_id)?;
|
||||||
|
game_write(&game, tx)?;
|
||||||
|
game
|
||||||
|
},
|
||||||
|
},
|
||||||
|
false => {
|
||||||
|
let opponent_id = *instance
|
||||||
|
.current_round(account.id)
|
||||||
|
.player_ids
|
||||||
|
.iter()
|
||||||
|
.find(|p| **p != account.id)
|
||||||
|
.expect("could not find opponent");
|
||||||
|
|
||||||
|
let a = instance.account_player(account.id)?.clone();
|
||||||
|
let b = instance.account_player(opponent_id)?.clone();
|
||||||
|
let teams = vec![a, b];
|
||||||
|
game_instance_new(tx, teams, game_id, instance.id)?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
instance_update(tx, instance)
|
instance_update(tx, instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn instance_state(params: InstanceStateParams, tx: &mut Transaction, account: &Account) -> Result<Instance, Error> {
|
pub fn instance_state(params: InstanceStateParams, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
|
||||||
instance_get(tx, params.instance_id)
|
let mut instance = instance_get(tx, params.instance_id)?;
|
||||||
|
|
||||||
|
if let Some(game_id) = instance.current_game(account.id) {
|
||||||
|
let game = game_get(tx, game_id)?;
|
||||||
|
|
||||||
|
if game.phase != Phase::Finish {
|
||||||
|
|
||||||
|
return Ok(RpcResult::GameState(game))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(RpcResult::InstanceState(instance))
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
|
// pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
|
||||||
@ -602,10 +640,10 @@ pub fn instance_state(params: InstanceStateParams, tx: &mut Transaction, account
|
|||||||
// // send game state
|
// // send game state
|
||||||
// match instance.player_ready(player.id) {
|
// match instance.player_ready(player.id) {
|
||||||
// Ok(_) => (),
|
// Ok(_) => (),
|
||||||
// Err(_) => return game_get(tx, instance.current_round(&player).game_id),
|
// Err(_) => return game_get(tx, instance.current_round(player.id).game_id),
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// let game_id = instance.current_round(&player).game_id;
|
// let game_id = instance.current_round(player.id).game_id;
|
||||||
|
|
||||||
// let game = match instance.player_has_pve_game(&player) {
|
// let game = match instance.player_has_pve_game(&player) {
|
||||||
// true => match game_get(tx, game_id) {
|
// true => match game_get(tx, game_id) {
|
||||||
@ -678,8 +716,8 @@ pub fn instance_state(params: InstanceStateParams, tx: &mut Transaction, account
|
|||||||
|
|
||||||
// // now modify the players and write them all
|
// // now modify the players and write them all
|
||||||
// // each player update will also update the instance in db
|
// // each player update will also update the instance in db
|
||||||
// if instance.games_phase_finished() {
|
// if instance.all_games_finished() {
|
||||||
// instance.vbox_phase_start();
|
// instance.next_round();
|
||||||
// let instance = instance_update(tx, instance)?;
|
// let instance = instance_update(tx, instance)?;
|
||||||
|
|
||||||
// for player in instance.players
|
// for player in instance.players
|
||||||
@ -711,22 +749,22 @@ mod tests {
|
|||||||
let player = Player::new(player_account, instance.id, &"test".to_string(), cryps).set_bot(true);
|
let player = Player::new(player_account, instance.id, &"test".to_string(), cryps).set_bot(true);
|
||||||
let player_id = player.id;
|
let player_id = player.id;
|
||||||
|
|
||||||
instance.add_player(player);
|
instance.add_player(player).expect("could not add player");
|
||||||
|
|
||||||
assert_eq!(instance.phase, InstancePhase::Open);
|
assert_eq!(instance.phase, InstancePhase::Lobby);
|
||||||
instance.player_ready(player_id).unwrap();
|
instance.player_ready(player_id).unwrap();
|
||||||
|
|
||||||
assert_eq!(instance.phase, InstancePhase::Vbox);
|
assert_eq!(instance.phase, InstancePhase::InProgress);
|
||||||
assert_eq!(instance.rounds[0].len(), 8);
|
assert_eq!(instance.rounds[0].len(), 8);
|
||||||
|
|
||||||
instance.player_ready(player_id).unwrap();
|
instance.player_ready(player_id).unwrap();
|
||||||
|
|
||||||
assert!(instance.games_phase_finished());
|
assert!(instance.all_games_finished());
|
||||||
instance.vbox_phase_start();
|
instance.next_round();
|
||||||
|
|
||||||
instance.player_ready(player_id).unwrap();
|
instance.player_ready(player_id).unwrap();
|
||||||
|
|
||||||
instance.vbox_phase_start();
|
instance.next_round();
|
||||||
|
|
||||||
instance.player_ready(player_id).unwrap();
|
instance.player_ready(player_id).unwrap();
|
||||||
|
|
||||||
@ -754,7 +792,7 @@ mod tests {
|
|||||||
let player = Player::new(player_account, instance.id, &"a".to_string(), cryps);
|
let player = Player::new(player_account, instance.id, &"a".to_string(), cryps);
|
||||||
let a_id = player.id;
|
let a_id = player.id;
|
||||||
|
|
||||||
instance.add_player(player.clone());
|
instance.add_player(player).expect("could not add player");
|
||||||
assert!(!instance.can_start());
|
assert!(!instance.can_start());
|
||||||
|
|
||||||
let player_account = Uuid::new_v4();
|
let player_account = Uuid::new_v4();
|
||||||
@ -762,14 +800,14 @@ mod tests {
|
|||||||
let player = Player::new(player_account, instance.id, &"b".to_string(), cryps);
|
let player = Player::new(player_account, instance.id, &"b".to_string(), cryps);
|
||||||
let b_id = player.id;
|
let b_id = player.id;
|
||||||
|
|
||||||
instance.add_player(player);
|
instance.add_player(player).expect("could not add player");
|
||||||
|
|
||||||
assert_eq!(instance.phase, InstancePhase::Open);
|
assert_eq!(instance.phase, InstancePhase::Lobby);
|
||||||
instance.player_ready(a_id).expect("a ready");
|
instance.player_ready(a_id).expect("a ready");
|
||||||
assert!(!instance.can_start());
|
assert!(!instance.can_start());
|
||||||
|
|
||||||
instance.player_ready(b_id).expect("b ready");
|
instance.player_ready(b_id).expect("b ready");
|
||||||
assert_eq!(instance.phase, InstancePhase::Vbox);
|
assert_eq!(instance.phase, InstancePhase::InProgress);
|
||||||
|
|
||||||
assert!(!instance.can_start());
|
assert!(!instance.can_start());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,6 @@ pub struct Score {
|
|||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub instance: Uuid,
|
pub instance: Uuid,
|
||||||
pub account: Uuid,
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub vbox: Vbox,
|
pub vbox: Vbox,
|
||||||
pub score: Score,
|
pub score: Score,
|
||||||
@ -38,8 +37,7 @@ pub struct Player {
|
|||||||
impl Player {
|
impl Player {
|
||||||
pub fn new(account: Uuid, instance: Uuid, name: &String, cryps: Vec<Cryp>) -> Player {
|
pub fn new(account: Uuid, instance: Uuid, name: &String, cryps: Vec<Cryp>) -> Player {
|
||||||
Player {
|
Player {
|
||||||
id: Uuid::new_v4(),
|
id: account,
|
||||||
account,
|
|
||||||
instance,
|
instance,
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
vbox: Vbox::new(account, instance),
|
vbox: Vbox::new(account, instance),
|
||||||
@ -296,7 +294,7 @@ pub fn player_create(tx: &mut Transaction, player: Player, account: &Account) ->
|
|||||||
";
|
";
|
||||||
|
|
||||||
let result = tx
|
let result = tx
|
||||||
.query(query, &[&player.id, &player.instance, &account.id, &player_bytes])?;
|
.query(query, &[&Uuid::new_v4(), &player.instance, &account.id, &player_bytes])?;
|
||||||
|
|
||||||
let _returned = result.iter().next().expect("no row written");
|
let _returned = result.iter().next().expect("no row written");
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ use skill::{Skill};
|
|||||||
// use zone::{Zone, zone_create, zone_join, zone_close};
|
// use zone::{Zone, zone_create, zone_join, zone_close};
|
||||||
use spec::{Spec};
|
use spec::{Spec};
|
||||||
use player::{Score, player_mm_cryps_set, Player};
|
use player::{Score, player_mm_cryps_set, Player};
|
||||||
use instance::{Instance, instance_state, instance_lobby, instance_ready, instance_join, instance_scores};
|
use instance::{Instance, instance_state, instance_new, instance_ready, instance_join, instance_scores};
|
||||||
use vbox::{Var, vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
|
use vbox::{Var, vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
|
||||||
|
|
||||||
pub struct Rpc;
|
pub struct Rpc;
|
||||||
@ -74,7 +74,7 @@ impl Rpc {
|
|||||||
|
|
||||||
"instance_join" => Rpc::instance_join(data, &mut tx, account.unwrap(), client),
|
"instance_join" => Rpc::instance_join(data, &mut tx, account.unwrap(), client),
|
||||||
"instance_ready" => Rpc::instance_ready(data, &mut tx, account.unwrap(), client),
|
"instance_ready" => Rpc::instance_ready(data, &mut tx, account.unwrap(), client),
|
||||||
"instance_lobby" => Rpc::instance_lobby(data, &mut tx, account.unwrap(), client),
|
"instance_new" => Rpc::instance_new(data, &mut tx, account.unwrap(), client),
|
||||||
"instance_scores" => Rpc::instance_scores(data, &mut tx, account.unwrap(), client),
|
"instance_scores" => Rpc::instance_scores(data, &mut tx, account.unwrap(), client),
|
||||||
"instance_state" => Rpc::instance_state(data, &mut tx, account.unwrap(), client),
|
"instance_state" => Rpc::instance_state(data, &mut tx, account.unwrap(), client),
|
||||||
|
|
||||||
@ -217,12 +217,12 @@ impl Rpc {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instance_lobby(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
fn instance_new(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||||
let msg = from_slice::<InstanceLobbyMsg>(&data).or(Err(err_msg("invalid params")))?;
|
let msg = from_slice::<InstanceLobbyMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||||
|
|
||||||
let response = RpcResponse {
|
let response = RpcResponse {
|
||||||
method: "instance_state".to_string(),
|
method: "instance_state".to_string(),
|
||||||
params: RpcResult::InstanceState(instance_lobby(msg.params, tx, &account)?)
|
params: RpcResult::InstanceState(instance_new(msg.params, tx, &account)?)
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
@ -274,13 +274,17 @@ impl Rpc {
|
|||||||
|
|
||||||
fn instance_state(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
fn instance_state(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||||
let msg = from_slice::<InstanceStateMsg>(&data).or(Err(err_msg("invalid params")))?;
|
let msg = from_slice::<InstanceStateMsg>(&data).or(Err(err_msg("invalid params")))?;
|
||||||
|
match instance_state(msg.params, tx, &account)? {
|
||||||
let response = RpcResponse {
|
RpcResult::GameState(p) => Ok(RpcResponse {
|
||||||
method: "instance_state".to_string(),
|
method: "game_state".to_string(),
|
||||||
params: RpcResult::InstanceState(instance_state(msg.params, tx, &account)?)
|
params: RpcResult::GameState(p),
|
||||||
};
|
}),
|
||||||
|
RpcResult::InstanceState(p) => Ok(RpcResponse {
|
||||||
return Ok(response);
|
method: "instance_state".to_string(),
|
||||||
|
params: RpcResult::InstanceState(p),
|
||||||
|
}),
|
||||||
|
_ => Err(err_msg("unhandled instance state"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn player_mm_cryps_set(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
fn player_mm_cryps_set(data: Vec<u8>, tx: &mut Transaction, account: Account, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user