use titan::Payload; use crate::battle::logic_game_object_ref::LogicGameObjectRef; use crate::data::LogicDataRef; pub const COMPONENT_PASSES: usize = 4; pub const OBJECT_TYPE_COUNT: usize = 6; pub const CHARACTER_OBJECT_TYPE: i32 = 5; #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Payload)] pub struct LogicVector2 { #[codec(vint)] pub x: i32, #[codec(vint)] pub y: i32, } impl LogicVector2 { pub fn new(x: i32, y: i32) -> Self { Self { x, y } } } #[derive(Debug, Default, Clone, PartialEq, Eq, Payload)] pub struct LogicGameObject { #[codec(vint)] pub owner_index: i32, #[codec(vint)] pub component_mask: i32, pub position: LogicVector2, #[codec(vint)] pub z: i32, } impl LogicGameObject { pub fn encode_base(&self, writer: &mut titan::ByteStreamWriter) -> titan::Result<()> { ::encode(self, writer) } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum LogicObjectBody { Character(Box), Summoner(Box), } impl LogicObjectBody { pub fn base_mut(&mut self) -> &mut LogicGameObject { match self { LogicObjectBody::Character(character) => &mut character.base, LogicObjectBody::Summoner(summoner) => &mut summoner.character.base, } } pub fn encode(&self, writer: &mut titan::ByteStreamWriter) -> titan::Result<()> { match self { LogicObjectBody::Character(character) => character.encode(writer), LogicObjectBody::Summoner(summoner) => summoner.encode(writer), } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct LogicGameObjectEntry { pub data: LogicDataRef, pub global_id: LogicGameObjectRef, pub body: LogicObjectBody, pub components: [Option; COMPONENT_PASSES], } impl LogicGameObjectEntry { pub fn hitpoints(&self) -> Option { match self .components .get(crate::battle::logic_component::COMPONENT_HITPOINT)? .as_ref()? { crate::battle::logic_component::LogicComponent::Hitpoint(component) => { Some(component.hitpoints) } _ => None, } } pub fn is_alive(&self) -> bool { self.hitpoints().map(|value| value > 0).unwrap_or(false) } pub fn new( data: LogicDataRef, global_id: LogicGameObjectRef, mut body: LogicObjectBody, components: [Option; COMPONENT_PASSES], ) -> Self { let mut component_mask = 0; for (index, component) in components.iter().enumerate() { if component.is_some() { component_mask |= 1 << index; } } body.base_mut().component_mask = component_mask; Self { data, global_id, body, components, } } pub fn object_type(&self) -> i32 { self.global_id.0.map(|id| id.class_id - 1).unwrap_or(-1) } }