Skip to content

Commit

Permalink
Improve first map server connect
Browse files Browse the repository at this point in the history
On first login the map server will send a command to change the map regardless, so we don't need to handle the map loading in the network event when we disconnect from the character server. We only initialize the player entity and interface in this case. We also now properly turn the screen black until we fully finished loading the map. Later we should also do the loading asynchronously on map change and turn the screen black while loading.
  • Loading branch information
hasenbanck committed Dec 28, 2024
1 parent e34271c commit 299c9cd
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 77 deletions.
28 changes: 27 additions & 1 deletion korangar/src/graphics/instruction.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use cgmath::{Matrix4, Point3, Vector2, Vector3, Vector4};
use cgmath::{Matrix4, Point3, SquareMatrix, Vector2, Vector3, Vector4, Zero};
use korangar_util::Rectangle;
use ragnarok_packets::EntityId;
use wgpu::BlendFactor;
Expand Down Expand Up @@ -66,6 +66,21 @@ pub struct Uniforms {
pub shadow_quality: ShadowQuality,
}

impl Default for Uniforms {
fn default() -> Self {
Self {
view_matrix: Matrix4::identity(),
projection_matrix: Matrix4::identity(),
camera_position: Vector4::zero(),
animation_timer: 0.0,
day_timer: 0.0,
ambient_light_color: Color::default(),
enhanced_lighting: false,
shadow_quality: ShadowQuality::Soft,
}
}
}

#[derive(Clone, Debug)]
pub struct WaterInstruction<'a> {
pub water_texture: &'a Texture,
Expand All @@ -86,6 +101,17 @@ pub struct DirectionalShadowCasterInstruction {
pub color: Color,
}

impl Default for DirectionalShadowCasterInstruction {
fn default() -> Self {
Self {
view_projection_matrix: Matrix4::identity(),
view_matrix: Matrix4::identity(),
direction: Vector3::zero(),
color: Color::default(),
}
}
}

/// Right now point shadows can't cast shadows of models that are not part of
/// the map.
#[derive(Clone, Debug)]
Expand Down
2 changes: 1 addition & 1 deletion korangar/src/graphics/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ impl Display for ScreenSpaceAntiAliasing {
}

