From 23e9870d8f6aba2c6fb2dfb5b575b639e1a048a5 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 31 May 2019 11:52:30 +1000 Subject: [PATCH] rework damage calculation between resolutions --- client/src/components/game.component.jsx | 65 ++--------------- client/src/components/game.construct.jsx | 43 +++++------ client/src/events.jsx | 5 +- client/src/utils.jsx | 92 ++++++++++++++++-------- server/src/skill.rs | 31 ++++---- 5 files changed, 105 insertions(+), 131 deletions(-) diff --git a/client/src/components/game.component.jsx b/client/src/components/game.component.jsx index fe110229..a7f60dcf 100644 --- a/client/src/components/game.component.jsx +++ b/client/src/components/game.component.jsx @@ -1,18 +1,14 @@ const preact = require('preact'); -const { STATS, eventClasses, getCombatText, constructAvatar } = require('../utils'); // const { animationDivs } = require('../animations'); const GameConstruct = require('./game.construct'); -const shapes = require('./shapes'); function GamePanel(props) { const { game, account, resolution, - activeSkill, setActiveSkill, setActiveConstruct, - selectSkillTarget, sendInstanceState, sendGameReady, showLog, @@ -109,8 +105,8 @@ function GamePanel(props) { ); function PlayerTeam(team) { - const constructs = team.constructs.map((c, i) => ); - + const constructs = team.constructs.map(c => + ); return (
{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) => ( -
- {shapes[s]()} -
{construct[STATS[s].stat].value} / {construct[STATS[s].stat].max}
-
{construct[STATS[s].stat].value}
-
- )); - - const [combatText, combatClass] = getCombatText(construct, resolution); - const combatTextClass = `combat-text ${combatClass}`; - const combatTextEl = combatText - ?
{combatText}
- : null; - - const effects = construct.effects.length - ? construct.effects.map(c =>
{c.effect} - {c.duration}T
) - :
 
; - - 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) =>

{`< ${s.skill}`}

); - - // const anim = ( - //
- // {animationDivs(combatClass)} - //
- // ); - - return ( -
selectSkillTarget(construct.id)} > -
{stats}
-

{construct.name}

