From 2638ba846750520bfb56f1a705538865700182c5 Mon Sep 17 00:00:00 2001 From: geneotech Date: Fri, 16 Feb 2024 21:58:11 +0100 Subject: [PATCH] Show enemy silhouettes in Spectator and demos. --- src/application/gui/client/demo_player_gui.h | 1 + .../gui/client/demo_player_gui.hpp | 1 + src/application/gui/settings_gui.cpp | 2 ++ .../setups/client/client_setup.cpp | 14 +++++++++ src/application/setups/client/client_setup.h | 2 ++ .../setups/server/server_setup.cpp | 12 ++++++++ src/application/setups/server/server_setup.h | 2 ++ src/augs/graphics/dedicated_buffers.h | 2 ++ src/view/game_drawing_settings.h | 2 ++ .../enqueue_illuminated_rendering_jobs.hpp | 30 ++++++++++++++++--- .../illuminated_rendering.cpp | 1 + .../rendering_scripts/illuminated_rendering.h | 1 + .../is_reasonably_in_view.hpp | 7 ++++- src/work.cpp | 19 ++++++++++++ 14 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/application/gui/client/demo_player_gui.h b/src/application/gui/client/demo_player_gui.h index 417dcd51e..afadb1259 100644 --- a/src/application/gui/client/demo_player_gui.h +++ b/src/application/gui/client/demo_player_gui.h @@ -9,6 +9,7 @@ struct demo_player_gui : standard_window_mixin { using base::base; using introspect_base = base; + bool draw_enemy_silhouettes = true; bool show_spectator_overlay = true; bool pending_interpolation_snap = false; bool pending_dump = false; diff --git a/src/application/gui/client/demo_player_gui.hpp b/src/application/gui/client/demo_player_gui.hpp index 6241d7ff2..1d53db3f2 100644 --- a/src/application/gui/client/demo_player_gui.hpp +++ b/src/application/gui/client/demo_player_gui.hpp @@ -18,6 +18,7 @@ inline void demo_player_gui::perform( } checkbox("Show spectator overlay", show_spectator_overlay); + checkbox("Draw enemy silhouettes", draw_enemy_silhouettes); text("POV:"); ImGui::SameLine(); if (enum_radio(shown_arena_type, true)) { diff --git a/src/application/gui/settings_gui.cpp b/src/application/gui/settings_gui.cpp index c2cf0a645..ae4ede8e9 100644 --- a/src/application/gui/settings_gui.cpp +++ b/src/application/gui/settings_gui.cpp @@ -1136,6 +1136,8 @@ void settings_gui_state::perform( if (auto node = scoped_tree_node("HUD")) { revertable_checkbox("Cinematic mode", config.drawing.cinematic_mode); + revertable_checkbox("Draw enemy silhouettes in Spectator", config.drawing.draw_enemy_silhouettes_in_spectator); + revertable_checkbox(SCOPE_CFG_NVP(draw_inventory)); revertable_checkbox(SCOPE_CFG_NVP(draw_hotbar)); diff --git a/src/application/setups/client/client_setup.cpp b/src/application/setups/client/client_setup.cpp index eb6b05cc5..e4bdf046d 100644 --- a/src/application/setups/client/client_setup.cpp +++ b/src/application/setups/client/client_setup.cpp @@ -746,6 +746,8 @@ void client_setup::customize_for_viewing(config_lua_table& config) const { if (is_replaying()) { config.arena_mode_gui.show_spectator_overlay = demo_player.gui.show_spectator_overlay; + config.drawing.draw_enemy_silhouettes_in_spectator = demo_player.gui.draw_enemy_silhouettes; + config.client.spectated_arena_type = demo_player.gui.shown_arena_type; if (is_paused()) { @@ -1784,3 +1786,15 @@ bool client_setup::would_abandon_match() const { } ); } + +faction_type client_setup::get_assigned_faction() const { + return get_arena_handle(client_arena_type::PREDICTED).on_mode( + [&](const auto& mode) { + if (const auto p = mode.find(get_local_player_id())) { + return p->get_faction(); + } + + return faction_type::COUNT; + } + ); +} diff --git a/src/application/setups/client/client_setup.h b/src/application/setups/client/client_setup.h index 65dfcb24d..baa073dd1 100644 --- a/src/application/setups/client/client_setup.h +++ b/src/application/setups/client/client_setup.h @@ -865,4 +865,6 @@ class client_setup : bool is_ranked_live_or_starting() const; bool would_abandon_match() const; + + faction_type get_assigned_faction() const; }; diff --git a/src/application/setups/server/server_setup.cpp b/src/application/setups/server/server_setup.cpp index 24835a0a0..a777979b8 100644 --- a/src/application/setups/server/server_setup.cpp +++ b/src/application/setups/server/server_setup.cpp @@ -3745,6 +3745,18 @@ bool server_setup::has_assigned_teams() const { return !assigned_teams.id_to_faction.empty(); } +faction_type server_setup::get_assigned_faction() const { + return get_arena_handle().on_mode( + [&](const auto& mode) { + if (const auto p = mode.find(get_local_player_id())) { + return p->get_faction(); + } + + return faction_type::COUNT; + } + ); +} + #include "augs/readwrite/to_bytes.h" // TODO: rewrite unit tests to use streams since we're no longer using preserialized_message diff --git a/src/application/setups/server/server_setup.h b/src/application/setups/server/server_setup.h index c539f23e0..8dd3f0fae 100644 --- a/src/application/setups/server/server_setup.h +++ b/src/application/setups/server/server_setup.h @@ -642,6 +642,8 @@ class server_setup : return get_integrated_player_id(); } + faction_type get_assigned_faction() const; + bool is_gameplay_on() const; #if !HEADLESS diff --git a/src/augs/graphics/dedicated_buffers.h b/src/augs/graphics/dedicated_buffers.h index 5046b329e..29eae7a61 100644 --- a/src/augs/graphics/dedicated_buffers.h +++ b/src/augs/graphics/dedicated_buffers.h @@ -57,6 +57,8 @@ namespace augs { BORDERS_FRIENDLY_SENTIENCES, BORDERS_ENEMY_SENTIENCES, + OCCLUDED_ENEMY_HIGHLIGHTS, + NEONS_FRIENDLY_SENTIENCES, NEONS_ENEMY_SENTIENCES, diff --git a/src/view/game_drawing_settings.h b/src/view/game_drawing_settings.h index b849ab764..f2f385da8 100644 --- a/src/view/game_drawing_settings.h +++ b/src/view/game_drawing_settings.h @@ -40,6 +40,8 @@ struct game_drawing_settings { int snap_zoom_to_multiple_if_different_by_pixels = 10; float custom_zoom = 1.0f; + bool draw_enemy_silhouettes_in_spectator = true; + bool draw_crosshairs = true; bool draw_weapon_laser = true; bool draw_aabb_highlighter = true; diff --git a/src/view/rendering_scripts/enqueue_illuminated_rendering_jobs.hpp b/src/view/rendering_scripts/enqueue_illuminated_rendering_jobs.hpp index aa0107285..234df2ca1 100644 --- a/src/view/rendering_scripts/enqueue_illuminated_rendering_jobs.hpp +++ b/src/view/rendering_scripts/enqueue_illuminated_rendering_jobs.hpp @@ -11,6 +11,7 @@ void enqueue_illuminated_rendering_jobs( using D = augs::dedicated_buffer; using DV = augs::dedicated_buffer_vector; + const bool draw_enemy_silhouettes = in.can_draw_enemy_silhouettes && in.drawing.draw_enemy_silhouettes_in_spectator; const bool streamer_mode = in.streamer_mode; const auto& necessarys = in.necessary_images; @@ -81,7 +82,7 @@ void enqueue_illuminated_rendering_jobs( return augs::line_drawer_with_default { dedicated[d].lines, necessarys.at(assets::necessary_image_id::BLANK) }; }; - auto sentience_hud_job = [&cosm, considered_fov, streamer_mode, cone, global_time_seconds, settings, &necessarys, &dedicated, queried_cone, &visible, viewed_character, &interp, &gui_font, indicator_meta, fog_of_war_effective, pre_step_crosshair_displacement, &damage_indication, damage_indication_settings]() { + auto sentience_hud_job = [draw_enemy_silhouettes, &cosm, considered_fov, streamer_mode, cone, global_time_seconds, settings, &necessarys, &dedicated, queried_cone, &visible, viewed_character, &interp, &gui_font, indicator_meta, fog_of_war_effective, pre_step_crosshair_displacement, &damage_indication, damage_indication_settings]() { (void)fog_of_war_effective; augs::constant_size_vector requested_meters; @@ -148,7 +149,8 @@ void enqueue_illuminated_rendering_jobs( pre_step_crosshair_displacement, interp, considered_fov, - settings.teammates_are_enemies + settings.teammates_are_enemies, + draw_enemy_silhouettes ); }; @@ -520,7 +522,7 @@ void enqueue_illuminated_rendering_jobs( } }; - auto sentiences_job = [ffa = settings.teammates_are_enemies, cast_highlight_tex, &cosm, fog_of_war_character_id, make_drawing_input, &visible, &interp, global_time_seconds]() { + auto sentiences_job = [draw_enemy_silhouettes, ffa = settings.teammates_are_enemies, cast_highlight_tex, &cosm, fog_of_war_character_id, make_drawing_input, &visible, &interp, global_time_seconds]() { auto draw_lights_for = [&](const auto& drawing_in, const auto& handle) { ::specific_draw_neon_map(handle, drawing_in); ::draw_character_glow( @@ -540,12 +542,28 @@ void enqueue_illuminated_rendering_jobs( return typed_handle.template get().find_low_health_border(timestamp_ms); }; + auto occluded_highlight_provider = [](const auto& typed_handle) -> std::optional { + switch (typed_handle.get_official_faction()) { + case faction_type::RESISTANCE: + return orange; + case faction_type::METROPOLIS: + return cyan; + case faction_type::ATLANTIS: + return green; + + default: + return std::nullopt; + } + }; + const auto friendly_drawing_in = make_drawing_input(D::FRIENDLY_SENTIENCES); const auto enemy_drawing_in = make_drawing_input(D::ENEMY_SENTIENCES); const auto borders_friendly_drawing_in = make_drawing_input(D::BORDERS_FRIENDLY_SENTIENCES); const auto borders_enemy_drawing_in = make_drawing_input(D::BORDERS_ENEMY_SENTIENCES); + const auto occluded_enemy_highlights_in = make_drawing_input(D::OCCLUDED_ENEMY_HIGHLIGHTS); + const auto neons_friendly_drawing_in = make_drawing_input(D::NEONS_FRIENDLY_SENTIENCES); const auto neons_enemy_drawing_in = make_drawing_input(D::NEONS_ENEMY_SENTIENCES); @@ -564,7 +582,7 @@ void enqueue_illuminated_rendering_jobs( return modified_input; }; - if (is_local || (!ffa && typed_handle.get_official_faction() == fow_faction)) { + if (const bool visible_in_fow = is_local || (!ffa && typed_handle.get_official_faction() == fow_faction)) { draw_lights_for(neons_friendly_drawing_in, typed_handle); ::specific_draw_color_highlight(typed_handle, SHADOW_COLOR, friendly_drawing_in, shadow_input_customizer); @@ -577,6 +595,10 @@ void enqueue_illuminated_rendering_jobs( ::specific_draw_color_highlight(typed_handle, SHADOW_COLOR, enemy_drawing_in, shadow_input_customizer); ::specific_draw_entity(typed_handle, enemy_drawing_in); ::specific_draw_border(typed_handle, borders_enemy_drawing_in, standard_border_provider); + + if (draw_enemy_silhouettes) { + ::specific_draw_border(typed_handle, occluded_enemy_highlights_in, occluded_highlight_provider); + } } }); }); diff --git a/src/view/rendering_scripts/illuminated_rendering.cpp b/src/view/rendering_scripts/illuminated_rendering.cpp index b9be3fe76..6efea47b2 100644 --- a/src/view/rendering_scripts/illuminated_rendering.cpp +++ b/src/view/rendering_scripts/illuminated_rendering.cpp @@ -238,6 +238,7 @@ void illuminated_rendering(const illuminated_rendering_input in) { renderer.call_triangles(D::BORDERS_ENEMY_SENTIENCES); renderer.set_stencil(false); + renderer.call_triangles(D::OCCLUDED_ENEMY_HIGHLIGHTS); renderer.call_triangles(D::BORDERS_FRIENDLY_SENTIENCES); } else { diff --git a/src/view/rendering_scripts/illuminated_rendering.h b/src/view/rendering_scripts/illuminated_rendering.h index 5c76e2ca9..e518b7420 100644 --- a/src/view/rendering_scripts/illuminated_rendering.h +++ b/src/view/rendering_scripts/illuminated_rendering.h @@ -49,6 +49,7 @@ struct illuminated_rendering_input { const vec2 pre_step_crosshair_displacement; const audiovisual_state& audiovisuals; const game_drawing_settings drawing; + const bool can_draw_enemy_silhouettes; const necessary_images_in_atlas_map& necessary_images; const all_loaded_gui_fonts& fonts; const images_in_atlas_map& game_images; diff --git a/src/view/rendering_scripts/is_reasonably_in_view.hpp b/src/view/rendering_scripts/is_reasonably_in_view.hpp index 47ffb43f8..ac47ba59a 100644 --- a/src/view/rendering_scripts/is_reasonably_in_view.hpp +++ b/src/view/rendering_scripts/is_reasonably_in_view.hpp @@ -7,7 +7,8 @@ bool is_reasonably_in_view( const vec2 pre_step_crosshair_displacement, const interpolation_system& interp, const fog_of_war_settings considered_fow, - const bool teammates_are_enemies + const bool teammates_are_enemies, + const bool skip_occlusion_check = false ) { const auto fow_angle = considered_fow.angle; const auto viewed_character_transform = viewed_character ? viewed_character.find_viewing_transform(interp) : std::optional(); @@ -33,6 +34,10 @@ bool is_reasonably_in_view( return false; } + if (skip_occlusion_check) { + return true; + } + auto look_dir = calc_crosshair_displacement(viewed_character) + pre_step_crosshair_displacement; if (look_dir.is_zero()) { diff --git a/src/work.cpp b/src/work.cpp index 764feba73..189c8465b 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -2308,6 +2308,24 @@ work_result work( return result; }; + auto can_show_enemy_silhouettes = [&]() { + if (is_replaying_demo()) { + return true; + } + + bool result = false; + + on_specific_setup([&](client_setup& setup) { + result = setup.get_assigned_faction() == faction_type::SPECTATOR; + }); + + on_specific_setup([&](server_setup& setup) { + result = setup.get_assigned_faction() == faction_type::SPECTATOR; + }); + + return result; + }; + augs::timer ad_hoc_animation_timer; auto perform_setup_custom_imgui = [&]() { @@ -4168,6 +4186,7 @@ work_result work( calc_pre_step_crosshair_displacement(viewing_config), get_audiovisuals(), viewing_config.drawing, + can_show_enemy_silhouettes(), streaming.necessary_images_in_atlas, streaming.get_loaded_gui_fonts(), streaming.images_in_atlas,