use titan::{ByteStreamWriter, Result}; use crate::battle::logic_game_object::{LogicGameObject, LogicVector2}; pub const DIRECTION_TOP: i32 = 256; pub const DIRECTION_BOTTOM: i32 = -256; pub const DEFAULT_SIZE: i32 = 100; pub const SUMMONER_HAND_SIZE: usize = 4; #[derive(Debug, Clone, PartialEq, Eq)] pub struct LogicCharacter { pub level_index: i32, pub is_destroyed: bool, pub is_leader: bool, pub base: LogicGameObject, pub direction: LogicVector2, pub state: i32, pub size: i32, pub growth_timer: i32, pub spawn_timer: i32, pub field_120: i32, pub remaining_spawn_count: i32, pub destruction_wave_timer: i32, pub lane_id: i32, pub deploy_timer: i32, pub hide_timer: i32, pub field_100: i32, pub pending_physical_damage: i32, pub mana_generate_limit: Option, pub reload: Option<(i32, i32)>, } impl Default for LogicCharacter { fn default() -> Self { Self { level_index: 0, is_destroyed: false, is_leader: false, base: LogicGameObject::default(), direction: LogicVector2::new(0, DIRECTION_BOTTOM), state: 0, size: DEFAULT_SIZE, growth_timer: 0, spawn_timer: 0, field_120: 0, remaining_spawn_count: 0, destruction_wave_timer: 0, lane_id: 0, deploy_timer: 0, hide_timer: 0, field_100: 0, pending_physical_damage: 0, mana_generate_limit: None, reload: None, } } } impl LogicCharacter { pub fn encode(&self, writer: &mut ByteStreamWriter) -> Result<()> { writer.write_vint(self.level_index); writer.write_boolean(self.is_destroyed); writer.write_boolean(self.is_leader); self.base.encode_base(writer)?; writer.write_vint(self.direction.x); writer.write_vint(self.direction.y); writer.write_vint(self.state); writer.write_vint(self.size); writer.write_vint(self.growth_timer); writer.write_vint(self.spawn_timer); writer.write_vint(self.field_120); writer.write_vint(self.remaining_spawn_count); writer.write_vint(self.destruction_wave_timer); writer.write_vint(self.lane_id); writer.write_vint(self.deploy_timer); writer.write_vint(self.hide_timer); writer.write_vint(self.field_100); writer.write_vint(self.pending_physical_damage); if let Some(limit) = self.mana_generate_limit { writer.write_vint(limit); } if let Some((timer, hits)) = self.reload { writer.write_vint(timer); writer.write_vint(hits); } Ok(()) } } #[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct LogicSummoner { pub character: LogicCharacter, pub deck: Option, pub mana_regen_timer: i32, pub mana: i32, pub field_244: i32, pub field_256: i32, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct LogicSummonerDeck { pub field_220: i32, pub hand: [i32; SUMMONER_HAND_SIZE], pub draw_pile: Vec, pub used_pile: Vec, pub last_used_index: i32, pub spell_cooldown: i32, pub field_240: i32, } impl Default for LogicSummonerDeck { fn default() -> Self { Self { field_220: 0, hand: [-1; SUMMONER_HAND_SIZE], draw_pile: Vec::new(), used_pile: Vec::new(), last_used_index: -1, spell_cooldown: 0, field_240: 0, } } } impl LogicSummonerDeck { pub fn starting(slot_count: usize) -> Self { let mut hand = [-1; SUMMONER_HAND_SIZE]; for (slot, index) in hand.iter_mut().zip(0..slot_count as i32) { *slot = index; } Self { hand, draw_pile: (SUMMONER_HAND_SIZE as i32..slot_count as i32).collect(), ..Self::default() } } } impl LogicSummoner { pub fn encode(&self, writer: &mut ByteStreamWriter) -> Result<()> { self.character.encode(writer)?; match &self.deck { None => writer.write_boolean(false), Some(deck) => { writer.write_boolean(true); writer.write_vint(deck.field_220); for slot in deck.hand { writer.write_vint(slot); } writer.write_vint(deck.draw_pile.len() as i32); for value in &deck.draw_pile { writer.write_vint(*value); } writer.write_vint(deck.used_pile.len() as i32); for value in &deck.used_pile { writer.write_vint(*value); } writer.write_vint(deck.last_used_index); writer.write_vint(deck.spell_cooldown); writer.write_vint(deck.field_240); } } writer.write_vint(self.mana_regen_timer); writer.write_vint(self.mana); writer.write_vint(self.field_244); writer.write_vint(self.field_256); Ok(()) } }