192 lines
6.2 KiB
Rust
192 lines
6.2 KiB
Rust
use bevy_ecs::prelude::*;
|
|
use tracing::debug;
|
|
use trigger_logic::{action_pb, scene::ESceneType};
|
|
use trigger_protocol::{ActionInfo, EnterSectionScRsp, SavePosInMainCityScRsp};
|
|
use trigger_sv::message::GameStateCallback;
|
|
|
|
use crate::logic::message::{EnterSectionEvent, PlayerMoveEvent};
|
|
|
|
use super::event_graph::*;
|
|
use super::hall::*;
|
|
use super::player::*;
|
|
use super::scene_unit::*;
|
|
|
|
use super::{GameStateListener, HallInitData, NapResources};
|
|
|
|
#[derive(Event)]
|
|
pub struct PlayerEnterScene;
|
|
|
|
pub fn hall_init(mut commands: Commands, init_data: Res<HallInitData>) {
|
|
commands.spawn(HallBundle {
|
|
section: MainCitySection(init_data.section_id),
|
|
bgm: BGMusic(init_data.bgm_id),
|
|
clock: Clock {
|
|
time_of_day: init_data.time_of_day as u16,
|
|
day_of_week: init_data.day_of_week as u8,
|
|
},
|
|
});
|
|
|
|
commands.spawn(PlayerBundle {
|
|
avatar: ControlledAvatar {
|
|
player_avatar_id: init_data.player_avatar_id,
|
|
control_avatar_id: init_data.control_avatar_id,
|
|
},
|
|
position: init_data.initial_position.clone(),
|
|
});
|
|
}
|
|
|
|
pub fn process_enter_section(
|
|
mut enter_section_events: EventReader<EnterSectionEvent>,
|
|
mut player_enter_events: EventWriter<PlayerEnterScene>,
|
|
mut section: Query<&mut MainCitySection>,
|
|
mut position: Query<&mut MainCityPosition>,
|
|
) {
|
|
for event in enter_section_events.read() {
|
|
debug!("{event:?}");
|
|
|
|
section.single_mut().0 = event.section_id;
|
|
*position.single_mut() = MainCityPosition::Predefined(event.transform_id.clone());
|
|
|
|
player_enter_events.send(PlayerEnterScene);
|
|
}
|
|
}
|
|
|
|
pub fn finish_enter_section(
|
|
mut enter_section_events: EventReader<EnterSectionEvent>,
|
|
mut listener: ResMut<GameStateListener>,
|
|
) {
|
|
for event in enter_section_events.read() {
|
|
listener.emit_callback(GameStateCallback::ClientCmdProcessed {
|
|
ack_request_id: event.request_id,
|
|
response: Some(EnterSectionScRsp { retcode: 0 }.into()),
|
|
});
|
|
}
|
|
}
|
|
|
|
pub fn fire_events_on_section_switch(
|
|
mut commands: Commands,
|
|
mut events: EventWriter<GraphEvent>,
|
|
resources: Res<NapResources>,
|
|
changed_section: Query<&MainCitySection, Changed<MainCitySection>>,
|
|
scene_units: Query<Entity, With<SceneUnitTag>>,
|
|
) {
|
|
if let Some(section) = changed_section.iter().take(1).next() {
|
|
// Remove all scene units that belong to previous section
|
|
scene_units
|
|
.iter()
|
|
.for_each(|entity_id| commands.entity(entity_id).despawn());
|
|
|
|
// Emit on_create and on_enter for new section
|
|
if let Some(section_cfg) = resources.main_city_config.sections.get(&(section.0 as i32)) {
|
|
section_cfg
|
|
.section_progress
|
|
.on_add
|
|
.iter()
|
|
.chain(section_cfg.section_progress.on_enter.iter())
|
|
.map(|name| section_cfg.section_progress.events.get(name))
|
|
.flatten()
|
|
.for_each(|event| {
|
|
events.send(GraphEvent(event));
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn notify_enter_scene(
|
|
mut events: EventReader<PlayerEnterScene>,
|
|
mut listener: ResMut<GameStateListener>,
|
|
hall: Query<HallQuery>,
|
|
player: Query<PlayerQuery>,
|
|
scene_units: Query<SceneUnitQuery>,
|
|
) {
|
|
use trigger_protocol::*;
|
|
|
|
for _ in events.read() {
|
|
let hall = hall.single();
|
|
let player = player.single();
|
|
|
|
let mut hall_scene_info = HallSceneInfo {
|
|
section_id: hall.section.0,
|
|
bgm_id: hall.bgm.0,
|
|
day_of_week: hall.clock.day_of_week as u32,
|
|
time_of_day: hall.clock.time_of_day as u32,
|
|
player_avatar_id: player.avatar.player_avatar_id,
|
|
control_avatar_id: player.avatar.control_avatar_id,
|
|
scene_unit_list: scene_units.iter().map(|unit| unit.to_protocol()).collect(),
|
|
..Default::default()
|
|
};
|
|
|
|
match player.position {
|
|
MainCityPosition::Predefined(id) => {
|
|
hall_scene_info.transform_id = id.clone();
|
|
}
|
|
MainCityPosition::Transform(transform) => {
|
|
hall_scene_info.position = Some(trigger_protocol::Transform {
|
|
position: vec![
|
|
transform.position.x,
|
|
transform.position.y,
|
|
transform.position.z,
|
|
],
|
|
rotation: vec![
|
|
transform.rotation.x,
|
|
transform.rotation.y,
|
|
transform.rotation.z,
|
|
],
|
|
});
|
|
}
|
|
}
|
|
|
|
listener.add(EnterSceneScNotify {
|
|
scene: Some(SceneData {
|
|
scene_type: ESceneType::Hall as u32,
|
|
hall_scene_info: Some(hall_scene_info),
|
|
..Default::default()
|
|
}),
|
|
dungeon: None,
|
|
});
|
|
}
|
|
}
|
|
|
|
pub fn tick_player_movement(
|
|
mut events: EventReader<PlayerMoveEvent>,
|
|
mut position: Query<&mut MainCityPosition>,
|
|
mut listener: ResMut<GameStateListener>,
|
|
section: Query<&MainCitySection>,
|
|
) {
|
|
for event in events.read() {
|
|
debug!("{event:?}");
|
|
|
|
if event.section_id == section.single().0 {
|
|
*position.single_mut() = MainCityPosition::Transform(event.position.clone());
|
|
}
|
|
|
|
listener.emit_callback(trigger_sv::message::GameStateCallback::ClientCmdProcessed {
|
|
ack_request_id: event.request_id,
|
|
response: Some(SavePosInMainCityScRsp { retcode: 0 }.into()),
|
|
});
|
|
}
|
|
}
|
|
|
|
pub fn tick_switch_section(
|
|
mut events: EventReader<ActionSwitchSectionEvent>,
|
|
mut graph: Query<&mut EventGraph>,
|
|
) {
|
|
use action_pb::PbMessage;
|
|
|
|
for event in events.read() {
|
|
let mut graph = graph.single_mut();
|
|
|
|
// Only add action to the graph
|
|
// We will do actual section switch on EnterSectionEvent
|
|
graph.actions.push(ActionInfo {
|
|
action_type: 6,
|
|
body: action_pb::ActionSwitchSection {
|
|
section: event.section_id,
|
|
transform_id: event.transform.clone(),
|
|
camera_x: event.camera_x,
|
|
camera_y: event.camera_y,
|
|
}
|
|
.encode_to_vec(),
|
|
});
|
|
}
|
|
}
|