use common::util; use data::tables::{self, BattleEventConfigID, HollowQuestID}; use proto::{ DungeonInfo, DungeonItemData, FightQuestInfo, LongFightInfo, LongFightSceneInfo, SceneInfo, WeatherPoolInfo, }; use thiserror::Error; use crate::logic::{ battle::{ drop::FightDropPool, unit::{AvatarUnit, BuddyUnit}, BuddyParam, DungeonQuestManager, LogicVariableTable, TeamDataItem, }, BuddyTeamType, EHollowQuestType, ELocalPlayType, ESceneType, TimePeriodType, WeatherType, }; use super::NapGameMode; #[derive(Error, Debug)] pub enum LongFightGameError { #[error("Tried to run quest of type {0:?} using LongFight logic")] InvalidQuestType(EHollowQuestType), #[error("Battle group not found, quest id: {0}")] BattleGroupNotFound(u32), } pub struct LongFightGame { pub quest_id: u32, pub battle_event_id: BattleEventConfigID, pub play_type: ELocalPlayType, pub time_period: TimePeriodType, pub weather: WeatherType, pub start_timestamp: i64, pub team_data: TeamDataItem, pub variable_table: LogicVariableTable, pub fight_drop_pool: FightDropPool, pub quest_manager: DungeonQuestManager, } impl LongFightGame { const RALLY_GUIDANCE_BUDDY_ID: u32 = 50001; pub fn create_rally_game( quest_id: HollowQuestID, avatars: &[u32], buddy_id: u32, time_period: TimePeriodType, weather: WeatherType, ) -> Result { let template = quest_id.template(); let quest_type = EHollowQuestType::from(template.hollow_quest_type); if quest_type != EHollowQuestType::RallyBattle { return Err(LongFightGameError::InvalidQuestType(quest_type)); } let Some(battle_group) = tables::battle_group_config_template_tb::iter() .find(|tmpl| tmpl.quest_id == template.id.value()) else { return Err(LongFightGameError::BattleGroupNotFound(template.id.value())); }; let mut buddy_params = vec![BuddyParam( Self::RALLY_GUIDANCE_BUDDY_ID, BuddyTeamType::RallyGuidance, )]; if buddy_id != 0 { buddy_params.push(BuddyParam(buddy_id, BuddyTeamType::Fighting)); } Ok(Self { quest_id: template.id.value(), battle_event_id: battle_group.battle_event_id, play_type: ELocalPlayType::RallyLongFight, time_period, weather, start_timestamp: util::cur_timestamp() as i64, team_data: TeamDataItem::new(avatars, &buddy_params), variable_table: LogicVariableTable::new(battle_group.battle_event_id), fight_drop_pool: FightDropPool::new(battle_group.battle_event_id), quest_manager: DungeonQuestManager::new_for_battle_group(battle_group.id), }) } } impl NapGameMode for LongFightGame { fn scene_type(&self) -> ESceneType { ESceneType::LongFight } fn scene_info(&self) -> Option { Some(SceneInfo { scene_type: self.scene_type() as u32, battle_event_id: self.battle_event_id.value(), play_type: self.play_type as u32, long_fight_scene_info: Some(LongFightSceneInfo { fight_data: Some(LongFightInfo { fight_quest_info: Some(FightQuestInfo { fight_variable_map: self.variable_table.to_client(), ..Default::default() }), ..Default::default() }), fight_drop_info: Some(self.fight_drop_pool.to_client()), weather_pool: Some(WeatherPoolInfo { time_period: self.time_period.to_string(), weather: self.weather.to_string(), febgjinpcbp: true, bejeblcfcha: true, ..Default::default() }), ..Default::default() }), ..Default::default() }) } fn dungeon_info(&self) -> Option { Some(DungeonInfo { quest_id: self.quest_id, start_timestamp: self.start_timestamp, dungeon_item_data: Some(DungeonItemData::default()), avatar_list: self .team_data .avatar_member_list .iter() .map(AvatarUnit::to_client) .collect(), buddy_list: self .team_data .equipped_buddy_list .iter() .map(BuddyUnit::to_client) .collect(), dungeon_quest_info: Some(self.quest_manager.to_client()), ..Default::default() }) } }