#[cfg(feature = "debug")]
#[derive(Copy, Clone, new)]
#[derive(Copy, Clone, Default, new)]
pub struct RenderSettings {
#[new(value = "true")]
pub show_frames_per_second: bool,
Expand Down
167 changes: 96 additions & 71 deletions korangar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ struct Client {
mouse_cursor: MouseCursor,
dialog_system: DialogSystem,
show_interface: bool,
show_game: bool,
game_timer: GameTimer,

#[cfg(feature = "debug")]
Expand Down Expand Up @@ -460,6 +461,7 @@ impl Client {
let mouse_cursor = MouseCursor::new(&mut sprite_loader, &mut action_loader);
let dialog_system = DialogSystem::default();
let show_interface = true;
let show_game = true;
});

time_phase!("initialize timer", {
Expand Down Expand Up @@ -633,6 +635,7 @@ impl Client {
mouse_cursor,
dialog_system,
show_interface,
show_game,
game_timer,
#[cfg(feature = "debug")]
debug_camera,
Expand Down Expand Up @@ -923,7 +926,8 @@ impl Client {
self.interface
.open_window(&self.application, &mut self.focus_state, &ErrorWindow::new(message.to_owned()))
}
NetworkEvent::CharacterSelected { login_data, map_name } => {
NetworkEvent::CharacterSelected { login_data, .. } => {
self.show_game = false;
self.audio_engine.play_sound_effect(self.main_menu_click_sound_effect);

let saved_login_data = self.saved_login_data.as_ref().unwrap();
Expand All @@ -938,21 +942,6 @@ impl Client {
.cloned()
.unwrap();

self.map = self
.map_loader
.load(
map_name,
&mut self.model_loader,
self.texture_loader.clone(),
#[cfg(feature = "debug")]
&self.tile_texture_mapping,
)
.unwrap();

self.map.set_ambient_sound_sources(&self.audio_engine);
self.audio_engine
.play_background_music_track(self.map.background_music_track_name());

self.saved_player_name = character_information.name.clone();

let player = Player::new(
Expand All @@ -972,8 +961,8 @@ impl Client {
self.player_camera.set_focus_point(player.get_position());
self.entities.push(player);

// TODO: this will do one unnecessary restore_focus. check if
// that will be problematic
// TODO: This will do one unnecessary restore_focus. Check if
// that will be problematic.
self.interface
.close_window_with_class(&mut self.focus_state, CharacterSelectionWindow::WINDOW_CLASS);
self.interface
Expand All @@ -991,10 +980,6 @@ impl Client {

// Put the dialog system in a well-defined state.
self.dialog_system.close_dialog();

self.particle_holder.clear();
let _ = self.networking_system.map_loaded();
self.game_timer.set_client_tick(client_tick);
}
NetworkEvent::CharacterCreated { character_information } => {
self.saved_characters.push(character_information);
Expand Down Expand Up @@ -1078,6 +1063,7 @@ impl Client {
self.entities[0].generate_pathing_mesh(&self.device, &self.queue, &self.map, &self.pathing_texture_mapping);
}
NetworkEvent::ChangeMap(map_name, player_position) => {
self.show_game = true;
self.entities.truncate(1);

self.map = self
Expand Down Expand Up @@ -2267,55 +2253,94 @@ impl Client {
let top_layer_instructions = self.top_interface_renderer.get_instructions();
let font_loader = self.font_loader.borrow();

let render_instruction = RenderInstruction {
clear_interface,
show_interface: self.show_interface,
picker_position,
uniforms: Uniforms {
view_matrix,
projection_matrix,
camera_position,
animation_timer,
day_timer,
ambient_light_color,
enhanced_lighting: lighting_mode == LightingMode::Enhanced,
shadow_quality,
},
indicator: indicator_instruction,
interface: interface_instructions.as_slice(),
bottom_layer_rectangles: bottom_layer_instructions.as_slice(),
middle_layer_rectangles: middle_layer_instructions.as_slice(),
top_layer_rectangles: top_layer_instructions.as_slice(),
directional_light_with_shadow: DirectionalShadowCasterInstruction {
view_projection_matrix: directional_light_view_projection_matrix,
view_matrix: directional_light_view_matrix,
direction: directional_light_direction,
color: directional_light_color,
},
point_light_shadow_caster: &self.point_light_with_shadow_instructions,
point_light: &self.point_light_instructions,
model_batches: &self.model_batches,
models: &mut self.model_instructions,
entities: &mut self.entity_instructions,
directional_model_batches: &self.directional_shadow_model_batches,
directional_shadow_models: &self.directional_shadow_model_instructions,
directional_shadow_entities: &self.directional_shadow_entity_instructions,
point_shadow_models: &self.point_shadow_model_instructions,
point_shadow_entities: &self.point_shadow_entity_instructions,
effects: self.effect_renderer.get_instructions(),
water: water_instruction,
map_picker_tile_vertex_buffer: self.map.get_tile_picker_vertex_buffer(),
font_map_texture: font_loader.get_font_map(),
#[cfg(feature = "debug")]
render_settings: *self.render_settings.get(),
#[cfg(feature = "debug")]
aabb: &self.aabb_instructions,
#[cfg(feature = "debug")]
circles: &self.circle_instructions,
#[cfg(feature = "debug")]
rectangles: &self.rectangle_instructions,
#[cfg(feature = "debug")]
marker: self.debug_marker_renderer.get_instructions(),
let render_instruction = if self.show_game {
RenderInstruction {
clear_interface,
show_interface: self.show_interface,
picker_position,
uniforms: Uniforms {
view_matrix,
projection_matrix,
camera_position,
animation_timer,
day_timer,
ambient_light_color,
enhanced_lighting: lighting_mode == LightingMode::Enhanced,
shadow_quality,
},
indicator: indicator_instruction,
interface: interface_instructions.as_slice(),
bottom_layer_rectangles: bottom_layer_instructions.as_slice(),
middle_layer_rectangles: middle_layer_instructions.as_slice(),
top_layer_rectangles: top_layer_instructions.as_slice(),
directional_light_with_shadow: DirectionalShadowCasterInstruction {
view_projection_matrix: directional_light_view_projection_matrix,
view_matrix: directional_light_view_matrix,
direction: directional_light_direction,
color: directional_light_color,
},
point_light_shadow_caster: &self.point_light_with_shadow_instructions,
point_light: &self.point_light_instructions,
model_batches: &self.model_batches,
models: &mut self.model_instructions,
entities: &mut self.entity_instructions,
directional_model_batches: &self.directional_shadow_model_batches,
directional_shadow_models: &self.directional_shadow_model_instructions,
directional_shadow_entities: &self.directional_shadow_entity_instructions,
point_shadow_models: &self.point_shadow_model_instructions,
point_shadow_entities: &self.point_shadow_entity_instructions,
effects: self.effect_renderer.get_instructions(),
water: water_instruction,
map_picker_tile_vertex_buffer: self.map.get_tile_picker_vertex_buffer(),
font_map_texture: font_loader.get_font_map(),
#[cfg(feature = "debug")]
render_settings: *self.render_settings.get(),
#[cfg(feature = "debug")]
aabb: &self.aabb_instructions,
#[cfg(feature = "debug")]
circles: &self.circle_instructions,
#[cfg(feature = "debug")]
rectangles: &self.rectangle_instructions,
#[cfg(feature = "debug")]
marker: self.debug_marker_renderer.get_instructions(),
}
} else {
RenderInstruction {
clear_interface: true,
show_interface: false,
picker_position: ScreenPosition::default(),
uniforms: Uniforms::default(),
indicator: None,
interface: &[],
bottom_layer_rectangles: &[],
middle_layer_rectangles: &[],
top_layer_rectangles: &[],
directional_light_with_shadow: DirectionalShadowCasterInstruction::default(),
point_light_shadow_caster: &[],
point_light: &[],
model_batches: &[],
models: &mut [],
entities: &mut [],
directional_model_batches: &[],
directional_shadow_models: &[],
directional_shadow_entities: &[],
point_shadow_models: &[],
point_shadow_entities: &[],
effects: &[],
water: None,
map_picker_tile_vertex_buffer: self.map.get_tile_picker_vertex_buffer(),
font_map_texture: font_loader.get_font_map(),
#[cfg(feature = "debug")]
render_settings: RenderSettings::default(),
#[cfg(feature = "debug")]
aabb: &[],
#[cfg(feature = "debug")]
circles: &[],
#[cfg(feature = "debug")]
rectangles: &[],
#[cfg(feature = "debug")]
marker: &[],
}
};

self.graphics_engine.render_next_frame(frame, render_instruction);
Expand Down
4 changes: 3 additions & 1 deletion korangar/src/world/action/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use derive_new::new;
use korangar_audio::SoundEffectKey;
use korangar_interface::elements::{ElementCell, PrototypeElement};
use korangar_util::container::Cacheable;
use ragnarok_formats::action::{Action, ActionsData};
use ragnarok_formats::action::Action;
#[cfg(feature = "debug")]
use ragnarok_formats::action::ActionsData;
use ragnarok_packets::ClientTick;

use crate::graphics::Color;
Expand Down
1 change: 0 additions & 1 deletion korangar_networking/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ pub enum NetworkEvent {
},
CharacterSelected {
login_data: CharacterServerLoginData,
map_name: String,
},
CharacterSelectionFailed {
reason: UnifiedCharacterSelectionFailedReason,
Expand Down
3 changes: 1 addition & 2 deletions korangar_networking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,9 +560,8 @@ where
server_port: packet.map_server_port,
character_id: packet.character_id,
};
let map_name = packet.map_name.strip_suffix(".gat").unwrap().to_owned();

NetworkEvent::CharacterSelected { login_data, map_name }
NetworkEvent::CharacterSelected { login_data }
})?;
packet_handler.register(|packet: CharacterSelectionFailedPacket| {
let (reason, message) = match packet.reason {
Expand Down

0 comments on commit 299c9cd

Please sign in to comment.