rework damage calculation between resolutions
This commit is contained in:
parent
ea04192897
commit
23e9870d8f
@ -1,18 +1,14 @@
|
|||||||
const preact = require('preact');
|
const preact = require('preact');
|
||||||
const { STATS, eventClasses, getCombatText, constructAvatar } = require('../utils');
|
|
||||||
// const { animationDivs } = require('../animations');
|
// const { animationDivs } = require('../animations');
|
||||||
const GameConstruct = require('./game.construct');
|
const GameConstruct = require('./game.construct');
|
||||||
const shapes = require('./shapes');
|
|
||||||
|
|
||||||
function GamePanel(props) {
|
function GamePanel(props) {
|
||||||
const {
|
const {
|
||||||
game,
|
game,
|
||||||
account,
|
account,
|
||||||
resolution,
|
resolution,
|
||||||
activeSkill,
|
|
||||||
setActiveSkill,
|
setActiveSkill,
|
||||||
setActiveConstruct,
|
setActiveConstruct,
|
||||||
selectSkillTarget,
|
|
||||||
sendInstanceState,
|
sendInstanceState,
|
||||||
sendGameReady,
|
sendGameReady,
|
||||||
showLog,
|
showLog,
|
||||||
@ -109,8 +105,8 @@ function GamePanel(props) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
function PlayerTeam(team) {
|
function PlayerTeam(team) {
|
||||||
const constructs = team.constructs.map((c, i) => <GameConstruct key={c.id} construct={c} />);
|
const constructs = team.constructs.map(c =>
|
||||||
|
<GameConstruct key={c.id} construct={c} player={true} />);
|
||||||
return (
|
return (
|
||||||
<div className="team player">
|
<div className="team player">
|
||||||
{constructs}
|
{constructs}
|
||||||
@ -118,62 +114,9 @@ function GamePanel(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function OpponentConstruct(construct, i) {
|
|
||||||
const ko = construct.green_life.value === 0 ? 'ko' : '';
|
|
||||||
const classes = eventClasses(resolution, construct);
|
|
||||||
|
|
||||||
const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
|
|
||||||
<div key={j} alt={STATS[s].stat}>
|
|
||||||
{shapes[s]()}
|
|
||||||
<div className="max" >{construct[STATS[s].stat].value} / {construct[STATS[s].stat].max}</div>
|
|
||||||
<div className="value" >{construct[STATS[s].stat].value}</div>
|
|
||||||
</div>
|
|
||||||
));
|
|
||||||
|
|
||||||
const [combatText, combatClass] = getCombatText(construct, resolution);
|
|
||||||
const combatTextClass = `combat-text ${combatClass}`;
|
|
||||||
const combatTextEl = combatText
|
|
||||||
? <div className={combatTextClass}>{combatText}</div>
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const effects = construct.effects.length
|
|
||||||
? construct.effects.map(c => <div key={c.effect}>{c.effect} - {c.duration}T</div>)
|
|
||||||
: <div> </div>;
|
|
||||||
|
|
||||||
const playerTeamIds = playerTeam.constructs.map(c => c.id);
|
|
||||||
const targeting = game.stack
|
|
||||||
.filter(s => playerTeamIds.includes(s.source_construct_id) && s.target_construct_id === construct.id)
|
|
||||||
.map((s, i) => <h3 key={i}>{`< ${s.skill}`}</h3>);
|
|
||||||
|
|
||||||
// const anim = (
|
|
||||||
// <div className="anim-container">
|
|
||||||
// {animationDivs(combatClass)}
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={i}
|
|
||||||
className={`game-construct ${ko} ${classes}`}
|
|
||||||
style={ activeSkill ? { cursor: 'pointer' } : {}}
|
|
||||||
onClick={() => selectSkillTarget(construct.id)} >
|
|
||||||
<div className="stats">{stats}</div>
|
|
||||||
<h3 className="name" >{construct.name}</h3>
|
|
||||||
<div className="effects">{effects}</div>
|
|
||||||
<div className="targeting">{targeting}</div>
|
|
||||||
<figure
|
|
||||||
className="img"
|
|
||||||
onClick={() => selectSkillTarget(construct.id)} >
|
|
||||||
{constructAvatar(construct.name, construct.id)}
|
|
||||||
{combatTextEl}
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function OpponentTeam(team) {
|
function OpponentTeam(team) {
|
||||||
const constructs = team.constructs.map(OpponentConstruct);
|
const constructs = team.constructs.map(c =>
|
||||||
|
<GameConstruct key={c.id} construct={c} player={false} />);
|
||||||
return (
|
return (
|
||||||
<div className="team opponent">
|
<div className="team opponent">
|
||||||
{constructs}
|
{constructs}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ const preact = require('preact');
|
|||||||
const range = require('lodash/range');
|
const range = require('lodash/range');
|
||||||
|
|
||||||
const actions = require('../actions');
|
const actions = require('../actions');
|
||||||
const { STATS, eventClasses, getCombatText, constructAvatar } = require('../utils');
|
const { STATS, eventClasses, getCombatText, constructAvatar, constructHealth } = require('../utils');
|
||||||
const { animationDivs } = require('../animations');
|
const { animationDivs } = require('../animations');
|
||||||
const shapes = require('./shapes');
|
const shapes = require('./shapes');
|
||||||
|
|
||||||
@ -46,6 +46,7 @@ function GameConstruct(props) {
|
|||||||
game,
|
game,
|
||||||
account,
|
account,
|
||||||
construct,
|
construct,
|
||||||
|
player,
|
||||||
resolution,
|
resolution,
|
||||||
activeSkill,
|
activeSkill,
|
||||||
setActiveConstruct,
|
setActiveConstruct,
|
||||||
@ -54,18 +55,23 @@ function GameConstruct(props) {
|
|||||||
|
|
||||||
const ko = construct.green_life.value === 0 ? 'ko' : '';
|
const ko = construct.green_life.value === 0 ? 'ko' : '';
|
||||||
const classes = eventClasses(resolution, construct);
|
const classes = eventClasses(resolution, construct);
|
||||||
|
|
||||||
const skills = range(0, 3)
|
const life = constructHealth(resolution, construct);
|
||||||
.map(i => <SkillBtn key={i} construct={construct} i={i} />);
|
|
||||||
|
|
||||||
const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
|
const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
|
||||||
<div key={j} alt={STATS[s].stat}>
|
<div key={j} alt={STATS[s].stat}>
|
||||||
{shapes[s]()}
|
{shapes[s]()}
|
||||||
<div className="max" >{construct[STATS[s].stat].value} / {construct[STATS[s].stat].max}</div>
|
<div className="max" >{life[s]} / {construct[STATS[s].stat].max}</div>
|
||||||
<div className="value" >{construct[STATS[s].stat].value}</div>
|
<div className="value" >{life[s]}</div>
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
const skills = range(0, 3)
|
||||||
|
.map(i => <SkillBtn key={i} construct={construct} i={i} />);
|
||||||
|
|
||||||
|
let crypSkills = <div> </div>;
|
||||||
|
if (player) crypSkills = (<div className="skills"> {skills} </div>);
|
||||||
|
|
||||||
const [combatText, combatClass] = getCombatText(construct, resolution);
|
const [combatText, combatClass] = getCombatText(construct, resolution);
|
||||||
const combatTextClass = `combat-text ${combatClass}`;
|
const combatTextClass = `combat-text ${combatClass}`;
|
||||||
const combatTextEl = combatText
|
const combatTextEl = combatText
|
||||||
@ -93,30 +99,19 @@ function GameConstruct(props) {
|
|||||||
<div
|
<div
|
||||||
style={ activeSkill ? { cursor: 'pointer' } : {}}
|
style={ activeSkill ? { cursor: 'pointer' } : {}}
|
||||||
className={`game-construct ${ko} ${classes}`} >
|
className={`game-construct ${ko} ${classes}`} >
|
||||||
<h3 className="name">
|
<h3 className="name"> {construct.name} </h3>
|
||||||
{construct.name}
|
{crypSkills}
|
||||||
</h3>
|
<div className="targeting"> {targeting} </div>
|
||||||
<div className="skills">
|
<div className="stats"> {stats} </div>
|
||||||
{skills}
|
|
||||||
</div>
|
|
||||||
<div className="targeting">
|
|
||||||
{targeting}
|
|
||||||
</div>
|
|
||||||
<figure
|
<figure
|
||||||
className="img"
|
className="img"
|
||||||
onClick={() => selectSkillTarget(construct.id)} >
|
onClick={() => selectSkillTarget(construct.id)} >
|
||||||
{constructAvatar(construct.name, construct.id)}
|
{constructAvatar(construct.name, construct.id)}
|
||||||
{combatTextEl}
|
{combatTextEl}
|
||||||
{anim}
|
|
||||||
</figure>
|
</figure>
|
||||||
<div className="effects">
|
<div className="effects"> {effects} </div>
|
||||||
{effects}
|
|
||||||
</div>
|
|
||||||
<div className="stats">
|
|
||||||
{stats}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = addState(GameConstruct);
|
module.exports = addState(GameConstruct);
|
||||||
@ -3,7 +3,7 @@ const eachSeries = require('async/eachSeries');
|
|||||||
|
|
||||||
const actions = require('./actions');
|
const actions = require('./actions');
|
||||||
const { TIMES } = require('./constants');
|
const { TIMES } = require('./constants');
|
||||||
const { getCombatSequence, resoConstructHealth } = require('./utils');
|
const { getCombatSequence } = require('./utils');
|
||||||
|
|
||||||
function registerEvents(store) {
|
function registerEvents(store) {
|
||||||
|
|
||||||
@ -49,9 +49,6 @@ function registerEvents(store) {
|
|||||||
if (skip) return sCb();
|
if (skip) return sCb();
|
||||||
const stagedR = Object.create(r);
|
const stagedR = Object.create(r);
|
||||||
stagedR.stage = stage;
|
stagedR.stage = stage;
|
||||||
|
|
||||||
// Apply damage for each construct
|
|
||||||
if (stage === 'POST_SKILL') resoConstructHealth(stagedR, currentGame);
|
|
||||||
store.dispatch(actions.setResolution(stagedR));
|
store.dispatch(actions.setResolution(stagedR));
|
||||||
|
|
||||||
return setTimeout(sCb, TIMES[stage]);
|
return setTimeout(sCb, TIMES[stage]);
|
||||||
|
|||||||
@ -167,38 +167,71 @@ const STATS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function resoConstructHealth(resolution, currentGame) {
|
function constructHealth(resolution, construct) {
|
||||||
if (!resolution) return false;
|
if (!resolution) {
|
||||||
|
return {
|
||||||
|
RedLife: construct.red_life.value,
|
||||||
|
GreenLife: construct.green_life.value,
|
||||||
|
BlueLife: construct.blue_life.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const [type, event] = resolution.event;
|
||||||
|
|
||||||
const modifyHealth = construct => {
|
|
||||||
if (construct.id !== resolution.target.id) return false; // not target
|
if (construct.id !== resolution.target.id) {
|
||||||
const [type, event] = resolution.event;
|
if (construct.id === resolution.source.id) {
|
||||||
if (type === 'Damage') {
|
return {
|
||||||
const { amount, mitigation, colour } = event;
|
RedLife: resolution.source.red,
|
||||||
construct.green_life.value -= amount;
|
GreenLife: resolution.source.green,
|
||||||
if (colour === 'Red') {
|
BlueLife: resolution.source.blue,
|
||||||
construct.red_life.value -= mitigation;
|
};
|
||||||
}
|
|
||||||
if (colour === 'Blue') {
|
|
||||||
construct.blue_life.value -= mitigation;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
RedLife: construct.red_life.value,
|
||||||
|
GreenLife: construct.green_life.value,
|
||||||
|
BlueLife: construct.blue_life.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (type === 'Healing') {
|
let RedLife = resolution.target.red;
|
||||||
const { amount } = event;
|
let BlueLife = resolution.target.blue;
|
||||||
construct.green_life.value += amount;
|
let GreenLife = resolution.target.green;
|
||||||
|
|
||||||
|
if (resolution.stage === 'POST_SKILL') {
|
||||||
|
return { RedLife, GreenLife, BlueLife };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Damage') {
|
||||||
|
const { amount, mitigation, colour } = event;
|
||||||
|
|
||||||
|
GreenLife = construct.green_life.max < GreenLife + amount
|
||||||
|
? construct.green_life.max
|
||||||
|
: GreenLife + amount;
|
||||||
|
|
||||||
|
if (colour === 'Red') {
|
||||||
|
RedLife = construct.red_life.max < RedLife + mitigation
|
||||||
|
? construct.red_life.max
|
||||||
|
: RedLife + mitigation;
|
||||||
}
|
}
|
||||||
|
if (colour === 'Blue') {
|
||||||
if (type === 'Recharge') {
|
BlueLife = construct.blue_life.max < BlueLife + mitigation
|
||||||
const { red, blue } = event;
|
? construct.blue_life.max
|
||||||
construct.red_life.value += red;
|
: BlueLife + mitigation;
|
||||||
construct.blue_life.value += blue;
|
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
};
|
|
||||||
currentGame.players.forEach(player => player.constructs.forEach(modifyHealth));
|
|
||||||
return true;
|
|
||||||
|
|
||||||
|
if (type === 'Healing') {
|
||||||
|
const { amount } = event;
|
||||||
|
GreenLife = GreenLife - amount < 0 ? 0 : GreenLife - amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'Recharge') {
|
||||||
|
const { red, blue } = event;
|
||||||
|
RedLife = RedLife - red < 0 ? 0 : RedLife - red;
|
||||||
|
BlueLife = BlueLife - red < 0 ? 0 : BlueLife - blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { RedLife, GreenLife, BlueLife };
|
||||||
}
|
}
|
||||||
|
|
||||||
function eventClasses(resolution, construct) {
|
function eventClasses(resolution, construct) {
|
||||||
@ -306,8 +339,7 @@ function eventClasses(resolution, construct) {
|
|||||||
function getCombatSequence(event) {
|
function getCombatSequence(event) {
|
||||||
if (!event) return false;
|
if (!event) return false;
|
||||||
// Skip combat animations depending on event type, expandable in future
|
// Skip combat animations depending on event type, expandable in future
|
||||||
const dotTicks = ['DecayTick', 'CorruptionTick', 'TriageTick', 'SiphonTick', 'StrangleTick'];
|
if (['Inversion'].includes(event[0])) return false;
|
||||||
|
|
||||||
if (['Skill', 'AoeSkill'].includes(event[0])) return ['START_SKILL', 'END_SKILL'];
|
if (['Skill', 'AoeSkill'].includes(event[0])) return ['START_SKILL', 'END_SKILL'];
|
||||||
if (['Immunity'].includes(event[0])) return ['START_SKILL', 'POST_SKILL'];
|
if (['Immunity'].includes(event[0])) return ['START_SKILL', 'POST_SKILL'];
|
||||||
if (['Removal'].includes(event[0])) return ['POST_SKILL'];
|
if (['Removal'].includes(event[0])) return ['POST_SKILL'];
|
||||||
@ -334,7 +366,7 @@ function getCombatSequence(event) {
|
|||||||
if (['Ko'].includes(event[0])
|
if (['Ko'].includes(event[0])
|
||||||
|| (event[1].skill.includes('Throw') && event[1].effect === 'Vulnerable')) return ['POST_SKILL'];
|
|| (event[1].skill.includes('Throw') && event[1].effect === 'Vulnerable')) return ['POST_SKILL'];
|
||||||
|
|
||||||
if (dotTicks.includes(event[1].skill)) return ['END_SKILL', 'POST_SKILL'];
|
if (['Tick'].includes(event[1].skill)) return ['END_SKILL', 'POST_SKILL'];
|
||||||
return ['START_SKILL', 'END_SKILL', 'POST_SKILL'];
|
return ['START_SKILL', 'END_SKILL', 'POST_SKILL'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,7 +498,7 @@ module.exports = {
|
|||||||
eventClasses,
|
eventClasses,
|
||||||
getCombatSequence,
|
getCombatSequence,
|
||||||
getCombatText,
|
getCombatText,
|
||||||
resoConstructHealth,
|
constructHealth,
|
||||||
NULL_UUID,
|
NULL_UUID,
|
||||||
STATS,
|
STATS,
|
||||||
COLOURS,
|
COLOURS,
|
||||||
|
|||||||
@ -388,6 +388,9 @@ pub type Immunity = Vec<Effect>;
|
|||||||
pub struct LogConstruct {
|
pub struct LogConstruct {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub red: u64,
|
||||||
|
pub green: u64,
|
||||||
|
pub blue: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
|
||||||
@ -400,8 +403,20 @@ pub struct Resolution {
|
|||||||
impl Resolution {
|
impl Resolution {
|
||||||
fn new(source: &Construct, target: &Construct) -> Resolution {
|
fn new(source: &Construct, target: &Construct) -> Resolution {
|
||||||
Resolution {
|
Resolution {
|
||||||
source: LogConstruct { id: source.id, name: source.name.clone() },
|
source: LogConstruct {
|
||||||
target: LogConstruct { id: target.id, name: target.name.clone() },
|
id: source.id,
|
||||||
|
name: source.name.clone(),
|
||||||
|
red: source.red_life(),
|
||||||
|
green: source.green_life(),
|
||||||
|
blue: source.blue_life(),
|
||||||
|
},
|
||||||
|
target: LogConstruct {
|
||||||
|
id: target.id,
|
||||||
|
name: target.name.clone(),
|
||||||
|
red: target.red_life(),
|
||||||
|
green: target.green_life(),
|
||||||
|
blue: target.blue_life(),
|
||||||
|
},
|
||||||
event: Event::Incomplete,
|
event: Event::Incomplete,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1427,14 +1442,6 @@ impl Skill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn touch(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
|
||||||
target.deal_red_damage(skill, 0)
|
|
||||||
.into_iter()
|
|
||||||
.for_each(|e| results.push(Resolution::new(source, target).event(e)));
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn attack(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
fn attack(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
||||||
let amount = source.red_power().pct(skill.multiplier());
|
let amount = source.red_power().pct(skill.multiplier());
|
||||||
target.deal_red_damage(skill, amount)
|
target.deal_red_damage(skill, amount)
|
||||||
@ -1453,7 +1460,7 @@ fn strike(source: &mut Construct, target: &mut Construct, mut results: Resolutio
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn injure(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
/*fn injure(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
||||||
let amount = source.red_power().pct(skill.multiplier());
|
let amount = source.red_power().pct(skill.multiplier());
|
||||||
target.deal_red_damage(skill, amount)
|
target.deal_red_damage(skill, amount)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -1464,7 +1471,7 @@ fn injure(source: &mut Construct, target: &mut Construct, mut results: Resolutio
|
|||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
fn stun(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
fn stun(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
||||||
skill.effect().into_iter()
|
skill.effect().into_iter()
|
||||||
.for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e)))));
|
.for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e)))));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user