use crate::{combat::DamageContributor, comp, uid::Uid, DamageSource, terrain::SpriteKind}; use comp::{beam, item::Reagent, poise::PoiseState, skillset::SkillGroupKind, UtteranceKind}; use hashbrown::HashSet; use serde::{Deserialize, Serialize}; use vek::*; #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct HealthChangeInfo { pub amount: f32, pub crit: bool, pub target: Uid, pub by: Option, pub cause: Option, pub instance: u64, } /// An outcome represents the final result of an instantaneous event. It implies /// that said event has already occurred. It is not a request for that event to /// occur, nor is it something that may be cancelled or otherwise altered. Its /// primary purpose is to act as something for frontends (both server and /// client) to listen to in order to receive feedback about events in the world. #[derive(Clone, Debug, Serialize, Deserialize)] pub enum Outcome { Explosion { pos: Vec3, power: f32, radius: f32, is_attack: bool, reagent: Option, // How can we better define this? }, Lightning { pos: Vec3, }, ProjectileShot { pos: Vec3, body: comp::Body, vel: Vec3, }, ProjectileHit { pos: Vec3, body: comp::Body, vel: Vec3, source: Option, target: Option, }, Beam { pos: Vec3, specifier: beam::FrontendSpecifier, }, ExpChange { uid: Uid, exp: u32, xp_pools: HashSet, }, SkillPointGain { uid: Uid, skill_tree: SkillGroupKind, total_points: u16, }, ComboChange { uid: Uid, combo: u32, }, BreakBlock { pos: Vec3, color: Option>, }, SummonedCreature { pos: Vec3, body: comp::Body, }, HealthChange { pos: Vec3, info: HealthChangeInfo, }, Death { pos: Vec3, }, Block { pos: Vec3, parry: bool, uid: Uid, }, PoiseChange { pos: Vec3, state: PoiseState, }, GroundSlam { pos: Vec3, }, IceSpikes { pos: Vec3, }, IceCrack { pos: Vec3, }, FlashFreeze { pos: Vec3, }, Utterance { pos: Vec3, body: comp::Body, kind: UtteranceKind, }, Glider { pos: Vec3, wielded: bool, }, SpriteDelete { pos: Vec3, sprite: SpriteKind, }, SpriteUnlocked { pos: Vec3, }, FailedSpriteUnlock { pos: Vec3, }, } impl Outcome { pub fn get_pos(&self) -> Option> { match self { Outcome::Explosion { pos, .. } // TODO: Include this, but allow it to be sent to clients when outside of the VD // | Outcome::Lightning { pos } | Outcome::ProjectileShot { pos, .. } | Outcome::ProjectileHit { pos, .. } | Outcome::Beam { pos, .. } | Outcome::SummonedCreature { pos, .. } | Outcome::HealthChange { pos, .. } | Outcome::Death { pos, .. } | Outcome::Block { pos, .. } | Outcome::PoiseChange { pos, .. } | Outcome::GroundSlam { pos } | Outcome::FlashFreeze { pos } | Outcome::IceSpikes { pos } | Outcome::IceCrack { pos } | Outcome::Utterance { pos, .. } | Outcome::SpriteDelete { pos, .. } | Outcome::Glider { pos, .. } => Some(*pos), Outcome::BreakBlock { pos, .. } | Outcome::SpriteUnlocked { pos } | Outcome::FailedSpriteUnlock { pos } => Some(pos.map(|e| e as f32 + 0.5)), Outcome::ExpChange { .. } | Outcome::ComboChange { .. } | Outcome::Lightning { .. } | Outcome::SkillPointGain { .. } => None, } } }