nginx change

This commit is contained in:
ntr
2019-04-02 18:19:33 +11:00
parent 4c16afa786
commit 23c7ae7aab
99 changed files with 538 additions and 538 deletions
+45
View File
@@ -0,0 +1,45 @@
// eslint-disable-next-line
const preact = require('preact');
const { connect } = require('preact-redux');
const InstanceListContainer = require('./instance.list.container');
const CrypListContainer = require('./cryp.list.container');
const GameContainer = require('./game.container');
const InstanceContainer = require('./instance.container');
const addState = connect(
(state) => {
const { game, instance, ws } = state;
if (!game) {
console.log('clear gs interval');
// ws.clearGameStateInterval();
}
return { game, instance };
}
);
function renderBody(props) {
const { game, instance } = props;
if (game) {
return (
<GameContainer />
);
}
if (instance) {
return (
<InstanceContainer />
);
}
return (
<main>
<CrypListContainer />
<InstanceListContainer />
</main>
);
}
module.exports = addState(renderBody);
+218
View File
@@ -0,0 +1,218 @@
module.exports = {
ITEMS: {
SKILLS: {
Amplify: {
description: 'increase the magic damage dealt by a cryp',
colours: '1 Green 1 Blue',
},
Attack: {
description: 'a fast attack with red damage',
upgrades: 'combine with 2 red / blue / green - red + blue attack not implemented',
},
Banish: {
description: 'target cryp is prevented from casting any skills and taking any damage',
colours: '1 Red 1 Green',
},
Blast: {
description: 'blast the target with magic damage',
colours: '2 Blue',
},
Block: {
description: 'decreases incoming red damage for 1T',
upgrades: 'combine with 2 red / blue / green',
},
Buff: {
description: 'increase target cryp speed',
upgrades: 'combine with 2 red / blue / green',
},
Clutch: {
description: '??????',
colours: '1 Red 1 Green',
},
Corrupt: {
description: 'Inflicts a dot to attacker while active',
colours: '2 Blue',
},
Curse: {
description: 'target cryp takes increased magic damage',
colours: '2 Blue',
},
Debuff: {
description: 'reduce target cryp speed',
upgrades: 'combine with 2 red / blue / green',
},
Decay: {
description: 'afflict a cryp with a blue damage based damage over time debuff',
colours: '1 Green 1 Blue',
},
Empower: {
description: 'increase the red damage dealt by a cryp',
colours: '2 Red',
},
Haste: {
description: 'magical skill that increases speed of target cryp',
colours: '1 Red 1 Blue',
},
Heal: {
description: 'heal a cryp with blue damage',
colours: '2 Green',
},
Hex: {
description: 'magical bsed skill that prevents target cryp from using any skills',
colours: '1 Red 1 Blue',
},
Hostility: {
description: 'magical bsed skill that prevents target cryp from using any skills',
colours: '2 Blue',
},
Invert: {
description: 'reverse ???',
colours: '1 Red 1 Blue',
},
Parry: {
description: 'prevents all red damage for 1T',
colours: '2 Red',
},
Purge: {
description: 'remove magical buffs from target cryp',
colours: '2 Green',
},
Purify: {
description: 'remove magical debuffs from target cryp',
colours: '1 Red 1 Green',
},
Recharge: {
description: 'restore something',
colours: '1 Red 1 Blue',
},
Reflect: {
description: 'reflect damage back to attacker',
colours: '2 Green',
},
Riposte: {
description: '???',
},
Ruin: {
description: 'Stun the entire enemy team',
colours: '2 Blue',
},
Shield: {
description: 'grants immunity to magical skills to target cryp',
colours: '1 Green 1 Blue',
},
Silence: {
description: 'prevent target cryp from casting magical skills',
colours: '1 Green 1 Blue',
},
Siphon: {
description: 'siphon hp from target cryp with a blue damage based debuff',
colours: '1 Green 1 Blue',
},
Slay: {
description: '????',
},
Slow: {
description: 'magical skill that reduces speed of target cryp',
colours: '1 Red 1 Green',
},
Snare: {
description: 'prevents red skills from being used for 2T',
colours: '2 Red',
},
Strangle: {
description: 'Stun the enemy and inflict physical damage over 3T',
colours: '2 Red',
},
Strike: {
description: 'Fast attacking red skill',
colours: '2 Red',
},
Stun: {
description: 'red skill hat prevents target cryp from using any skills',
upgrades: 'combine with 2 red / blue / green',
},
Taunt: {
description: 'Enemy skills will prioritise cryps with this skill active',
colours: '1 Red 1 Green',
},
Throw: {
description: 'stuns and makes the target take increased red damage',
colours: '2 Green',
},
Triage: {
description: 'grants a blue damage based healing over time buff',
colours: '2 Green',
},
},
SPECS: {
Damage: {
description: 'Increase red / green / blue power stats cryp',
upgrades: 'combine with 2 red / blue / green',
},
Hp: {
description: 'Increases health of cryp',
upgrades: 'combine with 2 red / blue / green',
},
Speed: {
description: 'Increases speed of cryp',
upgrades: 'combine with 2 red / blue / green',
},
},
COLOURS: {
Red: {
description: 'Used to create offensive type combos - fast and chaotic',
},
Green: {
description: 'Used to create defensive / healing type combos',
},
Blue: {
description: 'Used to create offensive type combos - slow and reliable',
},
},
},
};
@@ -0,0 +1,64 @@
const preact = require('preact');
const { stringSort } = require('./../utils');
const molecule = require('./molecule');
const idSort = stringSort('id');
const COLOURS = [
'#a52a2a',
'#1FF01F',
'#3498db',
];
function CrypList({ cryps, selectedCryps, setSelectedCryps }) {
if (!cryps) return <div>not ready</div>;
// redux limitation + suggested workaround
// so much for dumb components
function selectCryp(id) {
// remove
const i = selectedCryps.findIndex(sid => sid === id);
if (i > -1) {
selectedCryps[i] = null;
return setSelectedCryps(selectedCryps);
}
// window insert
const insert = selectedCryps.findIndex(j => j === null);
if (insert === -1) return setSelectedCryps([id, null, null]);
selectedCryps[insert] = id;
return setSelectedCryps(selectedCryps);
}
const crypPanels = cryps.sort(idSort).map(cryp => {
const colour = selectedCryps.indexOf(cryp.id);
const selected = colour > -1;
const borderColour = selected ? COLOURS[colour] : '#000000';
return (
<div
key={cryp.id}
className="menu-cryp-ctr">
<div
className="menu-cryp"
style={ { 'border-color': borderColour || 'whitesmoke' } }
onClick={() => selectCryp(cryp.id)} >
<figure className="img">
{molecule}
</figure>
<h2>{cryp.name}</h2>
</div>
</div>
);
});
return (
<div className="menu-cryps">
{crypPanels}
</div>
);
}
module.exports = CrypList;
@@ -0,0 +1,20 @@
const { connect } = require('preact-redux');
const CrypList = require('./cryp.list.component');
const actions = require('./../actions');
const addState = connect(
function receiveState(state) {
const { ws, cryps, selectedCryps } = state;
return { cryps, selectedCryps };
},
function receiveDispatch(dispatch) {
function setSelectedCryps(crypIds) {
dispatch(actions.setSelectedCryps(crypIds));
}
return { setSelectedCryps };
}
);
module.exports = addState(CrypList);
@@ -0,0 +1,32 @@
const preact = require('preact');
function renderSpawnButton({ account, sendCrypSpawn }) {
let name = '';
if (!account) return <div>...</div>;
return false;
return (
<div className="row">
<div className="two columns">
<input
className="input"
type="text"
placeholder="cryp name"
onChange={e => (name = e.target.value)}
/>
</div>
<div className="two columns">
<button
className="button"
type="submit"
onClick={() => sendCrypSpawn(name)}>
Spawn 👾
</button>
</div>
</div>
);
}
module.exports = renderSpawnButton;
@@ -0,0 +1,16 @@
const { connect } = require('preact-redux');
const CrypSpawnButton = require('./cryp.spawn.button');
const addState = connect(
function receiveState(state) {
const { ws } = state;
function sendCrypSpawn(name) {
return ws.sendCrypSpawn(name);
}
return { account: state.account, sendCrypSpawn };
}
);
module.exports = addState(CrypSpawnButton);
+202
View File
@@ -0,0 +1,202 @@
const preact = require('preact');
const range = require('lodash/range');
const molecule = require('./molecule');
const saw = require('./saw.component');
// const SKILL_HOT_KEYS = ['Q', 'W', 'E', 'R'];
function GamePanel(props) {
const {
game,
activeSkill,
setActiveSkill,
selectSkillTarget,
account,
quit,
} = props;
if (!game) return <div>...</div>;
function findCryp(id) {
const team = game.teams.find(t => t.cryps.find(c => c.id === id));
if (team) return team.cryps.find(c => c.id === id);
return null;
}
const otherTeams = game.teams.filter(t => t.id !== account.id);
const playerTeam = game.teams.find(t => t.id === account.id);
function stackElement(c, i) {
let skills = game.stack.filter(s => s.source_cryp_id === c.id).map((s, j) => {
const target = findCryp(s.target_cryp_id);
return (
<div key={j}>{s.skill} -> {target.name}</div>
);
});
if (!skills.length) skills = (<div>&nbsp;</div>);
return (
<div
key={i}
className="stack-line">
{skills}
</div>
);
}
function Cryp(cryp) {
const ko = cryp.hp.value === 0 ? 'ko' : '';
const skills = range(0, 4).map(i => {
const s = cryp.skills[i];
if (!s) {
return (
<button
disabled='true'
key={i}
className='cryp-skill-btn disabled'>
<span>&nbsp;</span>
</button>
);
}
const cdText = cryp.skills[i].cd > 0
? `- ${s.cd}`
: '';
const highlight = activeSkill
? activeSkill.crypId === cryp.id && activeSkill.skill === s
: false;
return (
<button
key={i}
disabled={!!cdText || ko}
className={`cryp-skill-btn right ${highlight ? 'active' : ''}`}
type="submit"
onClick={() => setActiveSkill(cryp.id, s.skill)}>
{s.skill} {cdText}
</button>
);
});
const stats = [
{ stat: 'hp', colour: '#1FF01F' },
{ stat: 'red_shield', colour: '#a52a2a' },
{ stat: 'blue_shield', colour: '#3498db' },
].map((s, i) => (
<figure key={i} alt={s.stat}>
{saw(s.colour)}
<figcaption>{cryp[s.stat].value} / {cryp[s.stat].max}</figcaption>
</figure>
));
return (
<div
key={cryp.id}
style={ activeSkill ? { cursor: 'pointer' } : {}}
className={`cryp-box ${ko}`} >
<div className="cryp-box-top">
<figure
className="img"
onClick={() => selectSkillTarget(cryp.id)} >
{molecule}
<figcaption>{cryp.name}</figcaption>
</figure>
<div className="skills">
{skills}
</div>
</div>
<div className="stats">
{stats}
</div>
</div>
);
}
function PlayerTeam(team) {
const cryps = team.cryps.map(c => Cryp(c));
return (
<div className="team-player cryp-list">
{cryps}
</div>
);
}
function OpponentCryp(cryp, i) {
const stats = [
{ stat: 'hp', colour: '#1FF01F' },
{ stat: 'red_shield', colour: '#a52a2a' },
{ stat: 'blue_shield', colour: '#3498db' },
].map((s, j) => (
<figure key={j} alt={s.stat}>
{saw(s.colour)}
<figcaption>{cryp[s.stat].value} / {cryp[s.stat].max}</figcaption>
</figure>
));
return (
<div
key={i}
className="cryp-box"
style={ activeSkill ? { cursor: 'pointer' } : {}}
onClick={() => selectSkillTarget(cryp.id)} >
<div className="cryp-box-top">
<figure className="img">
{molecule}
<figcaption>{cryp.name}</figcaption>
</figure>
</div>
<div className="stats">
{stats}
</div>
</div>
);
}
function OpponentTeam(team) {
const cryps = team.cryps.map(OpponentCryp);
return (
<div className="cryp-list" >
{cryps}
</div>
);
}
const selectedSkills = playerTeam.cryps.map((c, i) => stackElement(c, i));
const logs = game.log.map((l, i) => (<div key={i}>{l}</div>)).reverse();
return (
<main>
<div className="instance-hdr">
<button
className="game-back-btn instance-btn instance-ui-btn left"
onClick={quit}>
Back
</button>
<div className="spacer">
<div>&nbsp;</div>
</div>
</div>
{PlayerTeam(playerTeam, setActiveSkill)}
<div className="selected-skills">
{selectedSkills}
</div>
<div className="team-opponent">
{otherTeams.map(OpponentTeam)}
</div>
<div className="logs">
{logs}
</div>
</main>
);
}
module.exports = GamePanel;
+57
View File
@@ -0,0 +1,57 @@
import 'particles.js/particles';
const { connect } = require('preact-redux');
const actions = require('../actions');
const Game = require('./game.component');
const config = require('./particles.config');
const particlesJS = window.particlesJS;
const addState = connect(
function receiveState(state) {
const { ws, game, account, activeSkill, activeIncoming } = state;
function selectSkillTarget(targetCrypId) {
if (activeSkill) {
return ws.sendGameSkill(game.id, activeSkill.crypId, targetCrypId, activeSkill.skill);
}
return false;
}
// intercept self casting skills
if (activeSkill && activeSkill.skill.self_targeting) {
ws.sendGameSkill(game.id, activeSkill.crypId, null, activeSkill.skill.skill);
}
function selectIncomingTarget(crypId) {
if (activeIncoming) {
return ws.sendGameTarget(game.id, crypId, activeIncoming);
}
return false;
}
return { game, account, activeSkill, activeIncoming, selectSkillTarget, selectIncomingTarget };
},
function receiveDispatch(dispatch) {
function setActiveSkill(crypId, skill) {
dispatch(actions.setActiveSkill(crypId, skill));
// particlesJS(`particles-${crypId}`, config);
}
function setActiveIncoming(skillId) {
dispatch(actions.setActiveIncoming(skillId));
}
function quit() {
dispatch(actions.setGame(null));
}
return { setActiveSkill, setActiveIncoming, quit };
}
);
module.exports = addState(Game);
@@ -0,0 +1,17 @@
// eslint-disable-next-line
const preact = require('preact');
const LoginContainer = require('./login.container');
function renderHeader() {
return (
<header>
<h1 className="header-title">
cryps.gg
</h1>
<LoginContainer />
</header>
);
}
module.exports = renderHeader;
+29
View File
@@ -0,0 +1,29 @@
const preact = require('preact');
const { ITEMS: { SKILLS, SPECS, COLOURS } } = require('./constants');
function Info(args) {
const {
info,
} = args;
let desc = null;
if (info) {
if (info.type === 'item') {
if (SKILLS[info.info]) {
desc = SKILLS[info.info];
} else if (SPECS[info.info]) {
desc = SPECS[info.info];
} else if (COLOURS[info.info]) {
desc = COLOURS[info.info];
}
}
}
return (
<div className="instance-info">
<div> {JSON.stringify(info)} </div>
<div> {JSON.stringify(desc)} </div>
</div>
);
}
module.exports = Info;
+20
View File
@@ -0,0 +1,20 @@
const { connect } = require('preact-redux');
// const actions = require('../actions');
const Info = require('./info.component');
const addState = connect(
function receiveState(state) {
const { info } = state;
return { info };
}
/*
function receiveDispatch(dispatch) {
return { };
}
*/
);
module.exports = addState(Info);
@@ -0,0 +1,110 @@
const preact = require('preact');
// const key = require('keymaster');
const range = require('lodash/range');
const VboxContainer = require('./vbox.container');
const InfoContainer = require('./info.container');
const molecule = require('./molecule');
const saw = require('./saw.component');
function Cryp(cryp, sendVboxApply, setInfo) {
const skills = range(0, 4).map(i => {
const s = cryp.skills[i]
? cryp.skills[i].skill
: (<span>&nbsp;</span>);
return <button key={i} className="cryp-skill-btn right" onClick={() => setInfo('item', s)}>{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);
}
const stats = [
{ stat: 'hp', colour: '#1FF01F' },
{ stat: 'green_damage', colour: '#1FF01F' },
{ stat: 'red_shield', colour: '#a52a2a' },
{ stat: 'red_damage', colour: '#a52a2a' },
{ stat: 'blue_shield', colour: '#3498db' },
{ stat: 'blue_damage', colour: '#3498db' },
{ stat: 'speed', colour: '#FFD123' },
].map((s, i) => (
<figure key={i} alt={s.stat}>
{saw(s.colour)}
<figcaption>{cryp[s.stat].value}</figcaption>
</figure>
));
return (
<div
key={cryp.id}
className="cryp-box"
onDragOver={onDragOver}
onDrop={onDrop}
>
<div className="cryp-box-top">
<figure className="img">
{molecule}
<figcaption>{cryp.name}</figcaption>
</figure>
<div className="skills">
{skills}
</div>
</div>
<div className="stats">
{stats}
</div>
</div>
);
}
function InstanceComponent(args) {
const {
// account,
instance,
quit,
sendInstanceReady,
sendVboxApply,
setInfo,
} = args;
if (!instance) return <div>...</div>;
const cryps = instance.cryps.map(c => Cryp(c, sendVboxApply, setInfo));
return (
<main className="instance" >
<div className="instance-hdr">
<button
className="instance-btn instance-ui-btn menu-btn left"
onClick={quit}>
Menu
</button>
<div className="spacer">
<div>&nbsp;</div>
</div>
<button
className="instance-btn instance-ui-btn ready-btn"
onClick={() => sendInstanceReady()}>
Ready
</button>
</div>
<VboxContainer />
<div className="cryp-list">
{cryps}
</div>
<InfoContainer />
</main>
);
}
module.exports = InstanceComponent;
@@ -0,0 +1,36 @@
const { connect } = require('preact-redux');
const actions = require('../actions');
const Instance = require('./instance.component');
const addState = connect(
function receiveState(state) {
const { ws, instance, account, combiner } = state;
function sendInstanceReady() {
return ws.sendInstanceReady(instance.instance);
}
function sendVboxApply(crypId, i) {
return ws.sendVboxApply(instance.instance, crypId, i);
}
return { instance, account, sendInstanceReady, sendVboxApply };
},
function receiveDispatch(dispatch, { instance, combiner }) {
function quit() {
dispatch(actions.setInstance(null));
}
function setInfo(type, info) {
dispatch(actions.setInfo(type, info));
}
return { quit, setInfo };
}
);
module.exports = addState(Instance);
@@ -0,0 +1,43 @@
// eslint-disable-next-line
const preact = require('preact');
const { NULL_UUID } = require('./../utils');
function instanceList({ instances, setActiveInstance, sendInstanceJoin }) {
if (!instances) return <div>...</div>;
const instanceJoin = (
<button
className="menu-instance-btn full right"
onClick={() => sendInstanceJoin()}>
Join New Instance
</button>
);
const instancePanels = instances.map(instance => {
const globalInstance = instance.instance === NULL_UUID;
const name = globalInstance
? 'Global Matchmaking'
: `${instance.instance.substring(0, 5)}`;
return (
<button
className={`menu-instance-btn right ${globalInstance ? 'full' : ''}`}
key={instance.id}
onClick={() => setActiveInstance(instance)}>
{name}
</button>
);
});
// <h2>Instances</h2>
return (
<section className="menu-instance-list" >
{instanceJoin}
{instancePanels}
</section>
);
}
module.exports = instanceList;
@@ -0,0 +1,35 @@
const { connect } = require('preact-redux');
const actions = require('../actions');
const InstanceList = require('./instance.list.component');
const addState = connect(
function receiveState(state) {
const { ws, selectedCryps, instances } = state;
function sendCrypsSet() {
console.log('set crypos');
// return ws.sendGamePvp(crypIds);
}
function sendInstanceJoin() {
if (selectedCryps.length) {
return ws.sendInstanceJoin(selectedCryps);
}
return false;
}
return { instances, sendCrypsSet, sendInstanceJoin };
},
function receiveDispatch(dispatch) {
function setActiveInstance(instance) {
dispatch(actions.setInstance(instance));
}
return { setActiveInstance };
}
);
module.exports = addState(InstanceList);
+76
View File
@@ -0,0 +1,76 @@
// eslint-disable-next-line
const preact = require('preact');
const saw = require('./saw.component');
function renderLogin({ account, submitLogin, submitRegister }) {
if (account) return (
<div className="header-status">
<h3 className="header-username">{account.name}</h3>
{saw('whitesmoke')}
</div>
);
const details = {
name: '',
password: '',
};
return (
<div className="login" >
<div className="field">
<p className="control has-icons-left has-icons-right">
<input
className="input"
type="email"
placeholder="Email"
onChange={e => (details.name = e.target.value)}
/>
<span className="icon is-small is-left">
<i className="fas fa-user" />
</span>
<span className="icon is-small is-right">
<i className="fas fa-check" />
</span>
</p>
</div>
<div className="field">
<p className="control has-icons-left">
<input
className="input"
type="password"
placeholder="Password"
onChange={e => (details.password = e.target.value)}
/>
<span className="icon is-small is-left">
<i className="fas fa-lock" />
</span>
</p>
</div>
<div className="field">
<p className="control">
<button
className="button inverted"
type="submit"
onClick={() => submitLogin('ntr', 'grepgrepgrep')}>
Default
</button>
<button
className="button inverted"
type="submit"
onClick={() => submitLogin(details.name, details.password)}>
Login
</button>
<button
className="button inverted"
type="submit"
onClick={() => submitRegister(details.name, details.password)}>
Register
</button>
</p>
</div>
</div>
);
}
module.exports = renderLogin;
+18
View File
@@ -0,0 +1,18 @@
const { connect } = require('preact-redux');
const Login = require('./login.component');
const addState = connect(
(state) => {
const { ws } = state;
function submitLogin(name, password) {
return ws.sendAccountLogin(name, password);
}
function submitRegister(name, password) {
return ws.sendAccountRegister(name, password);
}
return { account: state.account, submitLogin, submitRegister };
},
);
module.exports = addState(Login);
File diff suppressed because one or more lines are too long
+41
View File
@@ -0,0 +1,41 @@
const config = {
particles: {
number: { value: 300, density: { enable: true, value_area: 800 } },
color: { value: '#ffffff' },
shape: {
type: 'circle',
stroke: { width: 0, color: '#000000' },
polygon: { nb_sides: 5 },
image: { src: 'img/github.svg', width: 100, height: 100 }
},
opacity: {
value: 0.5,
random: false,
anim: { enable: false, speed: 1, opacity_min: 0.1, sync: false },
},
size: {
value: 3,
random: true,
anim: { enable: false, speed: 40, size_min: 0.1, sync: false },
},
line_linked: {
enable: true,
distance: 150,
color: '#ffffff',
opacity: 0.4,
width: 1,
},
move: {
enable: true,
speed: 6,
direction: 'none',
random: false,
straight: false,
out_mode: 'out',
bounce: false,
attract: { enable: false, rotateX: 600, rotateY: 1200 },
},
},
};
module.exports = config;
+10
View File
@@ -0,0 +1,10 @@
const preact = require('preact');
module.exports = function saw(colour) {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" style={{ stroke: colour }}>
<path d="M0,50l50,-50v100l50,-50" className="ping-path"/>
<path d="M0,50l50,-50v100l50,-50" className="ping-path"/>
</svg>
);
}
+161
View File
@@ -0,0 +1,161 @@
const preact = require('preact');
const range = require('lodash/range');
function convertVar(v) {
return v || '';
// uncomment for double borders in vbox
// if (v) {
// return <div>{v}</div>;
// }
// return;
}
function Vbox(args) {
const {
instance,
combiner,
reclaiming,
sendVboxAccept,
sendVboxDiscard,
sendVboxReclaim,
sendVboxCombine,
setCombiner,
setReclaiming,
setInfo,
} = args;
const { vbox } = instance;
if (!instance.vbox) return false;
// lots of rubbish to make it flow nice
function boundClick(i) {
if (reclaiming) {
return sendVboxReclaim(i);
}
const insert = combiner.findIndex(j => j === null);
if (insert === -1) return setCombiner([i, null, null]);
combiner[insert] = i;
return setCombiner(combiner);
}
function combinerRmv(i) {
combiner[i] = null;
return setCombiner(combiner);
}
const free = [];
for (let i = 0 ; i < 6; i++) {
free.push([vbox.free[0][i], vbox.free[1][i], vbox.free[2][i]]);
}
const freeRows = free.map((row, i) => {
const cells = row.map((c, j) => (
<td
key={j}
onClick={() => {
if (c) {
sendVboxAccept(j, i);
setInfo('item', c);
}
}} >
{convertVar(c)}
</td>
));
return (
<tr key={i}>
{cells}
</tr>
);
});
const boundTds = range(0, 9).map(i => {
if (combiner.indexOf(i) > -1) {
return (
<td
key={i}>
&nbsp;
</td>
);
}
return (
<td
key={i}
draggable="true"
onDragStart={e => e.dataTransfer.setData('text', i)}
onClick={() => boundClick(i) }>
{convertVar(vbox.bound[i])}
</td>
);
});
const boundRows = [
<tr key={0} >
{boundTds[0]}
{boundTds[1]}
{boundTds[2]}
</tr>,
<tr key={1}>
{boundTds[3]}
{boundTds[4]}
{boundTds[5]}
</tr>,
<tr key={2}>
{boundTds[6]}
{boundTds[7]}
{boundTds[8]}
</tr>,
];
const combinerElement = (
<table className="vbox-table">
<tbody>
<tr>
<td onClick={() => combinerRmv(0)}>{convertVar(vbox.bound[combiner[0]])}</td>
<td onClick={() => combinerRmv(1)}>{convertVar(vbox.bound[combiner[1]])}</td>
<td onClick={() => combinerRmv(2)}>{convertVar(vbox.bound[combiner[2]])}</td>
</tr>
</tbody>
</table>
);
return (
<div className="vbox">
<div className="vbox-hdr">
<div>VBOX</div>
<div className="bits" >{vbox.bits}b</div>
</div>
<button
className="instance-btn instance-ui-btn vbox-btn"
onClick={() => sendVboxDiscard()}>
Reroll
</button>
<table className="vbox-table">
<tbody>
{freeRows}
</tbody>
</table>
<span>INVENTORY</span>
<button
className="instance-btn instance-ui-btn vbox-btn"
onClick={() => setReclaiming(!reclaiming)}>
reclaim
</button>
<table className="vbox-table">
<tbody>
{boundRows}
</tbody>
</table>
<span>I-COMBINATOR</span>
<button
className="instance-btn instance-ui-btn vbox-btn"
onClick={() => sendVboxCombine()}>
refine
</button>
{combinerElement}
</div>
);
}
module.exports = Vbox;
+57
View File
@@ -0,0 +1,57 @@
const { connect } = require('preact-redux');
const actions = require('../actions');
const Vbox = require('./vbox.component');
const addState = connect(
function receiveState(state) {
const { ws, instance, combiner, reclaiming } = state;
function sendVboxDiscard() {
return ws.sendVboxDiscard(instance.instance);
}
function sendVboxAccept(group, index) {
return ws.sendVboxAccept(instance.instance, group, index);
}
function sendVboxCombine() {
return ws.sendVboxCombine(instance.instance, combiner);
}
function sendVboxReclaim(i) {
return ws.sendVboxReclaim(instance.instance, i);
}
return {
instance,
combiner,
reclaiming,
sendVboxAccept,
sendVboxDiscard,
sendVboxReclaim,
sendVboxCombine,
};
},
function receiveDispatch(dispatch) {
function setCombiner(c) {
return dispatch(actions.setCombiner(c));
}
function setReclaiming(v) {
return dispatch(actions.setReclaiming(v));
}
function setInfo(type, info) {
return dispatch(actions.setInfo(type, info));
}
return { setCombiner, setReclaiming, setInfo };
}
);
module.exports = addState(Vbox);