mnml/client/src/components/game.component.jsx
2019-04-09 16:05:08 +10:00

250 lines
6.9 KiB
JavaScript

const preact = require('preact');
const range = require('lodash/range');
const molecule = require('./molecule');
const { STATS } = require('../utils');
// const SKILL_HOT_KEYS = ['Q', 'W', 'E', 'R'];
function GamePanel(props) {
const {
game,
activeSkill,
setActiveSkill,
setActiveCryp,
selectSkillTarget,
activeCryp,
account,
showLog,
toggleLog,
quit,
} = props;
if (!game) return <div>...</div>;
if (showLog) {
const logs = game.log.map((l, i) => (<div key={i}>{l}</div>)).reverse();
return (
<main className="game">
<div className="instance-hdr">
<button
className="game-back-btn instance-btn instance-ui-btn left"
onClick={() => toggleLog(!showLog)}>
Game
</button>
<div className="spacer">
<div>&nbsp;</div>
</div>
</div>
<div className="logs">
{logs}
</div>
</main>
);
}
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)}>
Log
</button>
</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 Skill(cryp, i, mobile) {
const ko = cryp.green_life.value === 0 ? 'ko' : '';
const s = cryp.skills[i];
if (!s) {
return (
<button
disabled='true'
key={i}
className='cryp-skill-btn disabled'>
<span>&nbsp;</span>
</button>
);
}
const side = mobile
? 'top'
: 'right';
const cdText = cryp.skills[i].cd > 0
? `- ${s.cd}`
: '';
const highlight = activeSkill
? activeSkill.crypId === cryp.id && activeSkill.skill === s
: false;
function onClick(e) {
e.stopPropagation();
return setActiveSkill(cryp.id, s.skill);
}
return (
<button
key={i}
disabled={!!cdText || ko}
className={`cryp-skill-btn ${side} ${highlight ? 'active' : ''}`}
type="submit"
onClick={onClick}>
{s.skill} {cdText}
</button>
);
}
function Cryp(cryp) {
const ko = cryp.green_life.value === 0 ? 'ko' : '';
const skills = range(0, 3).map(i => Skill(cryp, i));
const stats = [STATS.greenLife, STATS.redLife, STATS.blueLife].map((s, j) => (
<figure key={j} alt={s.stat}>
{s.svg(`stat-icon ${s.colour}`)}
<figcaption>{cryp[s.stat].value} / {cryp[s.stat].max}</figcaption>
</figure>
));
function onClick(e) {
e.stopPropagation();
return setActiveCryp(cryp);
}
return (
<div
key={cryp.id}
style={ activeSkill ? { cursor: 'pointer' } : {}}
onClick={onClick}
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 = [STATS.greenLife, STATS.redLife, STATS.blueLife].map((s, j) => (
<figure key={j} alt={s.stat}>
{s.svg(`stat-icon ${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 mobileSkills = activeCryp
? range(0, 3).map(i => Skill(activeCryp, i, true))
: (<div/>);
return (
<main className="game" onClick={() => setActiveCryp(null)} >
{header}
{PlayerTeam(playerTeam, setActiveSkill)}
<div className="mobile-skills">
{mobileSkills}
</div>
<div className="selected-skills">
{selectedSkills}
</div>
<div className="team-opponent cryp-list">
{otherTeams.map(OpponentTeam)}
</div>
</main>
);
}
module.exports = GamePanel;