combat events init

This commit is contained in:
ntr 2019-04-12 16:08:54 +10:00
parent c0303c5b61
commit 4a081d6ec1
18 changed files with 143 additions and 391 deletions

View File

@ -501,6 +501,11 @@ header {
border: 1px solid whitesmoke; border: 1px solid whitesmoke;
margin-bottom: 1em; margin-bottom: 1em;
justify-content: center; justify-content: center;
transition-property: all;
transition-duration: 0.5s;
transition-delay: 0;
transition-timing-function: ease;
} }
.cryp-box-top { .cryp-box-top {
@ -584,6 +589,27 @@ header {
.cryp-box.ko { .cryp-box.ko {
animation: none; animation: none;
opacity: 0.5; opacity: 0.5;
filter: grayscale(100%);
}
.cryp-box.unfocus {
filter: blur(5px);
}
.cryp-box.red-damage {
filter: drop-shadow(0 0 0.2em red);
border-width: 5px;
color: red;
border-color: red;
}
.red-damage button {
border: 3px solid red;
color: red;
}
.red-damage .stats {
border-top: 3px solid red;
} }
.team-player { .team-player {

View File

@ -1,105 +0,0 @@
const preact = require('preact');
const range = require('lodash/range');
const { stringSort } = require('./../utils');
const molecule = require('./molecule');
const SpawnButton = require('./spawn.button');
const idSort = stringSort('id');
const COLOURS = [
'#a52a2a',
'#1FF01F',
'#3498db',
];
function CrypList(args) {
const {
cryps,
selectedCryps,
setSelectedCryps,
sendPlayerMmCrypsSet,
sendInstanceJoin,
sendCrypSpawn
} = args;
if (!cryps) return <div></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 instanceJoinHidden = !selectedCryps.every(c => !!c);
const mmSet = (
<button
className={`menu-instance-btn full left ${instanceJoinHidden ? 'hidden' : ''}`}
disabled={instanceJoinHidden}
onClick={() => sendPlayerMmCrypsSet()}>
Set Matchmaking Team
</button>
);
const instanceJoin = (
<button
className={`menu-instance-btn full right ${instanceJoinHidden ? 'hidden' : ''}`}
disabled={instanceJoinHidden}
onClick={() => sendInstanceJoin()}>
Join New Instance
</button>
);
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>
);
});
const spawnButtonsNum = cryps.length < 3
? (3 - cryps.length)
: 1;
const spawnButtons = range(spawnButtonsNum)
.map(i => <SpawnButton key={i} i={i} spawn={name => sendCrypSpawn(name)} />);
return (
<div className="menu-cryps">
{mmSet}
{instanceJoin}
{crypPanels}
{spawnButtons}
</div>
);
}
module.exports = CrypList;

View File

@ -1,65 +0,0 @@
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, instances } = state;
function sendInstanceJoin() {
if (selectedCryps.length) {
return ws.sendInstanceJoin(selectedCryps);
}
return false;
}
function sendPlayerMmCrypsSet() {
if (selectedCryps.length) {
return ws.sendPlayerMmCrypsSet(selectedCryps);
}
return false;
}
function sendCrypSpawn(name) {
return ws.sendCrypSpawn(name);
}
return { cryps, selectedCryps, sendInstanceJoin, sendCrypSpawn, sendPlayerMmCrypsSet };
},
function receiveDispatch(dispatch) {
function setSelectedCryps(crypIds) {
dispatch(actions.setSelectedCryps(crypIds));
}
function setActiveInstance(instance) {
dispatch(actions.setInstance(instance));
}
return {
setSelectedCryps,
setActiveInstance,
};
}
);
module.exports = addState(CrypList);
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 };
},

View File