-
{effects}
-
{targeting}
-
selectSkillTarget(construct.id)} > - {constructAvatar(construct.name, construct.id)} - {combatTextEl} -
-
- ); - } - - function OpponentTeam(team) { - const constructs = team.constructs.map(OpponentConstruct); + const constructs = team.constructs.map(c => + ); return (
{constructs} diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index a12d231f..fa90a8c8 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -3,7 +3,7 @@ const preact = require('preact'); const range = require('lodash/range'); const actions = require('../actions'); -const { STATS, eventClasses, getCombatText, constructAvatar } = require('../utils'); +const { STATS, eventClasses, getCombatText, constructAvatar, constructHealth } = require('../utils'); const { animationDivs } = require('../animations'); const shapes = require('./shapes'); @@ -46,6 +46,7 @@ function GameConstruct(props) { game, account, construct, + player, resolution, activeSkill, setActiveConstruct, @@ -54,18 +55,23 @@ function GameConstruct(props) { const ko = construct.green_life.value === 0 ? 'ko' : ''; const classes = eventClasses(resolution, construct); - - const skills = range(0, 3) - .map(i => ); - + + const life = constructHealth(resolution, construct); const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
{shapes[s]()} -
{construct[STATS[s].stat].value} / {construct[STATS[s].stat].max}
-
{construct[STATS[s].stat].value}
+
{life[s]} / {construct[STATS[s].stat].max}
+
{life[s]}
)); + + const skills = range(0, 3) + .map(i => ); + + let crypSkills =
 
; + if (player) crypSkills = (
{skills}
); + const [combatText, combatClass] = getCombatText(construct, resolution); const combatTextClass = `combat-text ${combatClass}`; const combatTextEl = combatText @@ -93,30 +99,19 @@ function GameConstruct(props) {
-

- {construct.name} -

-
- {skills} -
-
- {targeting} -
+

{construct.name}

+ {crypSkills} +
{targeting}
+
{stats}
selectSkillTarget(construct.id)} > {constructAvatar(construct.name, construct.id)} {combatTextEl} - {anim}
-
- {effects} -
-
- {stats} -
+
{effects}
); } -module.exports = addState(GameConstruct); +module.exports = addState(GameConstruct); \ No newline at end of file diff --git a/client/src/events.jsx b/client/src/events.jsx index c0dcd3f2..411d6b7b 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -3,7 +3,7 @@ const eachSeries = require('async/eachSeries'); const actions = require('./actions'); const { TIMES } = require('./constants'); -const { getCombatSequence, resoConstructHealth } = require('./utils'); +const { getCombatSequence } = require('./utils'); function registerEvents(store) { @@ -49,9 +49,6 @@ function registerEvents(store) { if (skip) return sCb(); const stagedR = Object.create(r); stagedR.stage = stage; - - // Apply damage for each construct - if (stage === 'POST_SKILL') resoConstructHealth(stagedR, currentGame); store.dispatch(actions.setResolution(stagedR)); return setTimeout(sCb, TIMES[stage]); diff --git a/client/src/utils.jsx b/client/src/utils.jsx index 004a419d..b4f26ee2 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -167,38 +167,71 @@ const STATS = { }; -function resoConstructHealth(resolution, currentGame) { - if (!resolution) return false; +function constructHealth(resolution, construct) { + 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 - const [type, event] = resolution.event; - if (type === 'Damage') { - const { amount, mitigation, colour } = event; - construct.green_life.value -= amount; - if (colour === 'Red') { - construct.red_life.value -= mitigation; - } - if (colour === 'Blue') { - construct.blue_life.value -= mitigation; - } + + if (construct.id !== resolution.target.id) { + if (construct.id === resolution.source.id) { + return { + RedLife: resolution.source.red, + GreenLife: resolution.source.green, + BlueLife: resolution.source.blue, + }; } + return { + RedLife: construct.red_life.value, + GreenLife: construct.green_life.value, + BlueLife: construct.blue_life.value, + }; + } - if (type === 'Healing') { - const { amount } = event; - construct.green_life.value += amount; + let RedLife = resolution.target.red; + let BlueLife = resolution.target.blue; + 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 (type === 'Recharge') { - const { red, blue } = event; - construct.red_life.value += red; - construct.blue_life.value += blue; + if (colour === 'Blue') { + BlueLife = construct.blue_life.max < BlueLife + mitigation + ? construct.blue_life.max + : BlueLife + mitigation; } - 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) { @@ -306,8 +339,7 @@ function eventClasses(resolution, construct) { function getCombatSequence(event) { if (!event) return false; // 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 (['Immunity'].includes(event[0])) return ['START_SKILL', 'POST_SKILL']; if (['Removal'].includes(event[0])) return ['POST_SKILL']; @@ -334,7 +366,7 @@ function getCombatSequence(event) { if (['Ko'].includes(event[0]) || (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']; } @@ -466,7 +498,7 @@ module.exports = { eventClasses, getCombatSequence, getCombatText, - resoConstructHealth, + constructHealth, NULL_UUID, STATS, COLOURS, diff --git a/server/src/skill.rs b/server/src/skill.rs index e2c4d6a4..5019030c 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -388,6 +388,9 @@ pub type Immunity = Vec; pub struct LogConstruct { pub id: Uuid, pub name: String, + pub red: u64, + pub green: u64, + pub blue: u64, } #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] @@ -400,8 +403,20 @@ pub struct Resolution { impl Resolution { fn new(source: &Construct, target: &Construct) -> Resolution { Resolution { - source: LogConstruct { id: source.id, name: source.name.clone() }, - target: LogConstruct { id: target.id, name: target.name.clone() }, + source: LogConstruct { + 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, } } @@ -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 { let amount = source.red_power().pct(skill.multiplier()); target.deal_red_damage(skill, amount) @@ -1453,7 +1460,7 @@ fn strike(source: &mut Construct, target: &mut Construct, mut results: Resolutio 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()); target.deal_red_damage(skill, amount) .into_iter() @@ -1464,7 +1471,7 @@ fn injure(source: &mut Construct, target: &mut Construct, mut results: Resolutio return results; } - +*/ fn stun(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { skill.effect().into_iter() .for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e)))));