diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx
index abd1cb0d..248d3517 100644
--- a/client/src/animations.utils.jsx
+++ b/client/src/animations.utils.jsx
@@ -1,71 +1,66 @@
-function getObjects(resolution, game, account) {
- const [type, event] = resolution.variant;
-
+const direction = (game, account, source, target) => {
const playerTeam = game.players.find(t => t.id === account.id);
const playerTeamIds = playerTeam.constructs.map(c => c.id);
const otherTeam = game.players.find(t => t.id !== account.id);
const otherTeamIds = otherTeam.constructs.map(c => c.id);
- const sourceIsPlayer = playerTeamIds.includes(event.source);
- const targetIsPlayer = playerTeamIds.includes(resolution.target);
-
- const targetting = () => {
- if (type === 'AoeSkill') {
- if (targetIsPlayer) return playerTeamIds;
- return otherTeamIds;
- }
- return [resolution.target];
- };
+ const sourceIsPlayer = playerTeamIds.includes(source);
+ const targetIsPlayer = playerTeamIds.includes(target);
const sameTeam = (sourceIsPlayer && targetIsPlayer) || (!sourceIsPlayer && !targetIsPlayer);
let y = 0;
if (!sameTeam) y = targetIsPlayer ? 1 : -1;
const i = sourceIsPlayer
- ? playerTeamIds.findIndex(c => c === event.source)
- : otherTeamIds.findIndex(c => c === event.source);
+ ? playerTeamIds.findIndex(c => c === source)
+ : otherTeamIds.findIndex(c => c === source);
const j = targetIsPlayer
- ? playerTeamIds.findIndex(c => c === resolution.target)
- : otherTeamIds.findIndex(c => c === resolution.target);
+ ? playerTeamIds.findIndex(c => c === target)
+ : otherTeamIds.findIndex(c => c === target);
const x = j - i;
- const direction = { x, y };
- // const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds;
+ return { x, y };
+};
- const getFocusTargets = () => {
- if (type === 'HitCast') {
- const { source } = event;
- const { target } = resolution;
- if (source !== target) return [source, target];
- return [target];
- }
- if (type === 'AoeSkill') {
- if (targetIsPlayer) return playerTeamIds;
- return otherTeamIds;
- }
- return [resolution.target];
- };
+function getAnimSource(resolution, game, account) {
+ const { source, target } = resolution.cast;
const animSource = {
animation: 'sourceCast',
- constructId: event.source,
- direction,
+ constructId: source,
+ direction: direction(game, account, source, target),
};
+ return animSource;
+}
+function getAnimTarget(resolution, game, account) {
+ const { source, target, skill } = resolution.cast;
+ const player = resolution.cast.player === account;
const animTarget = {
- skill: event.skill,
- constructId: targetting(),
- player: playerTeamIds.includes(resolution.target),
- direction,
+ constructId: resolution.cast.target,
+ player,
+ direction: direction(game, account, source, target),
+ skill,
};
- return {
- animSource,
- animTarget,
- focusTargets: getFocusTargets(),
- skill: event.skill,
- };
+ return animTarget;
+}
+
+function getFocusTargets(resolution, game, account) {
+ if (resolution.variant[1] === 'AoeHit') {
+ const playerTeam = game.players.find(t => t.id === account.id);
+ const playerTeamIds = playerTeam.constructs.map(c => c.id);
+ const otherTeam = game.players.find(t => t.id !== account.id);
+ const otherTeamIds = otherTeam.constructs.map(c => c.id);
+ if (resolution.cast.player === account) return playerTeamIds;
+ return otherTeamIds;
+ }
+
+ const { source, target } = resolution.cast;
+ return [source, target];
}
module.exports = {
- getObjects,
+ getAnimSource,
+ getAnimTarget,
+ getFocusTargets,
};
diff --git a/client/src/components/anims/attack.jsx b/client/src/components/anims/attack.jsx
index 65756c1f..0f5dd317 100644
--- a/client/src/components/anims/attack.jsx
+++ b/client/src/components/anims/attack.jsx
@@ -46,8 +46,8 @@ class Attack extends Component {
y: [400, 200],
height: [100, 10, 0],
width: [12, 5, 0],
- delay: () => anime.random(TIMES.TARGET_DELAY_MS, TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS / 2),
- duration: TIMES.TARGET_DURATION_MS,
+ delay: () => anime.random(0, TIMES.TARGET_DURATION_MS / 4),
+ duration: TIMES.TARGET_DURATION_MS * 5 / 4,
}));
}
@@ -59,9 +59,7 @@ class Attack extends Component {
for (let i = this.animations.length - 1; i >= 0; i--) {
this.animations[i].reset();
}
- this.props.animCb && this.props.animCb();
}
-
}
module.exports = addState(Attack);
diff --git a/client/src/components/game.construct.anim.text.jsx b/client/src/components/game.construct.anim.text.jsx
index ad39219d..b54d9cd1 100644
--- a/client/src/components/game.construct.anim.text.jsx
+++ b/client/src/components/game.construct.anim.text.jsx
@@ -7,7 +7,7 @@ const shapes = require('./shapes');
const { removeTier } = require('../utils');
const { TIMES } = require('./../constants');
-const addState = connect(({ animText, animSkill, itemInfo }) => ({ animText, animSkill, itemInfo }));
+const addState = connect(({ animText, itemInfo }) => ({ animText, itemInfo }));
class AnimText extends preact.Component {
shouldComponentUpdate(newProps) {
@@ -17,7 +17,7 @@ class AnimText extends preact.Component {
componentDidUpdate(prevProps) {
const { animText, construct } = this.props;
- if (animText && animText !== prevProps.animText && animText.target === construct.id) {
+ if (animText && animText !== prevProps.animText && animText.variant[1].target === construct.id) {
anime({
targets: '.combat-text',
top: '40%',
@@ -28,10 +28,10 @@ class AnimText extends preact.Component {
}
render() {
- const { construct, animText, animSkill, itemInfo } = this.props;
- if (animText && animText.target === construct.id) {
+ const { construct, animText, itemInfo } = this.props;
+ if (animText && animText.variant[1].target === construct.id) {
const itemSourceDescription = () => {
- const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animSkill));
+ const itemSource = itemInfo.combos.filter(c => c.item === removeTier(animText.cast.skill));
const itemSourceInfo = itemSource.length
? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}`
: false;
@@ -82,7 +82,7 @@ class AnimText extends preact.Component {
return (
-
{animSkill}
+ {animText.cast.skill}
{itemSourceDescription()}
{generateAnimText()}
diff --git a/client/src/components/game.construct.effect.box.jsx b/client/src/components/game.construct.effect.box.jsx
index a6215475..598c2ae8 100644
--- a/client/src/components/game.construct.effect.box.jsx
+++ b/client/src/components/game.construct.effect.box.jsx
@@ -21,11 +21,10 @@ const addState = connect(
class GameConstructEffects extends preact.Component {
shouldComponentUpdate(newProps) {
- if (newProps.animText !== this.props.animText) {
- if (newProps.animText && newProps.animText.constructId === this.props.construct.id) {
- const [type] = newProps.animText.variant;
- if (type === 'Effect' || type === 'Removal') return true;
- }
+ if (newProps.animText && newProps.animText !== this.props.animText) {
+ const [type, info] = newProps.animText.variant;
+ if (info.target === this.props.construct.id
+ && (type === 'Effect' || type === 'Removal')) return true;
}
if (newProps.construct !== this.props.construct) return true;
return false;
diff --git a/client/src/components/game.construct.life.jsx b/client/src/components/game.construct.life.jsx
index 680f657c..fe2f76a1 100644
--- a/client/src/components/game.construct.life.jsx
+++ b/client/src/components/game.construct.life.jsx
@@ -7,11 +7,10 @@ const addState = connect(({ animText }) => ({ animText }));
class GameConstructLife extends preact.Component {
shouldComponentUpdate(newProps) {
- if (newProps.animText !== this.props.animText) {
- if (newProps.animText && newProps.animText.target === this.props.construct.id) {
- const [type] = newProps.animText.variant;
- if (type === 'Damage' || type === 'Healing' || type === 'Recharge') return true;
- }
+ if (newProps.animText && newProps.animText !== this.props.animText) {
+ const [type, info] = newProps.animText.variant;
+ if (info.target === this.props.construct.id
+ && (type === 'Damage' || type === 'Healing' || type === 'Recharge')) return true;
}
if (newProps.construct !== this.props.construct) return true;
return false;
diff --git a/client/src/events.jsx b/client/src/events.jsx
index ca91776d..ba78e4d2 100644
--- a/client/src/events.jsx
+++ b/client/src/events.jsx
@@ -5,7 +5,7 @@ const eachSeries = require('async/eachSeries');
const sample = require('lodash/sample');
const actions = require('./actions');
-const animations = require('./animations.utils');
+const { getAnimSource, getAnimTarget, getFocusTargets } = require('./animations.utils');
const { infoToast, errorToast } = require('./utils');
const { tutorialVbox } = require('./tutorial.utils');
const { TIMES } = require('./constants');
@@ -90,24 +90,19 @@ function registerEvents(store) {
const newRes = game.events[currentGame.events.length];
return eachSeries(newRes, (r, cb) => {
const timeout = r.delay;
+ const focusTargets = getFocusTargets(r, game, account);
+ store.dispatch(actions.setAnimFocus(focusTargets));
- if (r.variant[0].includes('Hit')) {
- let animTimeOut = TIMES.TARGET_DURATION_MS;
- const anims = animations.getObjects(r, game, account);
-
- if (r.variant[0] === 'HitCast') {
- animTimeOut += TIMES.TARGET_DELAY_MS;
- store.dispatch(actions.setAnimSource(anims.animSource));
- }
-
- store.dispatch(actions.setAnimFocus(anims.focusTargets));
- store.dispatch(actions.setAnimSkill(anims.skill));
- store.dispatch(actions.setAnimTarget(anims.animTarget));
+ if (r.variant[0] === 'Cast') {
+ const animSource = getAnimSource(r, game, account);
+ store.dispatch(actions.setAnimSource(animSource));
store.dispatch(actions.setAnimText(null));
- setTimeout(() => {
- store.dispatch(actions.setAnimSource(null));
- store.dispatch(actions.setAnimTarget(null));
- }, animTimeOut);
+ setTimeout(() => store.dispatch(actions.setAnimSource(null)), TIMES.SOURCE_DURATION_MS);
+ } else if (r.variant[0].includes('Hit')) {
+ const animTarget = getAnimTarget(r, game, account);
+ store.dispatch(actions.setAnimTarget(animTarget));
+ store.dispatch(actions.setAnimText(null));
+ setTimeout(() => store.dispatch(actions.setAnimTarget(null)), TIMES.TARGET_DURATION_MS);
} else {
store.dispatch(actions.setAnimText(r));
}
diff --git a/core/src/construct.rs b/core/src/construct.rs
index 937a377f..84f1b9e2 100644
--- a/core/src/construct.rs
+++ b/core/src/construct.rs
@@ -423,11 +423,11 @@ impl Construct {
match skill.cd {
Some(cd) => {
skill.cd = Some(cd.saturating_add(turns));
- events.push(EventVariant::CooldownIncrease { turns, skill: skill.skill })
+ events.push(EventVariant::CooldownIncrease { target: self.id, turns })
},
None => {
skill.cd = Some(turns);
- events.push(EventVariant::CooldownIncrease { turns, skill: skill.skill })
+ events.push(EventVariant::CooldownIncrease { target: self.id, turns })
},
}
}
@@ -548,7 +548,7 @@ impl Construct {
pub fn recharge(&mut self, red_amount: usize, blue_amount: usize) -> Vec {
let mut events = vec![];
-
+ let target = self.id;
if self.is_ko() { return events; }
match self.affected(Effect::Invert) {
@@ -565,7 +565,7 @@ impl Construct {
let blue = new_blue_life - current_blue_life;
if red != 0 || blue != 0 {
- events.push(EventVariant::Recharge { red, blue });
+ events.push(EventVariant::Recharge { target, red, blue });
}
},
true => {
@@ -592,6 +592,7 @@ impl Construct {
let red_damage_amount = red_current_green_life - self.green_life();
events.push(EventVariant::Damage {
+ target,
amount: red_damage_amount,
mitigation: red_mitigation,
colour: Colour::Red,
@@ -621,6 +622,7 @@ impl Construct {
let blue_damage_amount = blue_current_green_life - self.green_life();
events.push(EventVariant::Damage {
+ target,
amount: blue_damage_amount,
mitigation: blue_mitigation,
colour: Colour::Blue,
@@ -635,6 +637,7 @@ impl Construct {
pub fn deal_green_damage(&mut self, amount: usize) -> Vec {
let mut events = vec![];
if self.is_ko() { return events; }
+ let target = self.id;
let mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::GreenDamageTaken))
@@ -654,6 +657,7 @@ impl Construct {
let overhealing = modified_power - healing;
events.push(EventVariant::Healing {
+ target,
amount: healing,
overhealing,
});
@@ -667,6 +671,7 @@ impl Construct {
let delta = current_green_life - self.green_life();
events.push(EventVariant::Damage {
+ target,
amount: delta,
mitigation: 0,
colour: Colour::Green,
@@ -682,6 +687,7 @@ impl Construct {
let mut events = vec![];
if self.is_ko() { return events; }
+ let target = self.id;
let mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::RedDamageTaken))
@@ -710,6 +716,7 @@ impl Construct {
events.push(
EventVariant::Damage {
+ target,
amount: delta,
mitigation,
colour: Colour::Red,
@@ -717,7 +724,7 @@ impl Construct {
}
);
if self.is_ko() {
- events.push(EventVariant::Ko {});
+ events.push(EventVariant::Ko { target });
}
},
true => {
@@ -736,6 +743,7 @@ impl Construct {
if healing > 0 {
events.push(
EventVariant::Healing {
+ target,
amount: healing,
overhealing: overhealing - recharge,
}
@@ -743,7 +751,7 @@ impl Construct {
}
if recharge > 0 {
- events.push(EventVariant::Recharge { red: recharge, blue: 0 });
+ events.push(EventVariant::Recharge { target, red: recharge, blue: 0 });
}
}
};
@@ -755,6 +763,7 @@ impl Construct {
let mut events = vec![];
if self.is_ko() { return events; }
+ let target = self.id;
let mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::BlueDamageTaken))
@@ -778,6 +787,7 @@ impl Construct {
let delta = current_green_life - self.green_life();
events.push(EventVariant::Damage {
+ target,
amount: delta,
mitigation,
colour: Colour::Blue,
@@ -798,11 +808,11 @@ impl Construct {
let recharge = self.blue_life.value - current_life;
if healing > 0 {
- events.push(EventVariant::Healing { amount: healing, overhealing });
+ events.push(EventVariant::Healing { target, amount: healing, overhealing });
}
if recharge > 0 {
- events.push(EventVariant::Recharge { red: 0, blue: recharge });
+ events.push(EventVariant::Recharge { target, red: 0, blue: recharge });
}
}
};
@@ -828,6 +838,7 @@ impl Construct {
// todo modified durations cause of buffs
let result = EventVariant::Effect {
+ target: self.id,
effect: effect.effect,
duration: effect.duration,
display: EventConstruct::new(self)
diff --git a/core/src/game.rs b/core/src/game.rs
index effe4285..f351a70d 100644
--- a/core/src/game.rs
+++ b/core/src/game.rs
@@ -41,7 +41,7 @@ pub enum Colour {
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub enum Action {
Hit { cast: Cast },
- HitCast { cast: Cast },
+ Cast { cast: Cast },
Damage { cast: Cast, construct: Uuid, values: Vec, colour: Colour },
Effect { cast: Cast, construct: Uuid, effect: ConstructEffect },
IncreaseCooldowns { cast: Cast, construct: Uuid, turns: usize },
@@ -507,7 +507,7 @@ impl Game {
for action in actions {
match action {
Action::Hit { cast } => self.hit(cast),
- Action::HitCast { cast } => self.hit_cast(cast),
+ Action::Cast { cast } => self.cast(cast),
Action::Damage { cast, construct, values, colour } => self.damage(cast, construct, values, colour),
Action::Effect { cast, construct, effect } => self.effect(cast, construct, effect),
Action::IncreaseCooldowns { cast, construct, turns } => self.increase_cooldowns(cast, construct, turns),
@@ -517,8 +517,8 @@ impl Game {
self
}
- fn hit_cast(&mut self, cast: Cast) -> &mut Game {
- self.event_add(vec![EventVariant::HitCast()], cast);
+ fn cast(&mut self, cast: Cast) -> &mut Game {
+ self.event_add(vec![EventVariant::Cast()], cast);
self
}
diff --git a/core/src/skill.rs b/core/src/skill.rs
index 298c762f..a8b1db8f 100644
--- a/core/src/skill.rs
+++ b/core/src/skill.rs
@@ -109,10 +109,13 @@ impl Cast {
}
pub fn actions(&self) -> Vec {
- let mut actions = match self.skill.is_tick() {
- false => vec![Action::HitCast { cast: *self } ],
- true => vec![Action::Hit { cast: *self } ]
- };
+ let mut actions = vec![];
+
+ if self.skill.cast_animation() {
+ actions.push(Action::Cast { cast: *self });
+ }
+
+ actions.push(Action::Hit { cast: *self });
let mut rest = match self.skill {
Skill::Amplify => vec![
@@ -234,29 +237,23 @@ pub struct Event {
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub enum EventVariant {
+ Cast (),
Hit (),
- HitCast (),
+ HitAoe (),
- Damage { amount: usize, mitigation: usize, colour: Colour, display: EventConstruct },
- Effect { effect: Effect, duration: u8, display: EventConstruct },
- Removal { effect: Option, display: EventConstruct },
+ Damage { target: Uuid, amount: usize, mitigation: usize, colour: Colour, display: EventConstruct },
+ Effect { target: Uuid, effect: Effect, duration: u8, display: EventConstruct },
+ Removal { target: Uuid, effect: Option, display: EventConstruct },
- Healing { amount: usize, overhealing: usize },
- Recharge { red: usize, blue: usize },
- Inversion { skill: Skill },
- Reflection { skill: Skill },
- AoeSkill { skill: Skill },
- Skill { skill: Skill },
- TargetKo { skill: Skill },
- // skill not necessary but makes it neater as all events are arrays in js
- Ko (),
+ Healing { target: Uuid, amount: usize, overhealing: usize },
+ Recharge { target: Uuid, red: usize, blue: usize },
+ Inversion { target: Uuid },
+ Reflection { target: Uuid },
+ Ko { target: Uuid },
+
+ CooldownIncrease { target: Uuid, turns: usize },
+ CooldownDecrease { target: Uuid, turns: usize },
Forfeit (),
- Incomplete (),
- // not used
- Evasion { skill: Skill, evasion_rating: usize },
-
- CooldownIncrease { turns: usize, skill: Skill },
- CooldownDecrease { turns: usize, skill: Skill },
}
impl EventVariant {
@@ -269,7 +266,7 @@ impl EventVariant {
match self {
EventVariant::Hit() => target_duration - combat_text_overlap,
- EventVariant::HitCast() => target_delay + target_duration - combat_text_overlap,
+ EventVariant::Cast() => target_delay,
_ => combat_text_delay,
}
}
@@ -1053,6 +1050,24 @@ impl Skill {
}
}
+ pub fn cast_animation(&self) -> bool {
+ match self {
+ Skill::ElectrocuteTick |
+ Skill::ElectrocuteTickPlus |
+ Skill::ElectrocuteTickPlusPlus |
+ Skill::DecayTick |
+ Skill::DecayTickPlus |
+ Skill::DecayTickPlusPlus |
+ Skill::SiphonTick |
+ Skill::SiphonTickPlus |
+ Skill::SiphonTickPlusPlus |
+ Skill::TriageTick |
+ Skill::TriageTickPlus |
+ Skill::TriageTickPlusPlus => false,
+ _ => true
+ }
+ }
+
pub fn defensive(&self) -> bool {
match self {
Skill::Amplify|
@@ -1568,7 +1583,20 @@ mod tests {
let cast = Cast::new(Uuid::new_v4(), Uuid::new_v4(), Uuid::new_v4(), Skill::Attack);
let actions = cast.actions();
-
+ match actions[0] {
+ Action::Hit { cast } => {
+ assert_eq!(cast.skill, Skill::Attack);
+ },
+ _ => panic!("{:?}", actions),
+ };
+
+ match actions[1] {
+ Action::Damage { cast: _, construct: _, values: _, colour } => {
+ assert_eq!(colour, Colour::Red);
+ },
+ _ => panic!("{:?}", actions),
+ };
+
}
// #[test]