combat text
This commit is contained in:
parent
56d1162d79
commit
2e7e9d465d
@ -596,6 +596,12 @@ header {
|
|||||||
filter: blur(5px);
|
filter: blur(5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text.combat-text {
|
||||||
|
fill: whitesmoke;
|
||||||
|
font-size: 5em;
|
||||||
|
font-family: 'Jura';
|
||||||
|
}
|
||||||
|
|
||||||
.team-player {
|
.team-player {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
@ -654,6 +660,10 @@ CRYP DAMAGE
|
|||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red-damage text {
|
||||||
|
fill: red;
|
||||||
|
}
|
||||||
|
|
||||||
.red-damage .stats {
|
.red-damage .stats {
|
||||||
border-top: 3px solid red;
|
border-top: 3px solid red;
|
||||||
}
|
}
|
||||||
@ -670,6 +680,10 @@ CRYP DAMAGE
|
|||||||
color: blue;
|
color: blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blue-damage text {
|
||||||
|
fill: blue;
|
||||||
|
}
|
||||||
|
|
||||||
.blue-damage .stats {
|
.blue-damage .stats {
|
||||||
border-top: 3px solid blue;
|
border-top: 3px solid blue;
|
||||||
}
|
}
|
||||||
@ -686,6 +700,10 @@ CRYP DAMAGE
|
|||||||
color: green;
|
color: green;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.green-damage text {
|
||||||
|
fill: green;
|
||||||
|
}
|
||||||
|
|
||||||
.green-damage .stats {
|
.green-damage .stats {
|
||||||
border-top: 3px solid green;
|
border-top: 3px solid green;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,9 @@ const range = require('lodash/range');
|
|||||||
|
|
||||||
const molecule = require('./molecule');
|
const molecule = require('./molecule');
|
||||||
|
|
||||||
const { STATS, eventClasses } = require('../utils');
|
const { STATS, eventClasses, getCombatText } = require('../utils');
|
||||||
|
|
||||||
|
const GameCryp = require('./game.cryp');
|
||||||
|
|
||||||
// const SKILL_HOT_KEYS = ['Q', 'W', 'E', 'R'];
|
// const SKILL_HOT_KEYS = ['Q', 'W', 'E', 'R'];
|
||||||
|
|
||||||
@ -94,95 +96,8 @@ function GamePanel(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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> </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 classes = eventClasses(resolution, cryp);
|
|
||||||
|
|
||||||
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} ${classes}`} >
|
|
||||||
<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) {
|
function PlayerTeam(team) {
|
||||||
const cryps = team.cryps.map(c => Cryp(c));
|
const cryps = team.cryps.map((c, i) => <GameCryp key={i} cryp={c} />);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="team-player cryp-list">
|
<div className="team-player cryp-list">
|
||||||
@ -195,8 +110,6 @@ function GamePanel(props) {
|
|||||||
const ko = cryp.green_life.value === 0 ? 'ko' : '';
|
const ko = cryp.green_life.value === 0 ? 'ko' : '';
|
||||||
const classes = eventClasses(resolution, cryp);
|
const classes = eventClasses(resolution, cryp);
|
||||||
|
|
||||||
console.log(cryp.name, classes);
|
|
||||||
|
|
||||||
const stats = [STATS.greenLife, STATS.redLife, STATS.blueLife].map((s, j) => (
|
const stats = [STATS.greenLife, STATS.redLife, STATS.blueLife].map((s, j) => (
|
||||||
<figure key={j} alt={s.stat}>
|
<figure key={j} alt={s.stat}>
|
||||||
{s.svg(`stat-icon ${s.colour}`)}
|
{s.svg(`stat-icon ${s.colour}`)}
|
||||||
@ -204,6 +117,8 @@ function GamePanel(props) {
|
|||||||
</figure>
|
</figure>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
const combatText = getCombatText(cryp, resolution);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={i}
|
key={i}
|
||||||
@ -212,7 +127,7 @@ function GamePanel(props) {
|
|||||||
onClick={() => selectSkillTarget(cryp.id)} >
|
onClick={() => selectSkillTarget(cryp.id)} >
|
||||||
<div className="cryp-box-top">
|
<div className="cryp-box-top">
|
||||||
<figure className="img">
|
<figure className="img">
|
||||||
{molecule}
|
{molecule(combatText)}
|
||||||
<figcaption>{cryp.name}</figcaption>
|
<figcaption>{cryp.name}</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
</div>
|
</div>
|
||||||
@ -241,16 +156,15 @@ function GamePanel(props) {
|
|||||||
? resolutionEl(resolution)
|
? resolutionEl(resolution)
|
||||||
: playerTeam.cryps.map((c, i) => stackElement(c, i));
|
: playerTeam.cryps.map((c, i) => stackElement(c, i));
|
||||||
|
|
||||||
const mobileSkills = activeCryp
|
// const mobileSkills = activeCryp
|
||||||
? range(0, 3).map(i => Skill(activeCryp, i, true))
|
// ? range(0, 3).map(i => Skill(activeCryp, i, true))
|
||||||
: (<div/>);
|
// : (<div/>);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="game" onClick={() => setActiveCryp(null)} >
|
<main className="game" onClick={() => setActiveCryp(null)} >
|
||||||
{header}
|
{header}
|
||||||
{PlayerTeam(playerTeam, setActiveSkill)}
|
{PlayerTeam(playerTeam, setActiveSkill)}
|
||||||
<div className="mobile-skills">
|
<div className="mobile-skills">
|
||||||
{mobileSkills}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="selected-skills">
|
<div className="selected-skills">
|
||||||
{selectedSkills}
|
{selectedSkills}
|
||||||
|
|||||||
150
client/src/components/game.cryp.jsx
Normal file
150
client/src/components/game.cryp.jsx
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
const { connect } = require('preact-redux');
|
||||||
|
const preact = require('preact');
|
||||||
|
const range = require('lodash/range');
|
||||||
|
|
||||||
|
const molecule = require('./molecule');
|
||||||
|
const actions = require('../actions');
|
||||||
|
const { STATS, eventClasses, getCombatText } = require('../utils');
|
||||||
|
|
||||||
|
const addState = connect(
|
||||||
|
function receiveState(state) {
|
||||||
|
const {
|
||||||
|
ws,
|
||||||
|
game,
|
||||||
|
resolution,
|
||||||
|
activeSkill,
|
||||||
|
activeCryp,
|
||||||
|
} = 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
resolution,
|
||||||
|
activeSkill,
|
||||||
|
activeCryp,
|
||||||
|
selectSkillTarget,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
function receiveDispatch(dispatch) {
|
||||||
|
function setActiveSkill(crypId, skill) {
|
||||||
|
dispatch(actions.setActiveSkill(crypId, skill));
|
||||||
|
}
|
||||||
|
|
||||||
|
function setActiveCryp(cryp) {
|
||||||
|
dispatch(actions.setActiveCryp(cryp));
|
||||||
|
}
|
||||||
|
|
||||||
|
return { setActiveSkill, setActiveCryp };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
function GameCryp(props) {
|
||||||
|
const {
|
||||||
|
cryp,
|
||||||
|
resolution,
|
||||||
|
|
||||||
|
activeSkill,
|
||||||
|
setActiveSkill,
|
||||||
|
setActiveCryp,
|
||||||
|
selectSkillTarget,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const ko = cryp.green_life.value === 0 ? 'ko' : '';
|
||||||
|
|
||||||
|
function Skill(i, mobile) {
|
||||||
|
const s = cryp.skills[i];
|
||||||
|
if (!s) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
disabled='true'
|
||||||
|
key={i}
|
||||||
|
className='cryp-skill-btn disabled'>
|
||||||
|
<span> </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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const classes = eventClasses(resolution, cryp);
|
||||||
|
|
||||||
|
const skills = range(0, 3).map(i => Skill(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
const combatText = getCombatText(cryp, resolution);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={ activeSkill ? { cursor: 'pointer' } : {}}
|
||||||
|
onClick={onClick}
|
||||||
|
className={`cryp-box ${ko} ${classes}`} >
|
||||||
|
<div className="cryp-box-top">
|
||||||
|
<figure
|
||||||
|
className="img"
|
||||||
|
onClick={() => selectSkillTarget(cryp.id)} >
|
||||||
|
{molecule(combatText)}
|
||||||
|
<figcaption>{cryp.name}</figcaption>
|
||||||
|
</figure>
|
||||||
|
<div className="skills">
|
||||||
|
{skills}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="stats">
|
||||||
|
{stats}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = addState(GameCryp);
|
||||||
@ -92,7 +92,7 @@ function Cryp(props) {
|
|||||||
>
|
>
|
||||||
<div className="cryp-box-top">
|
<div className="cryp-box-top">
|
||||||
<figure className="img" onClick={onClick}>
|
<figure className="img" onClick={onClick}>
|
||||||
{molecule}
|
{molecule()}
|
||||||
<figcaption>{cryp.name}</figcaption>
|
<figcaption>{cryp.name}</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
<div className="skills">
|
<div className="skills">
|
||||||
|
|||||||
@ -109,7 +109,7 @@ function Menu(args) {
|
|||||||
style={ { 'border-color': borderColour || 'whitesmoke' } }
|
style={ { 'border-color': borderColour || 'whitesmoke' } }
|
||||||
onClick={() => selectCryp(cryp.id)} >
|
onClick={() => selectCryp(cryp.id)} >
|
||||||
<figure className="img">
|
<figure className="img">
|
||||||
{molecule}
|
{molecule()}
|
||||||
</figure>
|
</figure>
|
||||||
<h2>{cryp.name}</h2>
|
<h2>{cryp.name}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -23,7 +23,7 @@ function registerEvents(store) {
|
|||||||
if (game.resolved.length !== currentGame.resolved.length) {
|
if (game.resolved.length !== currentGame.resolved.length) {
|
||||||
const newRes = game.resolved.slice(currentGame.resolved.length);
|
const newRes = game.resolved.slice(currentGame.resolved.length);
|
||||||
return eachSeries(newRes, (r, cb) => {
|
return eachSeries(newRes, (r, cb) => {
|
||||||
if (r.event[0] === 'Disable') return cb();
|
if (['Disable', 'TargetKo'].includes(r.event[0])) return cb();
|
||||||
store.dispatch(actions.setResolution(r));
|
store.dispatch(actions.setResolution(r));
|
||||||
return setTimeout(cb, TIMES.RESOLUTION_TIME_MS);
|
return setTimeout(cb, TIMES.RESOLUTION_TIME_MS);
|
||||||
}, err => {
|
}, err => {
|
||||||
|
|||||||
@ -81,13 +81,13 @@ const SPECS = {
|
|||||||
GBDI: { colour: 'cyan', caption: 'DamageI', svg: shapes.circle },
|
GBDI: { colour: 'cyan', caption: 'DamageI', svg: shapes.circle },
|
||||||
RBDI: { colour: 'purple', caption: 'DamageI', svg: shapes.circle },
|
RBDI: { colour: 'purple', caption: 'DamageI', svg: shapes.circle },
|
||||||
|
|
||||||
Speed: { colour: 'white', caption: 'Speed', svg: shapes.diamond },
|
Speed: { colour: 'white', caption: 'Speed', svg: shapes.triangle },
|
||||||
RedSpeed: { colour: 'red', caption: 'Speed', svg: shapes.diamond },
|
RedSpeed: { colour: 'red', caption: 'Speed', svg: shapes.triangle },
|
||||||
BlueSpeedI: { colour: 'blue', caption: 'Speed', svg: shapes.diamond },
|
BlueSpeedI: { colour: 'blue', caption: 'Speed', svg: shapes.triangle },
|
||||||
GreenSpeedI: { colour: 'green', caption: 'Speed', svg: shapes.diamond },
|
GreenSpeedI: { colour: 'green', caption: 'Speed', svg: shapes.triangle },
|
||||||
GRSpeedI: { colour: 'yellow', caption: 'Speed', svg: shapes.diamond },
|
GRSpeedI: { colour: 'yellow', caption: 'Speed', svg: shapes.triangle },
|
||||||
GBSpeedI: { colour: 'cyan', caption: 'Speed', svg: shapes.diamond },
|
GBSpeedI: { colour: 'cyan', caption: 'Speed', svg: shapes.triangle },
|
||||||
RBSpeedI: { colour: 'purple', caption: 'Speed', svg: shapes.diamond },
|
RBSpeedI: { colour: 'purple', caption: 'Speed', svg: shapes.triangle },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -163,12 +163,70 @@ function eventClasses(resolution, cryp) {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCombatText(cryp, resolution) {
|
||||||
|
if (!resolution) return '';
|
||||||
|
if (cryp.id !== resolution.target.id) return '';
|
||||||
|
|
||||||
|
const [type, event] = resolution.event;
|
||||||
|
|
||||||
|
if (type === 'Ko') {
|
||||||
|
return 'KO!';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Disable') {
|
||||||
|
const { skill, disable } = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Immunity') {
|
||||||
|
const { skill, immunity } = event;
|
||||||
|
return 'IMMUNE';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'TargetKo') {
|
||||||
|
const { skill } = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Damage') {
|
||||||
|
const { skill, amount, mitigation, colour } = event;
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Healing') {
|
||||||
|
const { skill, amount, overhealing } = event;
|
||||||
|
return `${amount} (${overhealing}OH)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Inversion') {
|
||||||
|
const { skill } = event;
|
||||||
|
return 'INVERT';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Reflection') {
|
||||||
|
const { skill } = event;
|
||||||
|
return 'REFLECT';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Effect') {
|
||||||
|
const { skill, effect, duration } = event;
|
||||||
|
return `+ ${effect} ${duration}T`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Removal') {
|
||||||
|
const { effect } = event;
|
||||||
|
return `- ${effect}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
stringSort,
|
stringSort,
|
||||||
numSort,
|
numSort,
|
||||||
genAvatar,
|
genAvatar,
|
||||||
requestAvatar,
|
requestAvatar,
|
||||||
eventClasses,
|
eventClasses,
|
||||||
|
getCombatText,
|
||||||
NULL_UUID,
|
NULL_UUID,
|
||||||
STATS,
|
STATS,
|
||||||
SPECS,
|
SPECS,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user