HollowPS/gameserver/src/net/handlers/hollow.rs

329 lines
10 KiB
Rust

use itertools::Itertools;
use qwer::{phashmap, phashset, PropertyHashMap, PropertyHashSet};
use std::collections::HashMap;
use crate::data;
use super::*;
pub async fn on_rpc_hollow_move_arg(
session: &mut NetworkSession,
arg: &RpcHollowMoveArg,
) -> Result<()> {
tracing::info!("Hollow movement {:?}", &arg);
let destination_pos = *arg.positions.last().unwrap();
let scene_uid = session.get_player().scene_uid.unwrap();
let hollow_grid_manager = session.context.hollow_grid_manager.borrow();
let (ptc_hollow_grid, ptc_sync_hollow_event) =
hollow_grid_manager.move_to(destination_pos, scene_uid);
session.send_rpc_arg(114, &ptc_hollow_grid).await?;
if let Some(ptc_sync_hollow_event) = ptc_sync_hollow_event {
session.send_rpc_arg(210, &ptc_sync_hollow_event).await?;
}
let pos = PtcPositionInHollowChangedArg {
player_uid: 1337,
hollow_level: arg.hollow_level,
position: destination_pos,
};
session.send_rpc_arg(141, &pos).await?;
session
.send_rpc_ret(RpcHollowMoveRet::new(
arg.hollow_level,
*arg.positions.last().unwrap(),
))
.await
}
pub async fn on_rpc_end_battle_arg(session: &NetworkSession, arg: &RpcEndBattleArg) -> Result<()> {
tracing::info!("RpcEndBattle: {:?}", &arg);
let player_uid = session.get_player_uid();
let hollow_grid_manager = session.context.hollow_grid_manager.borrow();
let (sync_event, hollow_finished) = hollow_grid_manager.battle_finished();
if !hollow_finished {
session.send_rpc_arg(210, &sync_event).await?;
} else {
let dungeon_manager = session.context.dungeon_manager.borrow();
let _ = *dungeon_manager
.hollow_finished()
.send_changes(session)
.await?;
let ptc_dungeon_quest_finished = PtcDungeonQuestFinishedArg {
player_uid: 1337,
quest_id: 1001000101,
success: true,
reward_items: phashmap![],
statistics: phashmap![(QuestStatisticsType::ArrivedLevel, 1)],
};
session
.send_rpc_arg(148, &ptc_dungeon_quest_finished)
.await?;
}
let dungeon_manager = session.context.dungeon_manager.borrow();
let ptc_enter_scene = dungeon_manager
.leave_battle()
.unwrap()
.send_changes(session)
.await?
.clone();
session
.send_rpc_arg(
124,
&hollow_grid_manager.sync_hollow_maps(player_uid, dungeon_manager.get_cur_scene_uid()),
)
.await?;
let ptc_position_in_hollow_changed = PtcPositionInHollowChangedArg {
player_uid,
hollow_level: 1,
position: hollow_grid_manager.get_cur_position_in_hollow(),
};
session
.send_rpc_arg(141, &ptc_position_in_hollow_changed)
.await?;
session.send_rpc_arg(118, &ptc_enter_scene).await?;
session
.send_rpc_ret(RpcEndBattleRet::new(
hollow_grid_manager.get_cur_event_template_id(),
HashMap::new(),
))
.await
}
pub async fn on_rpc_run_hollow_event_graph_arg(
session: &mut NetworkSession,
arg: &RpcRunHollowEventGraphArg,
) -> Result<()> {
tracing::info!("Run hollow event graph {:?}", arg);
let scene_uid = session.get_player().scene_uid.unwrap();
if arg.event_graph_uid == 3405096459205834 {
// Perform (cutscene)
let finish_perform = PtcSyncHollowEventInfoArg {
event_graph_uid: 3405096459205834,
hollow_event_template_id: 1000108,
event_graph_id: 1000108,
updated_event: EventInfo {
id: 1000,
cur_action_id: -1,
action_move_path: vec![1001, 1002, -1],
state: EventState::Finished,
prev_state: EventState::Running,
cur_action_info: ActionInfo::None {},
cur_action_state: ActionState::Init,
predicated_failed_actions: phashset![],
stack_frames: Vec::new(),
},
specials: phashmap![],
};
session.send_rpc_arg(210, &finish_perform).await?;
let hollow_grid_manager = session.context.hollow_grid_manager.borrow();
let (ptc_hollow_grid, ptc_sync_hollow_event) = hollow_grid_manager.move_to(22, scene_uid);
session.send_rpc_arg(114, &ptc_hollow_grid).await?;
if let Some(ptc_sync_hollow_event) = ptc_sync_hollow_event {
session.send_rpc_arg(210, &ptc_sync_hollow_event).await?;
}
} else {
let hollow_grid_manager = session.context.hollow_grid_manager.borrow();
let (sync_hollow_event, hollow_grid, trigger_battle_id, hollow_finished) =
hollow_grid_manager.run_event_graph(
arg.event_graph_uid,
arg.event_id,
arg.move_path.clone(),
);
if !hollow_finished {
session.send_rpc_arg(210, &sync_hollow_event).await?;
}
session.send_rpc_arg(114, &hollow_grid).await?;
if hollow_finished {
let dungeon_manager = session.context.dungeon_manager.borrow();
let _ = *dungeon_manager
.hollow_finished()
.send_changes(session)
.await?;
let ptc_dungeon_quest_finished = PtcDungeonQuestFinishedArg {
player_uid: 1337,
quest_id: 1001000101,
success: true,
reward_items: phashmap![],
statistics: phashmap![],
};
session
.send_rpc_arg(148, &ptc_dungeon_quest_finished)
.await?;
}
if let Some(trigger_battle_id) = trigger_battle_id {
let dungeon_manager = session.context.dungeon_manager.borrow();
let hollow_uid = *session.get_player().scene_uid.as_ref().unwrap();
let battle_scene_uid = *dungeon_manager
.create_fight(trigger_battle_id, hollow_uid)
.send_changes(session)
.await?;
let ptc_position_in_hollow_changed = PtcPositionInHollowChangedArg {
player_uid: 1337,
hollow_level: 1,
position: hollow_grid_manager.get_cur_position_in_hollow(),
};
session
.send_rpc_arg(141, &ptc_position_in_hollow_changed)
.await?;
session
.send_rpc_arg(
118,
dungeon_manager
.enter_battle(battle_scene_uid)
.send_changes(session)
.await?,
)
.await?;
}
}
session.send_rpc_ret(RpcRunHollowEventGraphRet::new()).await
}
pub async fn on_rpc_start_hollow_quest_arg(
session: &NetworkSession,
arg: &RpcStartHollowQuestArg,
) -> Result<()> {
tracing::info!("start hollow quest: {arg:?}");
// Set avatar HP properties
for (_idx, avatar_uid) in &arg.avatar_map {
let player_info = session.get_player();
let items = player_info.items.as_ref().unwrap();
let Some(ItemInfo::Avatar { id, .. }) = items
.iter()
.find(|(uid, _)| **uid == *avatar_uid)
.map(|(_, item)| item)
else {
return session
.send_rpc_ret(RpcStartHollowQuestRet::error(
ErrorCode::ObjectNotExist,
Vec::new(),
))
.await;
};
let avatar_config = data::iter_avatar_config_collection()
.find(|c| c.id == *id)
.unwrap();
let update_properties = PtcPropertyChangedArg {
scene_unit_uid: *avatar_uid,
is_partial: true,
changed_properties: phashmap![(1, avatar_config.hp), (111, avatar_config.hp)],
};
session.send_rpc_arg(129, &update_properties).await?;
}
let dungeon_manager = session.context.dungeon_manager.borrow();
let avatars = arg
.avatar_map
.iter()
.sorted_by_key(|kv| kv.0)
.map(|(_idx, uid)| *uid)
.collect::<Vec<_>>();
let (dungeon_uid, scene_uid) = *dungeon_manager
.create_hollow(10001, 10010001, &avatars)
.send_changes(session)
.await?;
let quest_manager = session.context.quest_manager.borrow();
quest_manager
.add_quest_to_collection(
dungeon_uid,
QuestInfo::DungeonInner {
id: 1001000101,
finished_count: 0,
collection_uid: 0,
progress: 0,
parent_quest_id: 10010001,
state: QuestState::InProgress,
finish_condition_progress: phashmap![],
progress_time: 2111605,
sort_id: 2000,
},
)
.send_changes(session)
.await?;
let ptc_enter_scene = dungeon_manager
.enter_scene(scene_uid)?
.send_changes(session)
.await?
.clone();
let hollow_grid_manager = session.context.hollow_grid_manager.borrow();
hollow_grid_manager.init_default_map();
session
.send_rpc_arg(
124,
&hollow_grid_manager.sync_hollow_maps(session.get_player_uid(), scene_uid),
)
.await?;
let ptc_position_in_hollow_changed = PtcPositionInHollowChangedArg {
player_uid: 1337,
hollow_level: 1,
position: hollow_grid_manager.get_cur_position_in_hollow(),
};
session
.send_rpc_arg(141, &ptc_position_in_hollow_changed)
.await?;
let ptc_sync_hollow_event_info = PtcSyncHollowEventInfoArg {
event_graph_uid: 3405096459205834,
hollow_event_template_id: 1000108,
event_graph_id: 1000108,
updated_event: EventInfo {
id: 1000,
cur_action_id: 1001,
action_move_path: vec![1001],
state: EventState::WaitingClient,
prev_state: EventState::Running,
cur_action_info: ActionInfo::None {},
cur_action_state: ActionState::Init,
predicated_failed_actions: phashset![],
stack_frames: Vec::new(),
},
specials: phashmap![],
};
session
.send_rpc_arg(210, &ptc_sync_hollow_event_info)
.await?;
session.send_rpc_arg(118, &ptc_enter_scene).await?;
session.send_rpc_ret(RpcStartHollowQuestRet::new()).await
}