Added Specs to cryp Instance box

This commit is contained in:
Mashy 2019-04-03 23:29:12 +10:00
commit 01e3384e98
16 changed files with 180 additions and 87 deletions

View File

@ -153,7 +153,7 @@ header {
} }
.header-username { .header-username {
letter-spacing: 0.25em; letter-spacing: 0.05em;
font-size: 2em; font-size: 2em;
display: inline; display: inline;
} }
@ -485,10 +485,7 @@ header {
} }
.logs { .logs {
padding-left: 2em; flex: 0 0 100%;
display: flex;
flex-flow: row wrap;
flex: 0 0 20%;
} }
.selected-skills { .selected-skills {

View File

@ -13,6 +13,9 @@ export const setInstance = value => ({ type: SET_INSTANCE, value });
export const SET_GAME = 'SET_GAME'; export const SET_GAME = 'SET_GAME';
export const setGame = value => ({ type: SET_GAME, value }); export const setGame = value => ({ type: SET_GAME, value });
export const SET_SHOW_LOG = 'SET_SHOW_LOG';
export const setShowLog = value => ({ type: SET_SHOW_LOG, value });
export const SET_COMBINER = 'SET_COMBINER'; export const SET_COMBINER = 'SET_COMBINER';
export const setCombiner = value => ({ type: SET_COMBINER, value: Array.from(value) }); export const setCombiner = value => ({ type: SET_COMBINER, value: Array.from(value) });
@ -26,7 +29,7 @@ export const SET_ACTIVE_SKILL = 'SET_ACTIVE_SKILL';
export const setActiveSkill = (crypId, skill) => ({ type: SET_ACTIVE_SKILL, value: crypId ? { crypId, skill } : null }); export const setActiveSkill = (crypId, skill) => ({ type: SET_ACTIVE_SKILL, value: crypId ? { crypId, skill } : null });
export const SET_INFO = 'SET_INFO'; export const SET_INFO = 'SET_INFO';
export const setInfo = (type, value) => ({ type: SET_INFO, value: type ? { type, value } : null }); export const setInfo = value => ({ type: SET_INFO, value });
export const SET_RECLAIMING = 'SET_RECLAIMING'; export const SET_RECLAIMING = 'SET_RECLAIMING';
export const setReclaiming = value => ({ type: SET_RECLAIMING, value }); export const setReclaiming = value => ({ type: SET_RECLAIMING, value });

View File

@ -1,9 +1,9 @@
const preact = require('preact'); const preact = require('preact');
const { Component } = require('preact');
const range = require('lodash/range'); const range = require('lodash/range');
const { stringSort } = require('./../utils'); const { stringSort } = require('./../utils');
const molecule = require('./molecule'); const molecule = require('./molecule');
const SpawnButton = require('./spawn.button');
const idSort = stringSort('id'); const idSort = stringSort('id');
@ -13,40 +13,6 @@ const COLOURS = [
'#3498db', '#3498db',
]; ];
class SpawnButton extends Component {
toggle(e) {
this.setState({ enabled: e });
}
render({ spawn }, { enabled }) {
let spawnName = null;
return (
<div
className="menu-cryp-ctr spawn-btn">
<div
className="menu-cryp"
onClick={() => this.toggle(!this.enabled)} >
<h2>+</h2>
<input
className="login-input"
type="text"
disabled={!enabled}
placeholder="name"
onChange={e => spawnName = e.target.value}
/>
<button
className="login-btn"
disabled={!enabled}
onClick={() => spawn(spawnName)}
type="submit">
spawn
</button>
</div>
</div>
);
}
}
function CrypList(args) { function CrypList(args) {
const { const {
cryps, cryps,
@ -79,6 +45,7 @@ function CrypList(args) {
const instanceJoin = ( const instanceJoin = (
<button <button
className={`menu-instance-btn full right ${instanceJoinHidden ? 'hidden' : ''}`} className={`menu-instance-btn full right ${instanceJoinHidden ? 'hidden' : ''}`}
disabled={instanceJoinHidden}
onClick={() => sendInstanceJoin()}> onClick={() => sendInstanceJoin()}>
Join New Instance Join New Instance
</button> </button>
@ -113,7 +80,7 @@ function CrypList(args) {
: 1; : 1;
const spawnButtons = range(spawnButtonsNum) const spawnButtons = range(spawnButtonsNum)
.map(() => <SpawnButton key={Date.now()} spawn={name => sendCrypSpawn(name)} />); .map(i => <SpawnButton key={i} i={i} spawn={name => sendCrypSpawn(name)} />);
return ( return (
<div className="menu-cryps"> <div className="menu-cryps">

View File

@ -16,11 +16,43 @@ function GamePanel(props) {
setActiveSkill, setActiveSkill,
selectSkillTarget, selectSkillTarget,
account, account,
showLog,
toggleLog,
quit, quit,
} = props; } = props;
if (!game) return <div>...</div>; if (!game) return <div>...</div>;
const header = (
<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>
<button
className="game-back-btn instance-btn instance-ui-btn left"
onClick={() => toggleLog(!showLog)}>
{showLog ? 'Game' : 'Log'}
</button>
</div>
);
if (showLog) {
const logs = game.log.map((l, i) => (<div key={i}>{l}</div>)).reverse();
return (
<main>
{header}
<div className="logs">
{logs}
</div>
</main>
);
}
function findCryp(id) { function findCryp(id) {
const team = game.teams.find(t => t.cryps.find(c => c.id === id)); const team = game.teams.find(t => t.cryps.find(c => c.id === id));
if (team) return team.cryps.find(c => c.id === id); if (team) return team.cryps.find(c => c.id === id);
@ -166,20 +198,10 @@ function GamePanel(props) {
const selectedSkills = playerTeam.cryps.map((c, i) => stackElement(c, i)); const selectedSkills = playerTeam.cryps.map((c, i) => stackElement(c, i));
const logs = game.log.map((l, i) => (<div key={i}>{l}</div>)).reverse();
return ( return (
<main> <main>
<div className="instance-hdr"> {header}
<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)} {PlayerTeam(playerTeam, setActiveSkill)}
<div className="selected-skills"> <div className="selected-skills">
{selectedSkills} {selectedSkills}
@ -187,9 +209,6 @@ function GamePanel(props) {
<div className="team-opponent"> <div className="team-opponent">
{otherTeams.map(OpponentTeam)} {otherTeams.map(OpponentTeam)}
</div> </div>
<div className="logs">
{logs}
</div>
</main> </main>
); );
} }

View File

@ -11,7 +11,7 @@ const particlesJS = window.particlesJS;
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { ws, game, account, activeSkill, activeIncoming } = state; const { ws, game, account, showLog, activeSkill, activeIncoming } = state;
function selectSkillTarget(targetCrypId) { function selectSkillTarget(targetCrypId) {
if (activeSkill) { if (activeSkill) {
@ -32,7 +32,7 @@ const addState = connect(
return false; return false;
} }
return { game, account, activeSkill, activeIncoming, selectSkillTarget, selectIncomingTarget }; return { game, showLog, account, activeSkill, activeIncoming, selectSkillTarget, selectIncomingTarget };
}, },
function receiveDispatch(dispatch) { function receiveDispatch(dispatch) {
@ -49,7 +49,12 @@ const addState = connect(
dispatch(actions.setGame(null)); dispatch(actions.setGame(null));
} }
return { setActiveSkill, setActiveIncoming, quit }; function toggleLog(v) {
dispatch(actions.setShowLog(v));
}
return { setActiveSkill, setActiveIncoming, quit, toggleLog };
} }
); );

View File

@ -6,9 +6,10 @@ function Info(args) {
info, info,
sendUnequip, sendUnequip,
} = args; } = args;
if (!info) return (<div className="instance-info">&nbsp;</div>); if (!info.length) return (<div className="instance-info">&nbsp;</div>);
if (info.type === 'item') { const [type, value] = info;
if (type === 'item') {
return ( return (
<div className="instance-info"> <div className="instance-info">
{info.value} - what does it do? {info.value} - what does it do?
@ -16,34 +17,34 @@ function Info(args) {
); );
} }
if (info.type === 'skill') { if (type === 'skill') {
return ( return (
<div className="instance-info"> <div className="instance-info">
<div> <div>
<div> {info.value.skill} </div> <div> {value.skill} </div>
<div> {SKILLS[info.value.skill].description} </div> <div> {SKILLS[value.skill].description} </div>
</div> <button onClick={() => sendUnequip(value.cryp.id, value.skill)}>
<button onClick={() => sendUnequip(info.value.cryp.id, info.value.skill)}>
unequip unequip
</button> </button>
</div>
</div> </div>
); );
} }
if (info.type === 'spec') { if (type === 'spec') {
return ( return (
<div className="instance-info"> <div className="instance-info">
<div> <div>
<div> {info.value.spec} </div> <div> {value.spec} </div>
<div> {SPECS[info.value.spec].description} </div> <div> {SPECS[value.spec].description} </div>
</div> </div>
<button onClick={() => sendUnequip(info.value.cryp.id, info.value.spec)}> <button onClick={() => sendUnequip(value.cryp.id, value.spec)}>
unequip unequip
</button> </button>
</div> </div>
); );
} }
if (info.type === 'cryp') { if (type === 'cryp') {
const stats = [ const stats = [
{ stat: 'hp', disp: 'Hp', colour: '#1FF01F' }, { stat: 'hp', disp: 'Hp', colour: '#1FF01F' },
{ stat: 'red_shield', disp: 'Red Shield', colour: '#a52a2a' }, { stat: 'red_shield', disp: 'Red Shield', colour: '#a52a2a' },
@ -53,16 +54,30 @@ function Info(args) {
{ stat: 'green_damage', disp: 'Green Damage', colour: '#1FF01F' }, { stat: 'green_damage', disp: 'Green Damage', colour: '#1FF01F' },
{ stat: 'speed', disp: 'Speed', colour: '#FFD123' }, { stat: 'speed', disp: 'Speed', colour: '#FFD123' },
].map((s, i) => ( ].map((s, i) => (
<div key={i}>{s.disp}: {info.value[s.stat].base} -> {info.value[s.stat].max}</div> <div key={i}>{s.disp}: {value[s.stat].base} - {value[s.stat].max}</div>
)); ));
const cryp = value;
const skills = cryp.skills.map((s, i) => <button key={i} className="instance-btn"
onClick={() => sendUnequip(cryp.id, s.skill)} >{s.skill}</button>);
const specs = cryp.specs.map((s, i) => <button key={i} className="instance-btn"
onClick={() => sendUnequip(cryp.id, s) }>{s}</button>);
return ( return (
<div className="instance-info"> <div className="instance-info">
<h5> {info.value.name} </h5> <h5>{cryp.name}</h5>
{stats} <div className="info-stats">
{stats}
</div>
<div className="info-skills">
{skills}
</div>
<div className="info-specs">
{specs}
</div>
</div> </div>
); );
} }
} }
module.exports = Info; module.exports = Info;

View File

@ -71,7 +71,7 @@ function InstanceComponent(args) {
if (!instance) return <div>...</div>; if (!instance) return <div>...</div>;
const cryps = instance.cryps.map(c => Cryp(c, sendVboxApply, setInfo)); const cryps = instance.cryps.map((c, i) => Cryp(c, sendVboxApply, setInfo));
return ( return (
<main className="instance" > <main className="instance" >

View File

@ -16,6 +16,8 @@ const addState = connect(
return ws.sendVboxApply(instance.instance, crypId, i); return ws.sendVboxApply(instance.instance, crypId, i);
} }
console.log(instance, 'instaince')
return { instance, account, sendInstanceReady, sendVboxApply }; return { instance, account, sendInstanceReady, sendVboxApply };
}, },
@ -24,8 +26,8 @@ const addState = connect(
dispatch(actions.setInstance(null)); dispatch(actions.setInstance(null));
} }
function setInfo(item, cryp) { function setInfo(item, value) {
dispatch(actions.setInfo(item, cryp)); dispatch(actions.setInfo([item, value]));
} }
return { quit, setInfo }; return { quit, setInfo };

View File

@ -0,0 +1,59 @@
const preact = require('preact');
const { Component } = require('preact');
class SpawnButton extends Component {
constructor(props) {
super(props);
this.state = { value: null, enabled: false };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.enable = this.enable.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
this.props.spawn(this.state.value);
this.setState({ value: null, enabled: false });
}
enable() {
this.setState({ enabled: true });
}
render() {
return (
<div
key={this.props.i}
className="menu-cryp-ctr spawn-btn">
<div
className="menu-cryp"
onClick={() => this.enable()} >
<h2>+</h2>
<input
className="login-input"
type="text"
disabled={!this.state.enabled}
value={this.state.value}
placeholder="name"
onChange={this.handleChange}
/>
<button
className="login-btn"
disabled={!this.state.enabled}
onClick={this.handleSubmit}
type="submit">
spawn
</button>
</div>
</div>
);
}
}
module.exports = SpawnButton;

View File

@ -45,7 +45,7 @@ const addState = connect(
} }
function setInfo(type, info) { function setInfo(type, info) {
return dispatch(actions.setInfo(type, info)); return dispatch(actions.setInfo([type, info]));
} }

View File

@ -32,8 +32,8 @@ function registerEvents(store) {
store.dispatch(actions.setActiveSkill(skill)); store.dispatch(actions.setActiveSkill(skill));
} }
function setInfo(info) { function clearInfo(info) {
store.dispatch(actions.setInfo(info)); store.dispatch(actions.setInfo([]));
console.log('event clear item'); console.log('event clear item');
} }
@ -202,7 +202,7 @@ function registerEvents(store) {
setCryps, setCryps,
setCrypList, setCrypList,
setGame, setGame,
setInfo, clearInfo,
setMenu, setMenu,
setPlayer, setPlayer,
setInstanceList, setInstanceList,

View File

@ -21,6 +21,7 @@ const store = createStore(
combiner: reducers.combinerReducer, combiner: reducers.combinerReducer,
cryps: reducers.crypsReducer, cryps: reducers.crypsReducer,
game: reducers.gameReducer, game: reducers.gameReducer,
showLog: reducers.showLogReducer,
info: reducers.infoReducer, info: reducers.infoReducer,
instance: reducers.instanceReducer, instance: reducers.instanceReducer,
instances: reducers.instancesReducer, instances: reducers.instancesReducer,

View File

@ -80,6 +80,16 @@ function gameReducer(state = defaultGame, action) {
} }
} }
const defaultShowLog = false;
function showLogReducer(state = defaultShowLog, action) {
switch (action.type) {
case actions.SET_SHOW_LOG:
return action.value;
default:
return state;
}
}
const defaultReclaiming = false; const defaultReclaiming = false;
function reclaimingReducer(state = defaultReclaiming, action) { function reclaimingReducer(state = defaultReclaiming, action) {
switch (action.type) { switch (action.type) {
@ -100,7 +110,7 @@ function wsReducer(state = defaultWs, action) {
} }
} }
const defaultInfo = null; const defaultInfo = [];
function infoReducer(state = defaultInfo, action) { function infoReducer(state = defaultInfo, action) {
switch (action.type) { switch (action.type) {
case actions.SET_INFO: case actions.SET_INFO:
@ -116,6 +126,7 @@ module.exports = {
combinerReducer, combinerReducer,
crypsReducer, crypsReducer,
gameReducer, gameReducer,
showLogReducer,
instanceReducer, instanceReducer,
instancesReducer, instancesReducer,
reclaimingReducer, reclaimingReducer,

View File

@ -95,7 +95,7 @@ function createSocket(events) {
function sendVboxUnequip(instanceId, crypId, target) { function sendVboxUnequip(instanceId, crypId, target) {
send({ method: 'player_vbox_unequip', params: { instance_id: instanceId, cryp_id: crypId, target } }); send({ method: 'player_vbox_unequip', params: { instance_id: instanceId, cryp_id: crypId, target } });
events.setInfo(null); events.clearInfo();
} }
function sendVboxDiscard(instanceId) { function sendVboxDiscard(instanceId) {
@ -260,7 +260,7 @@ function createSocket(events) {
// if (!account) events.loginPrompt(); // if (!account) events.loginPrompt();
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
send({ method: 'account_login', params: { name: 'grepking', password: 'grepgrepgrep' } }); send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } });
} }
return true; return true;

View File

@ -61,7 +61,7 @@ const STATS = {
redDamage: { stat: 'red_damage', colour: 'red', svg: shapes.pentagon }, redDamage: { stat: 'red_damage', colour: 'red', svg: shapes.pentagon },
blueShield: { stat: 'blue_shield', colour: 'blue', svg: shapes.squircle }, blueShield: { stat: 'blue_shield', colour: 'blue', svg: shapes.squircle },
blueDamage: { stat: 'blue_damage', colour: 'blue', svg: shapes.circle }, blueDamage: { stat: 'blue_damage', colour: 'blue', svg: shapes.circle },
speed: { stat: 'speed', colour: 'yellow', svg: shapes.triangle }, speed: { stat: 'speed', colour: '', svg: shapes.triangle },
}; };
const SPECS = { const SPECS = {

View File

@ -638,6 +638,20 @@ pub fn vbox_unequip(params: VboxUnequipParams, tx: &mut Transaction, account: &A
None => return Err(err_msg("var has no effect on cryps")), None => return Err(err_msg("var has no effect on cryps")),
} }
// now the var has been applied
// recalculate the stats of the whole team
let team_colours = player.cryps.iter().fold(Colours::new(), |tc, c| {
Colours {
red: tc.red + c.colours.red,
green: tc.green + c.colours.green,
blue: tc.blue + c.colours.blue
}
});
for cryp in player.cryps.iter_mut() {
cryp.apply_modifiers(&team_colours);
}
player.vbox.bound.push(params.target); player.vbox.bound.push(params.target);
return player_update(tx, player, false); return player_update(tx, player, false);
} }