From f8e68042daa3484f5d00b9b35d660c9ad286949c Mon Sep 17 00:00:00 2001 From: Antti Riikonen Date: Thu, 7 Dec 2023 15:08:47 +0000 Subject: [PATCH 01/16] wip pain, prompt goes in right place and nothing else is drawn --- src/game.cpp | 169 ++++----------------------------------------------- 1 file changed, 11 insertions(+), 158 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 4b823fd67194f..a28f2db0f4b9e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -41,6 +41,7 @@ #include "activity_actor_definitions.h" #include "activity_handlers.h" #include "activity_type.h" +#include "ascii_art.h" #include "auto_note.h" #include "auto_pickup.h" #include "avatar.h" @@ -2804,92 +2805,7 @@ void game::bury_screen() const std::vector vRip; - int iMaxWidth = 0; - int iNameLine = 0; - int iInfoLine = 0; - - if( u.has_amount( itype_holybook_bible1, 1 ) || u.has_amount( itype_holybook_bible2, 1 ) || - u.has_amount( itype_holybook_bible3, 1 ) ) { - if( !( u.has_trait( trait_CANNIBAL ) || u.has_trait( trait_PSYCHOPATH ) ) ) { - vRip.emplace_back( " _______ ___" ); - vRip.emplace_back( " < `/ |" ); - vRip.emplace_back( " > _ _ (" ); - vRip.emplace_back( " | |_) | |_) |" ); - vRip.emplace_back( " | | \\ | | |" ); - vRip.emplace_back( " ______.__%_| |_________ __" ); - vRip.emplace_back( " _/ \\| |" ); - iNameLine = vRip.size(); - vRip.emplace_back( "| <" ); - vRip.emplace_back( "| |" ); - iMaxWidth = utf8_width( vRip.back() ); - vRip.emplace_back( "| |" ); - vRip.emplace_back( "|_____.-._____ __/|_________|" ); - vRip.emplace_back( " | |" ); - iInfoLine = vRip.size(); - vRip.emplace_back( " | |" ); - vRip.emplace_back( " | <" ); - vRip.emplace_back( " | |" ); - vRip.emplace_back( " | _ |" ); - vRip.emplace_back( " |__/ |" ); - vRip.emplace_back( " % / `--. |%" ); - vRip.emplace_back( " * .%%| -< @%%%" ); // NOLINT(cata-text-style) - vRip.emplace_back( " `\\%`@| |@@%@%%" ); - vRip.emplace_back( " .%%%@@@|% ` % @@@%%@%%%%" ); - vRip.emplace_back( " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" ); - - } else { - vRip.emplace_back( " _______ ___" ); - vRip.emplace_back( " | \\/ |" ); - vRip.emplace_back( " | |" ); - vRip.emplace_back( " | |" ); - iInfoLine = vRip.size(); - vRip.emplace_back( " | |" ); - vRip.emplace_back( " | |" ); - vRip.emplace_back( " | |" ); - vRip.emplace_back( " | |" ); - vRip.emplace_back( " | <" ); - vRip.emplace_back( " | _ |" ); - vRip.emplace_back( " |__/ |" ); - vRip.emplace_back( " ______.__%_| |__________ _" ); - vRip.emplace_back( " _/ \\| \\" ); - iNameLine = vRip.size(); - vRip.emplace_back( "| <" ); - vRip.emplace_back( "| |" ); - iMaxWidth = utf8_width( vRip.back() ); - vRip.emplace_back( "| |" ); - vRip.emplace_back( "|_____.-._______ __/|__________|" ); - vRip.emplace_back( " % / `_-. _ |%" ); - vRip.emplace_back( " * .%%| |_) | |_)< @%%%" ); // NOLINT(cata-text-style) - vRip.emplace_back( " `\\%`@| | \\ | | |@@%@%%" ); - vRip.emplace_back( " .%%%@@@|% ` % @@@%%@%%%%" ); - vRip.emplace_back( " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" ); - } - } else { - vRip.emplace_back( R"( _________ ____ )" ); - vRip.emplace_back( R"( _/ `/ \_ )" ); - vRip.emplace_back( R"( _/ _ _ \_. )" ); - vRip.emplace_back( R"( _%\ |_) | |_) \_ )" ); - vRip.emplace_back( R"( _/ \/ | \ | | \_ )" ); - vRip.emplace_back( R"( _/ \_ )" ); - vRip.emplace_back( R"(| |)" ); - iNameLine = vRip.size(); - vRip.emplace_back( R"( ) < )" ); - vRip.emplace_back( R"(| |)" ); - vRip.emplace_back( R"(| |)" ); - vRip.emplace_back( R"(| _ |)" ); - vRip.emplace_back( R"(|__/ |)" ); - iMaxWidth = utf8_width( vRip.back() ); - vRip.emplace_back( R"( / `--. |)" ); - vRip.emplace_back( R"(| ( )" ); - iInfoLine = vRip.size(); - vRip.emplace_back( R"(| |)" ); - vRip.emplace_back( R"(| |)" ); - vRip.emplace_back( R"(| % . |)" ); - vRip.emplace_back( R"(| @` %% |)" ); - vRip.emplace_back( R"(| %@%@%\ * %`%@%|)" ); - vRip.emplace_back( R"(%%@@@.%@%\%% `\ %%.%%@@%@)" ); - vRip.emplace_back( R"(@%@@%%%%%@@@@@@%%%%%%%%@@%%@@@%%%@%%@)" ); - } + int iMaxWidth = 41; const point iOffset( TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0, TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ); @@ -2898,86 +2814,23 @@ void game::bury_screen() const iOffset ); draw_border( w_rip ); + const ascii_art_id art = static_cast("hk_mp5a2"); + if( art.is_valid() ) { + for( const std::string &line : art->picture ) { + fold_and_print( w_rip, point( 0, 0 ), 41, c_white, line ); + } + } + + sfx::do_player_death_hurt( get_player_character(), true ); sfx::fade_audio_group( sfx::group::weather, 2000 ); sfx::fade_audio_group( sfx::group::time_of_day, 2000 ); sfx::fade_audio_group( sfx::group::context_themes, 2000 ); sfx::fade_audio_group( sfx::group::sleepiness, 2000 ); - for( size_t iY = 0; iY < vRip.size(); ++iY ) { - size_t iX = 0; - const char *str = vRip[iY].data(); - for( int slen = vRip[iY].size(); slen > 0; ) { - const uint32_t cTemp = UTF8_getch( &str, &slen ); - if( cTemp != U' ' ) { - nc_color ncColor = c_light_gray; - - if( cTemp == U'%' ) { - ncColor = c_green; - - } else if( cTemp == U'_' || cTemp == U'|' ) { - ncColor = c_white; - - } else if( cTemp == U'@' ) { - ncColor = c_brown; - - } else if( cTemp == U'*' ) { - ncColor = c_red; - } - - mvwputch( w_rip, point( iX + FULL_SCREEN_WIDTH / 2 - ( iMaxWidth / 2 ), iY + 1 ), ncColor, - cTemp ); - } - iX += mk_wcwidth( cTemp ); - } - } - - std::string sTemp; - - center_print( w_rip, iInfoLine++, c_white, _( "Survived:" ) ); - - const time_duration survived = calendar::turn - calendar::start_of_game; - const int minutes = to_minutes( survived ) % 60; - const int hours = to_hours( survived ) % 24; - const int days = to_days( survived ); - - if( days > 0 ) { - // NOLINTNEXTLINE(cata-translate-string-literal) - sTemp = string_format( "%dd %dh %dm", days, hours, minutes ); - } else if( hours > 0 ) { - // NOLINTNEXTLINE(cata-translate-string-literal) - sTemp = string_format( "%dh %dm", hours, minutes ); - } else { - // NOLINTNEXTLINE(cata-translate-string-literal) - sTemp = string_format( "%dm", minutes ); - } - - center_print( w_rip, iInfoLine++, c_white, sTemp ); - - const int iTotalKills = g->get_kill_tracker().monster_kill_count(); - - sTemp = _( "Kills:" ); - mvwprintz( w_rip, point( FULL_SCREEN_WIDTH / 2 - 5, 1 + iInfoLine++ ), c_light_gray, - ( sTemp + " " ) ); - wprintz( w_rip, c_magenta, "%d", iTotalKills ); - - sTemp = _( "In memory of:" ); - mvwprintz( w_rip, point( FULL_SCREEN_WIDTH / 2 - utf8_width( sTemp ) / 2, iNameLine++ ), - c_light_gray, - sTemp ); - - sTemp = u.get_name(); - mvwprintz( w_rip, point( FULL_SCREEN_WIDTH / 2 - utf8_width( sTemp ) / 2, iNameLine++ ), c_white, - sTemp ); - - sTemp = _( "Last Words:" ); - mvwprintz( w_rip, point( FULL_SCREEN_WIDTH / 2 - utf8_width( sTemp ) / 2, iNameLine++ ), - c_light_gray, - sTemp ); - int iStartX = FULL_SCREEN_WIDTH / 2 - ( ( iMaxWidth - 4 ) / 2 ); std::string sLastWords = string_input_popup() - .window( w_rip, point( iStartX, iNameLine ), iStartX + iMaxWidth - 4 - 1 ) + .window( w_rip, point( 0, 0 ), iStartX + iMaxWidth - 4 - 1 ) .max_length( iMaxWidth - 4 - 1 ) .query_string(); From 89983d06d63ef714c85ac8e76e85062fba8009f2 Mon Sep 17 00:00:00 2001 From: harakka Date: Sun, 28 Jan 2024 14:15:18 +0000 Subject: [PATCH 02/16] wip type for death screen --- data/json/ascii_art/graveyard.json | 30 ++++++++++++++++++++++++++++++ src/death_screen.h | 25 +++++++++++++++++++++++++ src/game.cpp | 11 ++++++----- src/type_id.h | 3 +++ 4 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 data/json/ascii_art/graveyard.json create mode 100644 src/death_screen.h diff --git a/data/json/ascii_art/graveyard.json b/data/json/ascii_art/graveyard.json new file mode 100644 index 0000000000000..d217c5a456dca --- /dev/null +++ b/data/json/ascii_art/graveyard.json @@ -0,0 +1,30 @@ +[ + { + "type": "ascii_art", + "id": "ascii_rip_cross", + "picture": [ + " _______ ___", + " < `/ |", + " > _ _ (", + " | |_) | |_) |", + " | | \\ | | |", + " ______.__%_| |_________ __", + " _/ \\| |", + "| <", + "| |", + "| |", + "|_____.-._____ __/|_________|", + " | |", + " | |", + " | <", + " | |", + " | _ |", + " |__/ |", + " % / `--. |%", + " * .%%| -< @%%%", + " `\\%`@| |@@%@%%", + " .%%%@@@|% ` % @@@%%@%%%%", + " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" + ] + } +] diff --git a/src/death_screen.h b/src/death_screen.h new file mode 100644 index 0000000000000..565bc077db589 --- /dev/null +++ b/src/death_screen.h @@ -0,0 +1,25 @@ +#pragma once +#ifndef CATA_SRC_DEATH_SCREEN_H +#define CATA_SRC_DEATH_SCREEN_H + +#include +#include + +#include "type_id.h" + +class JsonObject; + +class death_screen +{ + public: + static void load_death_screen( const JsonObject &jo, const std::string &src ); + static void reset(); + + void load( const JsonObject &jo, std::string_view ); + bool was_loaded = false; + + death_screen_id id; + std::string picture; +}; + +#endif // CATA_SRC_DEATH_SCREEN_H diff --git a/src/game.cpp b/src/game.cpp index a28f2db0f4b9e..5b89319f27991 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2806,6 +2806,8 @@ void game::bury_screen() const std::vector vRip; int iMaxWidth = 41; + int iStartX = FULL_SCREEN_WIDTH / 2 - ( ( iMaxWidth - 4 ) / 2 ); + int iNameLine = 15; const point iOffset( TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0, TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ); @@ -2814,23 +2816,22 @@ void game::bury_screen() const iOffset ); draw_border( w_rip ); - const ascii_art_id art = static_cast("hk_mp5a2"); + const ascii_art_id art = static_cast("battery_motorbike"); if( art.is_valid() ) { + int row = 1; for( const std::string &line : art->picture ) { - fold_and_print( w_rip, point( 0, 0 ), 41, c_white, line ); + fold_and_print( w_rip, point( 1, row++ ), 41, c_white, line ); } } - sfx::do_player_death_hurt( get_player_character(), true ); sfx::fade_audio_group( sfx::group::weather, 2000 ); sfx::fade_audio_group( sfx::group::time_of_day, 2000 ); sfx::fade_audio_group( sfx::group::context_themes, 2000 ); sfx::fade_audio_group( sfx::group::sleepiness, 2000 ); - int iStartX = FULL_SCREEN_WIDTH / 2 - ( ( iMaxWidth - 4 ) / 2 ); std::string sLastWords = string_input_popup() - .window( w_rip, point( 0, 0 ), iStartX + iMaxWidth - 4 - 1 ) + .window( w_rip, point( iStartX, iNameLine ), iStartX + iMaxWidth - 4 - 1 ) .max_length( iMaxWidth - 4 - 1 ) .query_string(); diff --git a/src/type_id.h b/src/type_id.h index bfbe45db19c4c..7fccb23d1a281 100644 --- a/src/type_id.h +++ b/src/type_id.h @@ -79,6 +79,9 @@ using damage_type_id = string_id; struct damage_info_order; using damage_info_order_id = string_id; +struct death_screen; +using death_screen_id = string_id; + class disease_type; using diseasetype_id = string_id; From b874e15aa6d51e84753ae4c3c9e543f8a9ff59fa Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 29 Jun 2024 20:13:44 +0200 Subject: [PATCH 03/16] truncate cross to 41 width --- data/json/ascii_art/graveyard.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/json/ascii_art/graveyard.json b/data/json/ascii_art/graveyard.json index d217c5a456dca..883821246dc1b 100644 --- a/data/json/ascii_art/graveyard.json +++ b/data/json/ascii_art/graveyard.json @@ -8,12 +8,12 @@ " > _ _ (", " | |_) | |_) |", " | | \\ | | |", - " ______.__%_| |_________ __", - " _/ \\| |", - "| <", - "| |", - "| |", - "|_____.-._____ __/|_________|", + " ______.__%_| |________ __", + " _/ \\| |", + "| <", + "| |", + "| |", + "|_____.-._____ _/|_________|", " | |", " | |", " | <", From 0ab0bf7e30ca6346dc11d98de490087aa0df252c Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 29 Jun 2024 20:14:32 +0200 Subject: [PATCH 04/16] load death screens --- src/death_screen.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/death_screen.h | 7 +++++-- src/game.cpp | 2 +- src/init.cpp | 2 ++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/death_screen.cpp diff --git a/src/death_screen.cpp b/src/death_screen.cpp new file mode 100644 index 0000000000000..84b238b1b28f1 --- /dev/null +++ b/src/death_screen.cpp @@ -0,0 +1,38 @@ +#include "assign.h" +#include "condition.h" +#include "death_screen.h" +#include "generic_factory.h" + +namespace +{ +generic_factory death_screen_factory( "death_screen" ); +} // namespace + +template<> +const death_screen &string_id::obj()const +{ + return death_screen_factory.obj( *this ); +} + +template<> +bool string_id::is_valid() const +{ + return death_screen_factory.is_valid( *this ); +} + +void death_screen::load_death_screen( const JsonObject &jo, const std::string &src ) +{ + death_screen_factory.load( jo, src ); +} + +void death_screen::load( const JsonObject &jo, std::string_view ) +{ + mandatory( jo, was_loaded, "id", id ); + mandatory( jo, was_loaded, "picture_id", picture_id ); + read_condition( jo, "condition", condition, false ); +} + +const std::vector &death_screen::get_all() +{ + return death_screen_factory.get_all(); +} diff --git a/src/death_screen.h b/src/death_screen.h index 565bc077db589..1224807c5cec9 100644 --- a/src/death_screen.h +++ b/src/death_screen.h @@ -5,6 +5,8 @@ #include #include +#include "ascii_art.h" +#include "effect_on_condition.h" #include "type_id.h" class JsonObject; @@ -13,13 +15,14 @@ class death_screen { public: static void load_death_screen( const JsonObject &jo, const std::string &src ); - static void reset(); void load( const JsonObject &jo, std::string_view ); + static const std::vector& get_all(); bool was_loaded = false; death_screen_id id; - std::string picture; + ascii_art_id picture_id; + std::function condition; }; #endif // CATA_SRC_DEATH_SCREEN_H diff --git a/src/game.cpp b/src/game.cpp index 5b89319f27991..d018476cead04 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2816,7 +2816,7 @@ void game::bury_screen() const iOffset ); draw_border( w_rip ); - const ascii_art_id art = static_cast("battery_motorbike"); + const ascii_art_id art = static_cast("ascii_rip_cross"); if( art.is_valid() ) { int row = 1; for( const std::string &line : art->picture ) { diff --git a/src/init.cpp b/src/init.cpp index 0bb49026b1952..cf929b36a495b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,6 +31,7 @@ #include "construction_group.h" #include "crafting_gui.h" #include "creature.h" +#include "death_screen.h" #include "debug.h" #include "dialogue.h" #include "disease.h" @@ -298,6 +299,7 @@ void DynamicDataLoader::initialize() add( "scent_type", &scent_type::load_scent_type ); add( "disease_type", &disease_type::load_disease_type ); add( "ascii_art", &ascii_art::load_ascii_art ); + add( "death_screen", &death_screen::load_death_screen ); // json/colors.json would be listed here, but it's loaded before the others (see init_colors()) // Non Static Function Access From 698d845a7ef3509c3a2b6337a05a641a7eef9cb8 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sun, 30 Jun 2024 12:12:24 +0200 Subject: [PATCH 05/16] rename death_screen to end_screen --- src/death_screen.cpp | 38 ---------------------------- src/end_screen.cpp | 38 ++++++++++++++++++++++++++++ src/{death_screen.h => end_screen.h} | 8 +++--- src/init.cpp | 4 +-- src/type_id.h | 6 ++--- 5 files changed, 47 insertions(+), 47 deletions(-) delete mode 100644 src/death_screen.cpp create mode 100644 src/end_screen.cpp rename src/{death_screen.h => end_screen.h} (69%) diff --git a/src/death_screen.cpp b/src/death_screen.cpp deleted file mode 100644 index 84b238b1b28f1..0000000000000 --- a/src/death_screen.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "assign.h" -#include "condition.h" -#include "death_screen.h" -#include "generic_factory.h" - -namespace -{ -generic_factory death_screen_factory( "death_screen" ); -} // namespace - -template<> -const death_screen &string_id::obj()const -{ - return death_screen_factory.obj( *this ); -} - -template<> -bool string_id::is_valid() const -{ - return death_screen_factory.is_valid( *this ); -} - -void death_screen::load_death_screen( const JsonObject &jo, const std::string &src ) -{ - death_screen_factory.load( jo, src ); -} - -void death_screen::load( const JsonObject &jo, std::string_view ) -{ - mandatory( jo, was_loaded, "id", id ); - mandatory( jo, was_loaded, "picture_id", picture_id ); - read_condition( jo, "condition", condition, false ); -} - -const std::vector &death_screen::get_all() -{ - return death_screen_factory.get_all(); -} diff --git a/src/end_screen.cpp b/src/end_screen.cpp new file mode 100644 index 0000000000000..5107d4d2ea8b4 --- /dev/null +++ b/src/end_screen.cpp @@ -0,0 +1,38 @@ +#include "assign.h" +#include "condition.h" +#include "end_screen.h" +#include "generic_factory.h" + +namespace +{ +generic_factory end_screen_factory( "end_screen" ); +} // namespace + +template<> +const end_screen &string_id::obj()const +{ + return end_screen_factory.obj( *this ); +} + +template<> +bool string_id::is_valid() const +{ + return end_screen_factory.is_valid( *this ); +} + +void end_screen::load_end_screen( const JsonObject &jo, const std::string &src ) +{ + end_screen_factory.load( jo, src ); +} + +void end_screen::load( const JsonObject &jo, std::string_view ) +{ + mandatory( jo, was_loaded, "id", id ); + mandatory( jo, was_loaded, "picture_id", picture_id ); + read_condition( jo, "condition", condition, false ); +} + +const std::vector &end_screen::get_all() +{ + return end_screen_factory.get_all(); +} diff --git a/src/death_screen.h b/src/end_screen.h similarity index 69% rename from src/death_screen.h rename to src/end_screen.h index 1224807c5cec9..34d9e40e6aada 100644 --- a/src/death_screen.h +++ b/src/end_screen.h @@ -11,16 +11,16 @@ class JsonObject; -class death_screen +class end_screen { public: - static void load_death_screen( const JsonObject &jo, const std::string &src ); + static void load_end_screen( const JsonObject &jo, const std::string &src ); void load( const JsonObject &jo, std::string_view ); - static const std::vector& get_all(); + static const std::vector &get_all(); bool was_loaded = false; - death_screen_id id; + end_screen_id id; ascii_art_id picture_id; std::function condition; }; diff --git a/src/init.cpp b/src/init.cpp index cf929b36a495b..e13963ea6c0af 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,13 +31,13 @@ #include "construction_group.h" #include "crafting_gui.h" #include "creature.h" -#include "death_screen.h" #include "debug.h" #include "dialogue.h" #include "disease.h" #include "effect.h" #include "effect_on_condition.h" #include "emit.h" +#include "end_screen.h" #include "event_statistics.h" #include "faction.h" #include "fault.h" @@ -299,7 +299,7 @@ void DynamicDataLoader::initialize() add( "scent_type", &scent_type::load_scent_type ); add( "disease_type", &disease_type::load_disease_type ); add( "ascii_art", &ascii_art::load_ascii_art ); - add( "death_screen", &death_screen::load_death_screen ); + add( "end_screen", &end_screen::load_end_screen ); // json/colors.json would be listed here, but it's loaded before the others (see init_colors()) // Non Static Function Access diff --git a/src/type_id.h b/src/type_id.h index 7fccb23d1a281..d3164eee1d3b6 100644 --- a/src/type_id.h +++ b/src/type_id.h @@ -79,9 +79,6 @@ using damage_type_id = string_id; struct damage_info_order; using damage_info_order_id = string_id; -struct death_screen; -using death_screen_id = string_id; - class disease_type; using diseasetype_id = string_id; @@ -91,6 +88,9 @@ using emit_id = string_id; class enchantment; using enchantment_id = string_id; +struct end_screen; +using end_screen_id = string_id; + class event_statistic; using event_statistic_id = string_id; From be14a15c65e445a4e46606539d56c01af61805a6 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sun, 30 Jun 2024 18:28:45 +0200 Subject: [PATCH 06/16] WIP migrate the window to ImGUI --- src/game.cpp | 90 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index d018476cead04..c7948228a8a49 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -53,6 +53,7 @@ #include "bodypart.h" #include "butchery_requirements.h" #include "cached_options.h" +#include "cata_imgui.h" #include "cata_path.h" #include "cata_scope_helpers.h" #include "cata_utility.h" @@ -87,6 +88,7 @@ #include "editmap.h" #include "effect.h" #include "effect_on_condition.h" +#include "end_screen.h" #include "enums.h" #include "event.h" #include "event_bus.h" @@ -106,6 +108,7 @@ #include "get_version.h" #include "harvest.h" #include "iexamine.h" +#include "imgui/imgui.h" #include "init.h" #include "input.h" #include "input_context.h" @@ -2799,30 +2802,79 @@ bool game::is_game_over() return false; } -void game::bury_screen() const -{ - avatar &u = get_avatar(); +class end_screen_data; - std::vector vRip; +class end_screen_data +{ + friend class end_screen_ui_impl; + public: + void draw_end_screen_ui(); +}; - int iMaxWidth = 41; - int iStartX = FULL_SCREEN_WIDTH / 2 - ( ( iMaxWidth - 4 ) / 2 ); - int iNameLine = 15; +class end_screen_ui_impl : public cataimgui::window +{ + end_screen_data &parent; + public: + explicit end_screen_ui_impl( end_screen_data &parent ) : cataimgui::window( _( "End Screen" ) ), + parent( parent ) { + } + protected: + void draw_controls() override; +}; - const point iOffset( TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0, - TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ); +void end_screen_data::draw_end_screen_ui() +{ + input_context ctxt; + ctxt.register_action( "QUIT" ); + end_screen_ui_impl p_impl( *this ); + bool stay_open = true; + while( stay_open ) { + ui_manager::redraw_invalidated(); + std::string action = ctxt.handle_input(); + if( action == "QUIT" || !p_impl.get_is_open() ) { + break; + } + } +} - catacurses::window w_rip = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, - iOffset ); - draw_border( w_rip ); +void end_screen_ui_impl::draw_controls() +{ + avatar &u = get_avatar(); + ascii_art_id art = static_cast( "1st_aid" ); + dialogue d( get_talker_for( &u ), nullptr ); + for( const end_screen &e_screen : end_screen::get_all() ) { + if( e_screen.condition( d ) ) { + art = e_screen.picture_id; + } + } - const ascii_art_id art = static_cast("ascii_rip_cross"); if( art.is_valid() ) { int row = 1; for( const std::string &line : art->picture ) { - fold_and_print( w_rip, point( 1, row++ ), 41, c_white, line ); + draw_colored_text( line ); } } +} + +void game::bury_screen() const +{ + avatar &u = get_avatar(); + + std::vector vRip; + + //int iMaxWidth = 41; + //int iStartX = FULL_SCREEN_WIDTH / 2 - ( ( iMaxWidth - 4 ) / 2 ); + //int iNameLine = 15; + + //const point iOffset( TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0, + // TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ); + + //catacurses::window w_rip = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, + // iOffset ); + //draw_border( w_rip ); + + end_screen_data new_instance; + new_instance.draw_end_screen_ui(); sfx::do_player_death_hurt( get_player_character(), true ); sfx::fade_audio_group( sfx::group::weather, 2000 ); @@ -2830,11 +2882,11 @@ void game::bury_screen() const sfx::fade_audio_group( sfx::group::context_themes, 2000 ); sfx::fade_audio_group( sfx::group::sleepiness, 2000 ); - std::string sLastWords = string_input_popup() - .window( w_rip, point( iStartX, iNameLine ), iStartX + iMaxWidth - 4 - 1 ) - .max_length( iMaxWidth - 4 - 1 ) - .query_string(); - + //std::string sLastWords = string_input_popup() + // .window( w_rip, point( iStartX, iNameLine ), iStartX + iMaxWidth - 4 - 1 ) + // .max_length( iMaxWidth - 4 - 1 ) + // .query_string(); + std::string sLastWords = "baba"; const bool is_suicide = uquit == QUIT_SUICIDE; get_event_bus().send( u.getID(), u.name, u.male, is_suicide, sLastWords ); From 739d52a62033ce1847d77bae2bc98102d73de203 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Wed, 3 Jul 2024 18:36:24 +0200 Subject: [PATCH 07/16] and tlak tags --- doc/NPCs.md | 2 ++ src/npctalk.cpp | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/doc/NPCs.md b/doc/NPCs.md index d2a910c2f70a8..c7aeb7570fc57 100644 --- a/doc/NPCs.md +++ b/doc/NPCs.md @@ -356,6 +356,8 @@ Field | Used for... `` | displays npc's current activity `` | displays a random punctuation from: `.`, `…`, `!` `` | displays npc's pronoun +`` | total kills of the Player +`` | time since start of the game `` | referenced item `` | referenced item unit price `` | TODO Add diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 95de6f3e67983..0d7181b4f3838 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -48,6 +48,7 @@ #include "item.h" #include "item_category.h" #include "itype.h" +#include "kill_tracker.h" #include "line.h" #include "magic.h" #include "map.h" @@ -2280,6 +2281,26 @@ void parse_tags( std::string &phrase, const talker &u, const talker &me, const d cityname = c->name; } phrase.replace( fa, l, cityname ); + } else if( tag.find( "" ) == 0 ) { + std::string time_survived; + const time_duration survived = calendar::turn - calendar::start_of_game; + const int minutes = to_minutes( survived ) % 60; + const int hours = to_hours( survived ) % 24; + const int days = to_days( survived ); + if( days > 0 ) { + // NOLINTNEXTLINE(cata-translate-string-literal) + time_survived = string_format( "%dd %dh %dm", days, hours, minutes ); + } else if( hours > 0 ) { + // NOLINTNEXTLINE(cata-translate-string-literal) + time_survived = string_format( "%dh %dm", hours, minutes ); + } else { + // NOLINTNEXTLINE(cata-translate-string-literal) + time_survived = string_format( "%dm", minutes ); + } + phrase.replace( fa, l, time_survived ); + } else if( tag.find( "" ) == 0 ) { + const std::string total_kills = std::to_string( g->get_kill_tracker().monster_kill_count() ); + phrase.replace( fa, l, total_kills ); } else if( !tag.empty() ) { debugmsg( "Bad tag. '%s' (%d - %d)", tag.c_str(), fa, fb ); phrase.replace( fa, fb - fa + 1, "????" ); From a49db66bb30b373d385a35312515460f95198429 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Wed, 3 Jul 2024 22:53:20 +0200 Subject: [PATCH 08/16] Finish port to ImGui and jsonization infrastructure --- data/json/ascii_art/graveyard.json | 27 ++++++++++ src/end_screen.cpp | 3 ++ src/end_screen.h | 2 + src/game.cpp | 84 ++++++++++++++++-------------- 4 files changed, 76 insertions(+), 40 deletions(-) diff --git a/data/json/ascii_art/graveyard.json b/data/json/ascii_art/graveyard.json index 883821246dc1b..8877613d4a782 100644 --- a/data/json/ascii_art/graveyard.json +++ b/data/json/ascii_art/graveyard.json @@ -26,5 +26,32 @@ " .%%%@@@|% ` % @@@%%@%%%%", " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" ] + }, + { + "type": "ascii_art", + "id": "ascii_tombstone", + "picture": [ + " _________ ____ ", + " _/ `/ \\_ ", + " _/ _ _ \\_. ", + " _%\\ |_) | |_) \\_ ", + " _/ \/ | \\ | | \\_ ", + " _/ \\_ ", + "| |", + " ) < ", + "| |", + "| |", + "| _ |", + "|__/ |", + " / `--. |", + "| ( ", + "| |", + "| |", + "| % . |", + "| @` %% |", + "| %@%@%\\ * %`%@%|", + "%%@@@.%@%\\%% `\\ %%.%%@@%@", + "@%@@%%%%%@@@@@@%%%%%%%%@@%%@@@%%%@%%@" + ] } ] diff --git a/src/end_screen.cpp b/src/end_screen.cpp index 5107d4d2ea8b4..7eea8434c5513 100644 --- a/src/end_screen.cpp +++ b/src/end_screen.cpp @@ -30,6 +30,9 @@ void end_screen::load( const JsonObject &jo, std::string_view ) mandatory( jo, was_loaded, "id", id ); mandatory( jo, was_loaded, "picture_id", picture_id ); read_condition( jo, "condition", condition, false ); + + optional( jo, was_loaded, "added_info", added_info ); + optional( jo, was_loaded, "last_words_label", last_words_label ); } const std::vector &end_screen::get_all() diff --git a/src/end_screen.h b/src/end_screen.h index 34d9e40e6aada..59ca80be57664 100644 --- a/src/end_screen.h +++ b/src/end_screen.h @@ -23,6 +23,8 @@ class end_screen end_screen_id id; ascii_art_id picture_id; std::function condition; + std::vector, std::string>> added_info; + std::string last_words_label; }; #endif // CATA_SRC_DEATH_SCREEN_H diff --git a/src/game.cpp b/src/game.cpp index c7948228a8a49..d5c5fb6df94f8 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -289,9 +289,6 @@ static const itype_id fuel_type_animal( "animal" ); static const itype_id itype_battery( "battery" ); static const itype_id itype_disassembly( "disassembly" ); static const itype_id itype_grapnel( "grapnel" ); -static const itype_id itype_holybook_bible1( "holybook_bible1" ); -static const itype_id itype_holybook_bible2( "holybook_bible2" ); -static const itype_id itype_holybook_bible3( "holybook_bible3" ); static const itype_id itype_manhole_cover( "manhole_cover" ); static const itype_id itype_remotevehcontrol( "remotevehcontrol" ); static const itype_id itype_rope_30( "rope_30" ); @@ -346,7 +343,6 @@ static const ter_str_id ter_t_pit( "t_pit" ); static const ter_str_id ter_t_pit_shallow( "t_pit_shallow" ); static const trait_id trait_BADKNEES( "BADKNEES" ); -static const trait_id trait_CANNIBAL( "CANNIBAL" ); static const trait_id trait_CENOBITE( "CENOBITE" ); static const trait_id trait_ILLITERATE( "ILLITERATE" ); static const trait_id trait_INATTENTIVE( "INATTENTIVE" ); @@ -359,7 +355,6 @@ static const trait_id trait_M_IMMUNE( "M_IMMUNE" ); static const trait_id trait_NPC_STARTING_NPC( "NPC_STARTING_NPC" ); static const trait_id trait_NPC_STATIC_NPC( "NPC_STATIC_NPC" ); static const trait_id trait_PROF_CHURL( "PROF_CHURL" ); -static const trait_id trait_PSYCHOPATH( "PSYCHOPATH" ); static const trait_id trait_THICKSKIN( "THICKSKIN" ); static const trait_id trait_VINES2( "VINES2" ); static const trait_id trait_VINES3( "VINES3" ); @@ -2813,10 +2808,9 @@ class end_screen_data class end_screen_ui_impl : public cataimgui::window { - end_screen_data &parent; public: - explicit end_screen_ui_impl( end_screen_data &parent ) : cataimgui::window( _( "End Screen" ) ), - parent( parent ) { + std::array text; + explicit end_screen_ui_impl() : cataimgui::window( _( "End Screen" ) ) { } protected: void draw_controls() override; @@ -2825,54 +2819,73 @@ class end_screen_ui_impl : public cataimgui::window void end_screen_data::draw_end_screen_ui() { input_context ctxt; - ctxt.register_action( "QUIT" ); - end_screen_ui_impl p_impl( *this ); - bool stay_open = true; - while( stay_open ) { + ctxt.register_action( "TEXT.CONFIRM" ); +#if defined(WIN32) || defined(TILES) + ctxt.set_timeout( 50 ); +#endif + end_screen_ui_impl p_impl; + + while( true ) { ui_manager::redraw_invalidated(); std::string action = ctxt.handle_input(); - if( action == "QUIT" || !p_impl.get_is_open() ) { + if( action == "TEXT.CONFIRM" || !p_impl.get_is_open() ) { break; } } + avatar &u = get_avatar(); + const bool is_suicide = g->uquit == QUIT_SUICIDE; + get_event_bus().send( u.getID(), u.name, u.male, is_suicide, + std::string( p_impl.text.data() ) ); } void end_screen_ui_impl::draw_controls() { + text[0] = '\0'; avatar &u = get_avatar(); - ascii_art_id art = static_cast( "1st_aid" ); - dialogue d( get_talker_for( &u ), nullptr ); + ascii_art_id art = static_cast( "ascii_tombstone" ); + dialogue d( get_talker_for( u ), nullptr ); + std::string input_label; + std::vector, std::string>> added_info; for( const end_screen &e_screen : end_screen::get_all() ) { if( e_screen.condition( d ) ) { art = e_screen.picture_id; + if( !e_screen.added_info.empty() ) { + added_info = e_screen.added_info; + } + if( !e_screen.last_words_label.empty() ) { + input_label = e_screen.last_words_label; + } } } if( art.is_valid() ) { int row = 1; - for( const std::string &line : art->picture ) { + for( std::string line : art->picture ) { draw_colored_text( line ); + + for( std::pair, std::string> info : added_info ) { + if( row == info.first.second ) { + parse_tags( info.second, u, u ); + ImGui::SameLine( str_width_to_pixels( info.first.first ), 0 ); + draw_colored_text( info.second ); + } + } + row++; } } + + if( !input_label.empty() ) { + ImGui::NewLine(); + draw_colored_text( input_label ); + ImGui::SameLine( str_width_to_pixels( input_label.size() + 2 ), 0 ); + ImGui::InputText( "##LAST_WORD_BOX", text.data(), text.size() ); + ImGui::SetKeyboardFocusHere( -1 ); + } + } void game::bury_screen() const { - avatar &u = get_avatar(); - - std::vector vRip; - - //int iMaxWidth = 41; - //int iStartX = FULL_SCREEN_WIDTH / 2 - ( ( iMaxWidth - 4 ) / 2 ); - //int iNameLine = 15; - - //const point iOffset( TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0, - // TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ); - - //catacurses::window w_rip = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, - // iOffset ); - //draw_border( w_rip ); - end_screen_data new_instance; new_instance.draw_end_screen_ui(); @@ -2881,15 +2894,6 @@ void game::bury_screen() const sfx::fade_audio_group( sfx::group::time_of_day, 2000 ); sfx::fade_audio_group( sfx::group::context_themes, 2000 ); sfx::fade_audio_group( sfx::group::sleepiness, 2000 ); - - //std::string sLastWords = string_input_popup() - // .window( w_rip, point( iStartX, iNameLine ), iStartX + iMaxWidth - 4 - 1 ) - // .max_length( iMaxWidth - 4 - 1 ) - // .query_string(); - std::string sLastWords = "baba"; - const bool is_suicide = uquit == QUIT_SUICIDE; - get_event_bus().send( u.getID(), u.name, u.male, is_suicide, - sLastWords ); } void game::death_screen() From b9b5c7282c054f07d8821786a76b03554df40ab5 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Fri, 5 Jul 2024 19:06:10 +0200 Subject: [PATCH 09/16] Use priority value to chose between multiple end screens with valid conditions --- data/json/ascii_art/graveyard.json | 26 +++++++++++++------------- src/end_screen.cpp | 1 + src/end_screen.h | 1 + src/game.cpp | 11 ++++++++++- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/data/json/ascii_art/graveyard.json b/data/json/ascii_art/graveyard.json index 8877613d4a782..bf52626e6b436 100644 --- a/data/json/ascii_art/graveyard.json +++ b/data/json/ascii_art/graveyard.json @@ -8,7 +8,7 @@ " > _ _ (", " | |_) | |_) |", " | | \\ | | |", - " ______.__%_| |________ __", + " ______.__%_| |________ __", " _/ \\| |", "| <", "| |", @@ -20,11 +20,11 @@ " | |", " | _ |", " |__/ |", - " % / `--. |%", - " * .%%| -< @%%%", - " `\\%`@| |@@%@%%", - " .%%%@@@|% ` % @@@%%@%%%%", - " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" + " % / `--. |%", + " * .%%| -< @%%%", + " `\\%`@| |@@%@%%", + " .%%%@@@|% ` % @@@%%@%%%%", + " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" ] }, { @@ -34,8 +34,8 @@ " _________ ____ ", " _/ `/ \\_ ", " _/ _ _ \\_. ", - " _%\\ |_) | |_) \\_ ", - " _/ \/ | \\ | | \\_ ", + " _%\\ |_) | |_) \\_ ", + " _/ \\/ | \\ | | \\_ ", " _/ \\_ ", "| |", " ) < ", @@ -47,11 +47,11 @@ "| ( ", "| |", "| |", - "| % . |", - "| @` %% |", - "| %@%@%\\ * %`%@%|", - "%%@@@.%@%\\%% `\\ %%.%%@@%@", - "@%@@%%%%%@@@@@@%%%%%%%%@@%%@@@%%%@%%@" + "| % . |", + "| @` %% |", + "| %@%@%\\ * %`%@%|", + "%%@@@.%@%\\%% `\\ %%.%%@@%@", + "@%@@%%%%%@@@@@@%%%%%%%%@@%%@@@%%%@%%@" ] } ] diff --git a/src/end_screen.cpp b/src/end_screen.cpp index 7eea8434c5513..3d1c6507b4b17 100644 --- a/src/end_screen.cpp +++ b/src/end_screen.cpp @@ -29,6 +29,7 @@ void end_screen::load( const JsonObject &jo, std::string_view ) { mandatory( jo, was_loaded, "id", id ); mandatory( jo, was_loaded, "picture_id", picture_id ); + mandatory( jo, was_loaded, "priority", priority ); read_condition( jo, "condition", condition, false ); optional( jo, was_loaded, "added_info", added_info ); diff --git a/src/end_screen.h b/src/end_screen.h index 59ca80be57664..f9337125ce160 100644 --- a/src/end_screen.h +++ b/src/end_screen.h @@ -23,6 +23,7 @@ class end_screen end_screen_id id; ascii_art_id picture_id; std::function condition; + int priority; std::vector, std::string>> added_info; std::string last_words_label; }; diff --git a/src/game.cpp b/src/game.cpp index d5c5fb6df94f8..7ed9b1c03bfd9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2846,7 +2846,15 @@ void end_screen_ui_impl::draw_controls() dialogue d( get_talker_for( u ), nullptr ); std::string input_label; std::vector, std::string>> added_info; - for( const end_screen &e_screen : end_screen::get_all() ) { + + //Sort end_screens in order of decreasing priority + std::vector sorted_screens = end_screen::get_all(); + std::sort( sorted_screens.begin(), sorted_screens.end(), []( end_screen const & a, + end_screen const & b ) { + return a.priority > b.priority; + } ); + + for( const end_screen &e_screen : sorted_screens ) { if( e_screen.condition( d ) ) { art = e_screen.picture_id; if( !e_screen.added_info.empty() ) { @@ -2855,6 +2863,7 @@ void end_screen_ui_impl::draw_controls() if( !e_screen.last_words_label.empty() ) { input_label = e_screen.last_words_label; } + break; } } From ca32af8133149e7e541b96f7a3a94b83b60b47e5 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Fri, 5 Jul 2024 21:40:09 +0200 Subject: [PATCH 10/16] finish porting existing screens to json --- data/json/ascii_art/graveyard.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/data/json/ascii_art/graveyard.json b/data/json/ascii_art/graveyard.json index bf52626e6b436..99e7665fd1c66 100644 --- a/data/json/ascii_art/graveyard.json +++ b/data/json/ascii_art/graveyard.json @@ -27,6 +27,34 @@ " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" ] }, + { + "type": "ascii_art", + "id": "ascii_rip_inverted_cross", + "picture": [ + " _______ ___", + " | \\/ |", + " | |", + " | |", + " | |", + " | |", + " | |", + " | |", + " | <", + " | _ |", + " |__/ |", + " _____.__%_| |_________ _", + " _/ \\| \\", + "| <", + "| |", + "| |", + "|____.-._______ __/|__________|", + " % / `_-. _ |%", + " * .%%| |_) | |_)< @%%%", + " `\\%`@| | \\ | | |@@%@%%", + " .%%%@@@|% ` % @@@%%@%%%%", + " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" + ] + }, { "type": "ascii_art", "id": "ascii_tombstone", From ac6db289017901304d0e9488512918cccdcc0fac Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Fri, 5 Jul 2024 22:34:27 +0200 Subject: [PATCH 11/16] documentation --- doc/JSON_INFO.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index ae5fc10e484ac..8d8a5cccdba08 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -39,6 +39,7 @@ Use the `Home` key to return to the top. - [Damage Info Ordering](#damage-info-ordering) - [Dreams](#dreams) - [Disease](#disease) + - [End Screen](#end-screen) - [Emitters](#emitters) - [Item Groups](#item-groups) - [Item Category](#item-category) @@ -1512,6 +1513,41 @@ Using `damage_info_order` we can reorder how these are shown, and even determine } ``` +### End Screen + +| Identifier | Description +|--- |--- +| `id` | (_mandatory_) Unique ID. Must be one continuous word, use underscores if necessary. +| `priority` | (_mandatory_) Int used to chose among several end sreens with valid conditions, higher value have higher priority. Priority 0 is the default tombstone end. +| `picture_id` | (_mandatory_) ID of an ascii art, see #Ascii_arts. +| `condition` | (_mandatory_) Conditions necessary to display this end screen. See the "Dialogue conditions" section of [NPCs](NPCs.md) for the full syntax. +| `added_info` | (_optional_) Vector of pairs of a pair of int character offset and Line number and a string to be written on the end screen. The string can use talk tags, see the "Special Custom Entries" section of [NPCs](NPCs.md) for the full syntax. +| `last_words_label` | (_optional_) String used to label the last word input prompt. If left empty no prompt will be displayed. + +```json + { + "type": "end_screen", + "id": "death_cross", + "priority": 1, + "picture_id": "ascii_rip_cross", + "condition": { + "and": [ + { "not": "u_is_alive" }, + { + "or": [ { "u_has_item": "holybook_bible1" }, { "u_has_item": "holybook_bible2" }, { "u_has_item": "holybook_bible3" } ] + }, + { "not": { "and": [ { "u_has_trait": "CANNIBAL" }, { "u_has_trait": "PSYCHOPATH" } ] } } + ] + }, + "added_info": [ + [ [ 8, 8 ], "In memory of: " ], + [ [ 15, 9 ], "Survived: " ], + [ [ 17, 10 ], "Kills: " ] + ], + "last_words_label": "Last Words:" + } +``` + ### Emitters Emitters randomly place [fields](#field-types) around their positions - every turn for monster emissions, every ten seconds for furniture/terrain. From 36629e96a68973ef28217df352ea5c0aab2c5cac Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 6 Jul 2024 17:34:10 +0200 Subject: [PATCH 12/16] Winning! --- data/json/ascii_art/graveyard.json | 28 +++++++++ data/json/effects.json | 6 ++ data/json/end_screen.json | 64 ++++++++++++++++++++ data/json/npcs/EOC_talkers/portal_storm.json | 8 ++- src/game.cpp | 2 +- 5 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 data/json/end_screen.json diff --git a/data/json/ascii_art/graveyard.json b/data/json/ascii_art/graveyard.json index 99e7665fd1c66..e23da83c1129d 100644 --- a/data/json/ascii_art/graveyard.json +++ b/data/json/ascii_art/graveyard.json @@ -81,5 +81,33 @@ "%%@@@.%@%\\%% `\\ %%.%%@@%@", "@%@@%%%%%@@@@@@%%%%%%%%@@%%@@@%%%@%%@" ] + }, + { + "type": "ascii_art", + "id": "ascii_portal_storm_win", + "picture": [ + " ", + " | ", + " -.- ", + " | ", + " ", + " ", + " | ", + " _._ ", + " | ", + " ", + " ", + " ", + " | ", + " -.- ", + " | ", + " ", + " | ", + " _._ ", + " | ", + " ", + " ", + " " + ] } ] diff --git a/data/json/effects.json b/data/json/effects.json index 7aca1e9932648..9da88a13a9bf1 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -4985,5 +4985,11 @@ "desc": [ "Applied by leap special attack of burned frog zombies, conditional for related spell." ], "max_duration": "5 m", "show_in_info": true + }, + { + "type": "effect_type", + "id": "a_winner_is_u", + "name": [ "Winning!" ], + "//": "Used to display the winning screen upon winning like a winner." } ] diff --git a/data/json/end_screen.json b/data/json/end_screen.json new file mode 100644 index 0000000000000..1efee7e185a8a --- /dev/null +++ b/data/json/end_screen.json @@ -0,0 +1,64 @@ +[ + { + "type": "end_screen", + "id": "death_tombstone", + "priority": 0, + "picture_id": "ascii_tombstone", + "condition": { "not": "u_is_alive" }, + "added_info": [ + [ [ 6, 8 ], "In memory of: " ], + [ [ 13, 9 ], "Survived: " ], + [ [ 15, 10 ], "Kills: " ] + ], + "last_words_label": "Last Words:" + }, + { + "type": "end_screen", + "id": "death_cross", + "priority": 1, + "picture_id": "ascii_rip_cross", + "condition": { + "and": [ + { "not": "u_is_alive" }, + { + "or": [ { "u_has_item": "holybook_bible1" }, { "u_has_item": "holybook_bible2" }, { "u_has_item": "holybook_bible3" } ] + }, + { "not": { "and": [ { "u_has_trait": "CANNIBAL" }, { "u_has_trait": "PSYCHOPATH" } ] } } + ] + }, + "added_info": [ + [ [ 8, 8 ], "In memory of: " ], + [ [ 15, 9 ], "Survived: " ], + [ [ 17, 10 ], "Kills: " ] + ], + "last_words_label": "Last Words:" + }, + { + "type": "end_screen", + "id": "death_inverted_cross", + "priority": 1, + "picture_id": "ascii_rip_inverted_cross", + "condition": { "and": [ { "not": "u_is_alive" }, { "or": [ { "u_has_trait": "CANNIBAL" }, { "u_has_trait": "PSYCHOPATH" } ] } ] }, + "added_info": [ + [ [ 8, 14 ], "In memory of: " ], + [ [ 15, 15 ], "Survived: " ], + [ [ 17, 16 ], "Kills: " ] + ], + "last_words_label": "Last Words:" + }, + { + "type": "end_screen", + "id": "portal_storm_win", + "priority": 2, + "picture_id": "ascii_portal_storm_win", + "condition": { "and": [ { "not": "u_is_alive" }, { "u_has_effect": "a_winner_is_u" } ] }, + "added_info": [ + [ [ 6, 6 ], "You won" ], + [ [ 8, 7 ], "..." ], + [ [ 4, 10 ], "..., who's that?" ], + [ [ 15, 11 ], "Not your problem anymore." ], + [ [ 9, 15 ], "What a success." ], + [ [ 4, 21 ], "Something struggled for: " ] + ] + } +] diff --git a/data/json/npcs/EOC_talkers/portal_storm.json b/data/json/npcs/EOC_talkers/portal_storm.json index 6a2b1c9a54466..a7e7eb62c9a49 100644 --- a/data/json/npcs/EOC_talkers/portal_storm.json +++ b/data/json/npcs/EOC_talkers/portal_storm.json @@ -109,6 +109,12 @@ "type": "talk_topic", "id": "TALK_PORTAL_STORM_WILL_IT", "dynamic_line": "&You do not exist anymore. Something else exists elsewhere, and vaguely remembers being you. Its (torment?/joy?/confusion?/freedom?) will never truly end.", - "responses": [ { "text": "An ending? The cataclysm was bad but was this better?", "topic": "TALK_DONE", "effect": [ "u_die" ] } ] + "responses": [ + { + "text": "An ending? The cataclysm was bad but was this better?", + "topic": "TALK_DONE", + "effect": [ "u_die", { "u_add_effect": "a_winner_is_u", "duration": "PERMANENT" } ] + } + ] } ] diff --git a/src/game.cpp b/src/game.cpp index 7ed9b1c03bfd9..7cfea3ad4d76c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2810,7 +2810,7 @@ class end_screen_ui_impl : public cataimgui::window { public: std::array text; - explicit end_screen_ui_impl() : cataimgui::window( _( "End Screen" ) ) { + explicit end_screen_ui_impl() : cataimgui::window( _( "The End" ) ) { } protected: void draw_controls() override; From 6524c6ef2661af074fb1b727fac2b7a1eeae1834 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 6 Jul 2024 18:43:38 +0200 Subject: [PATCH 13/16] update string parser --- lang/string_extractor/parser.py | 2 ++ lang/string_extractor/parsers/end_screen.py | 8 ++++++++ 2 files changed, 10 insertions(+) create mode 100644 lang/string_extractor/parsers/end_screen.py diff --git a/lang/string_extractor/parser.py b/lang/string_extractor/parser.py index 24ff1470e1237..589e204481c61 100644 --- a/lang/string_extractor/parser.py +++ b/lang/string_extractor/parser.py @@ -17,6 +17,7 @@ from .parsers.effect import parse_effect_on_condition from .parsers.effect_type import parse_effect_type from .parsers.enchant import parse_enchant +from .parsers.end_screen import parse_end_screen from .parsers.event_statistic import parse_event_statistic from .parsers.faction import parse_faction from .parsers.fault import parse_fault @@ -137,6 +138,7 @@ def dummy_parser(json, origin): "effect_type": parse_effect_type, "emit": dummy_parser, "enchantment": parse_enchant, + "end_screen": parse_end_screen, "engine": parse_generic, "event_statistic": parse_event_statistic, "event_transformation": dummy_parser, diff --git a/lang/string_extractor/parsers/end_screen.py b/lang/string_extractor/parsers/end_screen.py new file mode 100644 index 0000000000000..db3935de0f187 --- /dev/null +++ b/lang/string_extractor/parsers/end_screen.py @@ -0,0 +1,8 @@ +from ..write_text import write_text + + +def parse_end_screen(json, origin): + if "last_words_label" in json: + write_text(json["last_words_label"], origin, + comment="String used to label the last word input prompt." + "ex: \"Last Words:\")") From 40fc35015cc9ee1d2757617a9dc44fbc1e4fa1ca Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 6 Jul 2024 19:08:15 +0200 Subject: [PATCH 14/16] fix struct / class discrepency --- src/end_screen.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/end_screen.h b/src/end_screen.h index f9337125ce160..78d092c3da818 100644 --- a/src/end_screen.h +++ b/src/end_screen.h @@ -11,8 +11,7 @@ class JsonObject; -class end_screen -{ +struct end_screen { public: static void load_end_screen( const JsonObject &jo, const std::string &src ); From 2608d4f6578136c4bb3441c1c49a4635913eb0b0 Mon Sep 17 00:00:00 2001 From: Fris0uman <41293484+Fris0uman@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:15:32 +0200 Subject: [PATCH 15/16] Use bigger number for priority to leave more space in between Co-authored-by: Anton Simakov <67688115+GuardianDll@users.noreply.github.com> --- data/json/end_screen.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/json/end_screen.json b/data/json/end_screen.json index 1efee7e185a8a..4189a56a228bf 100644 --- a/data/json/end_screen.json +++ b/data/json/end_screen.json @@ -15,7 +15,7 @@ { "type": "end_screen", "id": "death_cross", - "priority": 1, + "priority": 100, "picture_id": "ascii_rip_cross", "condition": { "and": [ @@ -36,7 +36,7 @@ { "type": "end_screen", "id": "death_inverted_cross", - "priority": 1, + "priority": 100, "picture_id": "ascii_rip_inverted_cross", "condition": { "and": [ { "not": "u_is_alive" }, { "or": [ { "u_has_trait": "CANNIBAL" }, { "u_has_trait": "PSYCHOPATH" } ] } ] }, "added_info": [ @@ -49,7 +49,7 @@ { "type": "end_screen", "id": "portal_storm_win", - "priority": 2, + "priority": 200, "picture_id": "ascii_portal_storm_win", "condition": { "and": [ { "not": "u_is_alive" }, { "u_has_effect": "a_winner_is_u" } ] }, "added_info": [ From 5afc762217dd9bdb267e7411c3e3e3db2b09650c Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Mon, 8 Jul 2024 14:04:42 +0200 Subject: [PATCH 16/16] tidying --- src/game.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 7cfea3ad4d76c..f2a1c1ecd2b5d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -230,6 +230,8 @@ static const activity_id ACT_TRAIN_TEACHER( "ACT_TRAIN_TEACHER" ); static const activity_id ACT_TRAVELLING( "ACT_TRAVELLING" ); static const activity_id ACT_VIEW_RECIPE( "ACT_VIEW_RECIPE" ); +static const ascii_art_id ascii_tombstone( "ascii_tombstone" ); + static const bionic_id bio_jointservo( "bio_jointservo" ); static const bionic_id bio_probability_travel( "bio_probability_travel" ); static const bionic_id bio_remote( "bio_remote" ); @@ -2842,7 +2844,7 @@ void end_screen_ui_impl::draw_controls() { text[0] = '\0'; avatar &u = get_avatar(); - ascii_art_id art = static_cast( "ascii_tombstone" ); + ascii_art_id art = ascii_tombstone; dialogue d( get_talker_for( u ), nullptr ); std::string input_label; std::vector, std::string>> added_info; @@ -2869,7 +2871,7 @@ void end_screen_ui_impl::draw_controls() if( art.is_valid() ) { int row = 1; - for( std::string line : art->picture ) { + for( const std::string &line : art->picture ) { draw_colored_text( line ); for( std::pair, std::string> info : added_info ) {