@ -140,6 +140,11 @@ function GamePanel(props) {
function Cryp(cryp) { function Cryp(cryp) {
const ko = cryp.green_life.value === 0 ? 'ko' : ''; const ko = cryp.green_life.value === 0 ? 'ko' : '';
const unfocus = () => {
if (!resolution) return false;
if (cryp.id === resolution.source.id || cryp.id === resolution.target.id) return false;
return 'unfocus';
};
const skills = range(0, 3).map(i => Skill(cryp, i)); const skills = range(0, 3).map(i => Skill(cryp, i));
@ -161,7 +166,7 @@ function GamePanel(props) {
key={cryp.id} key={cryp.id}
style={ activeSkill ? { cursor: 'pointer' } : {}} style={ activeSkill ? { cursor: 'pointer' } : {}}
onClick={onClick} onClick={onClick}
className={`cryp-box ${ko}`} > className={`cryp-box ${ko} ${unfocus()}`} >
<div className="cryp-box-top"> <div className="cryp-box-top">
<figure <figure
className="img" className="img"
@ -193,6 +198,12 @@ function GamePanel(props) {
function OpponentCryp(cryp, i) { function OpponentCryp(cryp, i) {
const ko = cryp.green_life.value === 0 ? 'ko' : ''; const ko = cryp.green_life.value === 0 ? 'ko' : '';
const unfocus = () => {
if (!resolution) return false;
if (cryp.id === resolution.source.id || cryp.id === resolution.target.id) return false;
return 'unfocus';
};
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}`)}
@ -203,7 +214,7 @@ function GamePanel(props) {
return ( return (
<div <div
key={i} key={i}
className={`cryp-box ${ko}`} className={`cryp-box ${ko} ${unfocus()}`}
style={ activeSkill ? { cursor: 'pointer' } : {}} style={ activeSkill ? { cursor: 'pointer' } : {}}
onClick={() => selectSkillTarget(cryp.id)} > onClick={() => selectSkillTarget(cryp.id)} >
<div className="cryp-box-top"> <div className="cryp-box-top">

View File

@ -1,13 +1,8 @@
// import 'particles.js/particles';
const { connect } = require('preact-redux'); const { connect } = require('preact-redux');
const actions = require('../actions'); const actions = require('../actions');
const Game = require('./game.component'); const Game = require('./game.component');
// const config = require('./particles.config');
// const particlesJS = window.particlesJS;
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {

View File

@ -1,7 +1,7 @@
const preact = require('preact'); const preact = require('preact');
const range = require('lodash/range'); const range = require('lodash/range');
const { ITEMS: { SKILLS, COLOURS, SPECS: SPEC_CONSTANT } } = require('./constants'); const { ITEMS: { SKILLS, COLOURS, SPECS: SPEC_CONSTANT } } = require('./../constants');
const { COLOUR_ICONS, STATS, SPECS } = require('../utils'); const { COLOUR_ICONS, STATS, SPECS } = require('../utils');
function Info(args) { function Info(args) {

View File

@ -1,131 +0,0 @@
const preact = require('preact');
const range = require('lodash/range');
const { stringSort, NULL_UUID } = require('./../utils');
const molecule = require('./molecule');
const SpawnButton = require('./spawn.button');
const idSort = stringSort('id');
const COLOURS = [
'#a52a2a',
'#1FF01F',
'#3498db',
];
function CrypList(args) {
const {
cryps,
selectedCryps,
setSelectedCryps,
sendPlayerMmCrypsSet,
sendInstanceJoin,
sendCrypSpawn
} = args;
if (!cryps) return <div></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 instanceJoinHidden = !selectedCryps.every(c => !!c);
const mmSet = (
<button
className={`menu-instance-btn full left ${instanceJoinHidden ? 'hidden' : ''}`}
disabled={instanceJoinHidden}
onClick={() => sendPlayerMmCrypsSet()}>
Set Matchmaking Team
</button>
);
const instanceJoin = (
<button
className={`menu-instance-btn full right ${instanceJoinHidden ? 'hidden' : ''}`}
disabled={instanceJoinHidden}
onClick={() => sendInstanceJoin()}>
Join New Instance
</button>
);
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>
);
});
const spawnButtonsNum = cryps.length < 3
? (3 - cryps.length)
: 1;
const spawnButtons = range(spawnButtonsNum)
.map(i => <SpawnButton key={i} i={i} spawn={name => sendCrypSpawn(name)} />);
return (
<div className="menu-cryps">
{mmSet}
{instanceJoin}
{crypPanels}
{spawnButtons}
</div>
);
}
function instanceList({ instances, setActiveInstance }) {
if (!instances) return <div>...</div>;
const instancePanels = instances.map(instance => {
const globalInstance = instance.instance === NULL_UUID;
const name = globalInstance
? 'Global Matchmaking'
: `${instance.instance.substring(0, 5)} | ${instance.score.wins} : ${instance.score.losses}`;
return (
<button
className={`menu-instance-btn right ${globalInstance ? 'full' : ''}`}
key={instance.id}
onClick={() => setActiveInstance(instance)}>
{name}
</button>
);
});
return (
<section className="menu-instance-list" >
{instancePanels}
</section>
);
}
module.exports = instanceList;

View File

@ -1,35 +0,0 @@
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);

View File

@ -20,7 +20,7 @@ function Menu(args) {
cryps, cryps,
selectedCryps, selectedCryps,
setSelectedCryps, setSelectedCryps,
setActiveInstance, sendPlayerState,
sendPlayerMmCrypsSet, sendPlayerMmCrypsSet,
sendInstanceJoin, sendInstanceJoin,
sendCrypSpawn, sendCrypSpawn,
@ -40,7 +40,7 @@ function Menu(args) {
<button <button
className={`menu-instance-btn right ${globalInstance ? 'full' : ''}`} className={`menu-instance-btn right ${globalInstance ? 'full' : ''}`}
key={instance.id} key={instance.id}
onClick={() => setActiveInstance(instance)}> onClick={() => sendPlayerState(instance)}>
{name} {name}
</button> </button>
); );

View File

@ -25,10 +25,15 @@ const addState = connect(
return ws.sendCrypSpawn(name); return ws.sendCrypSpawn(name);
} }
function sendPlayerState(instance) {
return ws.sendPlayerState(instance.instance);
}
return { return {
cryps, cryps,
selectedCryps, selectedCryps,
sendInstanceJoin, sendInstanceJoin,
sendPlayerState,
sendCrypSpawn, sendCrypSpawn,
sendPlayerMmCrypsSet, sendPlayerMmCrypsSet,
instances, instances,
@ -40,13 +45,8 @@ const addState = connect(
dispatch(actions.setSelectedCryps(crypIds)); dispatch(actions.setSelectedCryps(crypIds));
} }
function setActiveInstance(instance) {
dispatch(actions.setInstance(instance));
}
return { return {
setSelectedCryps, setSelectedCryps,
setActiveInstance,
}; };
} }
); );

View File

@ -1,4 +1,8 @@
module.exports = { module.exports = {
TIMES: {
RESOLUTION_TIME_MS: 2000,
},
ITEMS: { ITEMS: {
SKILLS: { SKILLS: {
Amplify: { Amplify: {

View File

@ -2,6 +2,7 @@ const toast = require('izitoast');
const eachSeries = require('async/eachSeries'); const eachSeries = require('async/eachSeries');
const actions = require('./actions'); const actions = require('./actions');
const { TIMES } = require('./constants');
function registerEvents(store) { function registerEvents(store) {
function setCryps(cryps) { function setCryps(cryps) {
@ -23,7 +24,7 @@ function registerEvents(store) {
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) => {
store.dispatch(actions.setResolution(r)); store.dispatch(actions.setResolution(r));
return setTimeout(cb, 500); return setTimeout(cb, TIMES.RESOLUTION_TIME_MS);
}, err => { }, err => {
if (err) return console.error(err); if (err) return console.error(err);
store.dispatch(actions.setResolution(null)); store.dispatch(actions.setResolution(null));

View File

@ -97,6 +97,60 @@ const COLOUR_ICONS = {
green: { colour: 'green', caption: 'green', svg: shapes.square }, green: { colour: 'green', caption: 'green', svg: shapes.square },
}; };
function eventClasses(resolution) {
const [type, event] = resolution.event;
if (type === 'Ko') {
return 'ko';
}
if (type === 'Disable') {
const { skill, disable } = event;
}
if (type === 'Immunity') {
const { skill, immunity } = event;
}
if (type === 'TargetKo') {
const { skill } = event;
}
if (type === 'Damage') {
const { skill, amount, mitigation, colour } = event;
}
if (type === 'Healing') {
const { skill, amount, overhealing } = event;
}
if (type === 'Inversion') {
const { skill } = event;
}
if (type === 'Reflection') {
const { skill } = event;
}
if (type === 'Effect') {
const { skill, effect, duration } = event;
}
if (type === 'Removal') {
const { effect } = event;
}
if (type === 'Recharge') {
const { skill, red, blue } = event;
}
if (type === 'Evasion') {
const { skill, evasion_rating } = event;
}
return false;
}
module.exports = { module.exports = {
stringSort, stringSort,
numSort, numSort,

View File

@ -25,9 +25,6 @@
* resolve animations + effects * resolve animations + effects
*SERVER* *SERVER*
cryp vbox
update defensives in skill.rs
consolidate buffs debuffs and disables consolidate buffs debuffs and disables
no more red/blue no more red/blue

View File

@ -536,7 +536,7 @@ impl Cryp {
skill, skill,
amount: delta, amount: delta,
mitigation: 0, mitigation: 0,
category: Category::GreenDamage, colour: Category::GreenDamage,
}); });
} }
} }
@ -584,7 +584,7 @@ impl Cryp {
skill, skill,
amount: delta, amount: delta,
mitigation, mitigation,
category: Category::RedDamage, colour: Category::RedDamage,
}); });
}, },
true => { true => {
@ -653,7 +653,7 @@ impl Cryp {
skill, skill,
amount: delta, amount: delta,
mitigation, mitigation,
category: Category::BlueDamage, colour: Category::BlueDamage,
}); });
}, },
true => { true => {

View File

@ -512,7 +512,7 @@ impl Game {
fn log_resolution(&mut self, speed: u64, resolution: &Resolution) -> &mut Game { fn log_resolution(&mut self, speed: u64, resolution: &Resolution) -> &mut Game {
let Resolution { source, target, event } = resolution; let Resolution { source, target, event } = resolution;
match event { match event {
Event::Ko => Event::Ko { skill: _ }=>
self.log.push(format!("{:} KO!", target.name)), self.log.push(format!("{:} KO!", target.name)),
Event::Disable { skill, disable } => Event::Disable { skill, disable } =>
@ -527,7 +527,7 @@ impl Game {
self.log.push(format!("[{:}] {:} {:?} {:} - target is KO", self.log.push(format!("[{:}] {:} {:?} {:} - target is KO",
speed, source.name, skill, target.name)), speed, source.name, skill, target.name)),
Event::Damage { skill, amount, mitigation, category: _ } => Event::Damage { skill, amount, mitigation, colour: _ } =>
self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:} mitigated)", self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:} mitigated)",
speed, source.name, skill, target.name, amount, mitigation)), speed, source.name, skill, target.name, amount, mitigation)),

View File

@ -94,7 +94,7 @@ pub fn resolve(skill: Skill, source: &mut Cryp, target: &mut Cryp, mut resolutio
// have to think // have to think
for r in resolutions.clone() { for r in resolutions.clone() {
match r.event { match r.event {
Event::Damage { amount, skill, mitigation: _, category: _ } => { Event::Damage { amount, skill, mitigation: _, colour: _ } => {
if target.affected(Effect::Corrupt) { if target.affected(Effect::Corrupt) {
resolutions = corruption(target, source, resolutions); resolutions = corruption(target, source, resolutions);
} }
@ -113,7 +113,7 @@ pub fn resolve(skill: Skill, source: &mut Cryp, target: &mut Cryp, mut resolutio
// i don't think we need to check the source being ko // i don't think we need to check the source being ko
if target.is_ko() { if target.is_ko() {
resolutions.push(Resolution::new(source, target).event(Event::Ko)); resolutions.push(Resolution::new(source, target).event(Event::Ko { skill }));
target.effects.clear(); target.effects.clear();
} }
@ -191,7 +191,7 @@ impl Resolution {
pub enum Event { pub enum Event {
Disable { skill: Skill, disable: Disable }, Disable { skill: Skill, disable: Disable },
Immunity { skill: Skill, immunity: Immunity }, Immunity { skill: Skill, immunity: Immunity },
Damage { skill: Skill, amount: u64, mitigation: u64, category: Category }, Damage { skill: Skill, amount: u64, mitigation: u64, colour: Category },
Healing { skill: Skill, amount: u64, overhealing: u64 }, Healing { skill: Skill, amount: u64, overhealing: u64 },
Recharge { skill: Skill, red: u64, blue: u64 }, Recharge { skill: Skill, red: u64, blue: u64 },
Inversion { skill: Skill }, Inversion { skill: Skill },
@ -200,8 +200,8 @@ pub enum Event {
Removal { effect: Effect }, Removal { effect: Effect },
Evasion { skill: Skill, evasion_rating: u64 }, Evasion { skill: Skill, evasion_rating: u64 },
TargetKo { skill: Skill }, TargetKo { skill: Skill },
Ko, // skill not necessary but makes it neater as all events are arrays in js
Ko { skill: Skill },
Incomplete, Incomplete,
} }
@ -1058,7 +1058,7 @@ fn siphon_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -
for e in siphon_events { for e in siphon_events {
match e { match e {
Event::Damage { amount, mitigation: _, category: _, skill: _ } => { Event::Damage { amount, mitigation: _, colour: _, skill: _ } => {
let dmg = source.deal_green_damage(Skill::Siphon, amount); let dmg = source.deal_green_damage(Skill::Siphon, amount);
for e in dmg { for e in dmg {
results.push(Resolution::new(source, target).event(e)); results.push(Resolution::new(source, target).event(e));
@ -1168,7 +1168,7 @@ mod tests {
let Resolution { source: _, target: _, event } = results.remove(0); let Resolution { source: _, target: _, event } = results.remove(0);
match event { match event {
Event::Damage { amount, mitigation: _, category: _, skill: _ } => assert_eq!(amount, 50), Event::Damage { amount, mitigation: _, colour: _, skill: _ } => assert_eq!(amount, 50),
_ => panic!("not damage"), _ => panic!("not damage"),
}; };
} }
@ -1191,7 +1191,7 @@ mod tests {
let Resolution { source: _, target: _, event } = results.remove(0); let Resolution { source: _, target: _, event } = results.remove(0);
match event { match event {
Event::Damage { amount, mitigation: _, category: _, skill: _ } => assert_eq!(amount, 1023), Event::Damage { amount, mitigation: _, colour: _, skill: _ } => assert_eq!(amount, 1023),
_ => panic!("not damage"), _ => panic!("not damage"),
}; };
} }
@ -1273,7 +1273,7 @@ mod tests {
let Resolution { source: _, target: _, event } = results.remove(0); let Resolution { source: _, target: _, event } = results.remove(0);
match event { match event {
Event::Damage { amount, mitigation: _, category: _, skill: _ } => assert_eq!(amount, 256), Event::Damage { amount, mitigation: _, colour: _, skill: _ } => assert_eq!(amount, 256),
_ => panic!("not damage"), _ => panic!("not damage"),
}; };
} }
@ -1307,7 +1307,7 @@ mod tests {
let Resolution { source: _, target: _, event } = results.remove(0); let Resolution { source: _, target: _, event } = results.remove(0);
match event { match event {
Event::Damage { amount, skill: _, mitigation: _, category: _} => assert_eq!(amount, 256), Event::Damage { amount, skill: _, mitigation: _, colour: _} => assert_eq!(amount, 256),
_ => panic!("not damage siphon"), _ => panic!("not damage siphon"),
}; };