Skip to content

Commit

Permalink
Merge branch 'ImguifyHelpMenu' into ImguifyHelpMenu
Browse files Browse the repository at this point in the history
  • Loading branch information
Procyonae authored Dec 15, 2024
2 parents e720f0d + 5eec260 commit db4cae5
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 92 deletions.
48 changes: 34 additions & 14 deletions data/core/help.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,25 @@
"order": 1,
"name": "Movement",
"messages": [
"Movement is performed using the numpad, the arrow keys, or vikeys.",
"<HELP_DRAW_DIRECTIONS>",
"Movement is typically performed using the numpad, vikeys, the mouse or arrow keys. Here are the layouts for numpad and vikeys, where the central bind is to wait in place:",
{
"force_monospaced": "<color_light_blue>7 8 9 y k u\n \\|/ \\|/ \n4-5-6 h-.-l\n /|\\ /|\\ \n1 2 3 b j n\n"
},
"Movement is also possible using the arrow keys by first enabling the \"Diagonal movement with cursor keys and modifiers\" setting in the Interface tab to one of these four modes:",
"- Numpad Emulation: In this mode you hold Ctrl throughout, first pressing a direction which will then modify further key presses to be in altered by that direction, for example if you first press Up, then further Left, Up, Right and Down presses will become NW, N, NE, and wait respectively.",
{
"force_monospaced": "<color_light_blue> After Up After Right\n N NE\n NW O NE O SE E\n"
},
"- CW/CCW: In this mode holding Shift modifies each key 45 degrees clockwise while holding Ctrl modifies each key 45 degrees counter-clockwise.",
{
"force_monospaced": "<color_light_blue> With Shift With Ctrl\n NE NW\n NW SW SE SW SE NE\n"
},
"- L/R Tilt: In this mode holding Shift/Ctrl makes Left and Right behave as NW/SW and NE/SE respectively. Up and Down behave normally regardless of modifiers.",
{
"force_monospaced": "<color_light_blue> With Shift With Ctrl\n N NW\n NW S NE SW S SE\n"
},
"- Diagonal Lock: In this mode holding Shift or Ctrl results in only diagonal combinations of two directions being accepted for example Ctrl + Up + Right becomes NE.",
{ "seperator": "color_green" },
"Each step will take 100 movement points (or more, depending on the terrain); you will then replenish a variable amount of movement points, depending on many factors (press <press_player_data> to see the exact amount).",
"To attempt to hit a monster with your weapon, simply move into it.",
"You may find doors, ('+'); these may be opened with <press_open> or closed with <press_close>. Some doors are locked. Locked doors, windows, and some other obstacles can be destroyed by smashing them (<press_smash>, then choose a direction). Smashing down obstacles is much easier with a good weapon or a strong character.",
Expand Down Expand Up @@ -276,18 +293,23 @@
{
"type": "help",
"order": 19,
"name": "Description of map symbols",
"name": "Overmap key",
"messages": [
"MAP SYMBOLS:",
"OVERMAP SYMBOLS:",
"<color_brown>.</color> Field - Empty grassland with occasional wild fruit.",
"<color_brown>,</color> Meadow - .",
"<color_green>F</color> Forest - May be dense or sparse. Movement will be slowed. You might be able to forage for food here.",
"<color_dark_gray>│─└┌┐┘├┴┤┬┼</color> Road - Safe from burrowing animals.",
"<color_dark_gray>H=</color> Highway - Like roads, but lined with guard rails.",
"<color_dark_gray>|-</color> Bridge - Helps you cross rivers.",
"<color_blue>R</color> River - Most creatures cannot swim across them, but you can.",
"<color_dark_gray>O</color> Parking lot - Empty lot, few items. Mostly useless.",
"<color_light_green>^>v<</color> House - Filled with a variety of items. Good place to sleep.",
"<color_light_blue>^>v<</color> Gas station - A good place to collect gasoline. Risk of explosion.",
"<color_green>│─└┌┐┘├┴┤┬┼</color> Forest Trail - A path through the forest. Faster and more open than walking through the forest proper. Consider breaking line of sight through the forest if anything does catch up with you.",
"<color_brown>T</color> Trailhead - The start of a trail. If you're lucky you'll find a map and maybe even a working vehicle here.",
"<color_cyan>F</color> Freshwater Swamp - .",
"<color_dark_gray>│─└┌┐┘├┴┤┬┼</color> Road - Safe from burrowing animals.",
"><color_blue>-</color>< Roadbridge - Helps you cross rivers.",
"<color_light_blue>.</color> Stream - A small body of water that you can drive over.",
"<color_light_blue>R</color><color_blue>R</color> River - Most creatures cannot swim across them, but you can.",
"<color_light_blue>#</color><color_blue>#</color> Lake/Ocean - .",
"<color_light_gray>X</color> Radio Tower - A tall tower useful for getting a good view of the surrounding area. Beware any fauna that may have made its home here.",
"<color_light_green>^>v<</color> House - Come in many forms. Good place to find basic supplies and everyday tools.",
"<color_light_blue>^>v<</color> Gas station - A good place to collect gasoline.",
"<color_light_red>^>v<</color> Pharmacy - The best source for vital medications.",
"<color_green>^>v<</color> Grocery store - A good source of canned food and other supplies.",
"<color_cyan>^>v<</color> Hardware store - Home to tools, melee weapons and crafting goods.",
Expand All @@ -296,9 +318,7 @@
"<color_red>^>v<</color> Gun store - Firearms and ammunition are very valuable.",
"<color_blue>^>v<</color> Clothing store - High-capacity clothing, some light armor.",
"<color_brown>^>v<</color> Library - Home to books, both entertaining and informative.",
"<color_white>^>v<</color> Man-made buildings - The pointed side indicates the front door.",
" There are many others out there… search for them!",
"<DRAW_NOTE_COLORS>"
"<color_white>^>v<</color> Man-made buildings - The pointed side indicates the front door."
]
},
{
Expand Down
1 change: 1 addition & 0 deletions doc/HELP_MENU.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
BEFOREMERGE Update
# Help Menu

The help menu consists of scrollable categorised help pages that would ideally explain everything a new survivor needs to know, as well as any information the game can't convey clearly in an immersive way.
Expand Down
143 changes: 71 additions & 72 deletions src/help.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ void help::reset_instance()
read_categories.clear();
}

enum message_modifier {
MM_NORMAL = 0, // Normal message
MM_SUBTITLE, // Formatted subtitle
MM_MONOFONT, // Forced monofont for fixed space diagrams
MM_SEPERATOR // ImGui seperator, value is the color to use
};

void help::load_object( const JsonObject &jo, const std::string &src )
{
if( src == "dda" ) {
Expand All @@ -59,60 +66,32 @@ void help::load_object( const JsonObject &jo, const std::string &src )
current_order_start = help_categories.empty() ? 0 : help_categories.crbegin()->first + 1;
current_src = src;
}

help_category category;
jo.read( "messages", category.paragraphs );

translation name;
jo.read( "name", category.name );
const int modified_order = jo.get_int( "order" ) + current_order_start;
if( !help_categories.try_emplace( modified_order, category ).second ) {
jo.throw_error_at( "order", "\"order\" must be unique per source" );
}
}

std::string help_window::get_dir_grid()
{
static const std::array<action_id, 9> movearray = {{
ACTION_MOVE_FORTH_LEFT, ACTION_MOVE_FORTH, ACTION_MOVE_FORTH_RIGHT,
ACTION_MOVE_LEFT, ACTION_PAUSE, ACTION_MOVE_RIGHT,
ACTION_MOVE_BACK_LEFT, ACTION_MOVE_BACK, ACTION_MOVE_BACK_RIGHT
}
};

std::string movement = "<LEFTUP_0> <UP_0> <RIGHTUP_0> <LEFTUP_1> <UP_1> <RIGHTUP_1>\n"
" \\ | / \\ | /\n"
" \\|/ \\|/\n"
"<LEFT_0>--<pause_0>--<RIGHT_0> <LEFT_1>--<pause_1>--<RIGHT_1>\n"
" /|\\ /|\\\n"
" / | \\ / | \\\n"
"<LEFTDOWN_0> <DOWN_0> <RIGHTDOWN_0> <LEFTDOWN_1> <DOWN_1> <RIGHTDOWN_1>";

for( action_id dir : movearray ) {
std::vector<input_event> keys = keys_bound_to( dir, /*maximum_modifier_count=*/0 );
for( size_t i = 0; i < 2; i++ ) {
movement = string_replace( movement, "<" + action_ident( dir ) + string_format( "_%d>", i ),
i < keys.size()
? string_format( "<color_light_blue>%s</color>",
keys[i].short_description() )
: "<color_red>?</color>" );
for( JsonValue jv : jo.get_array( "messages" ) ) {
if( jv.test_string() ) {
category.paragraphs.emplace_back( to_translation( jv.get_string() ), MM_NORMAL );
} else {
JsonObject jobj = jv.get_object();
if( jobj.has_string( "subtitle" ) ) {
category.paragraphs.emplace_back( to_translation( jobj.get_string( "subtitle" ) ), MM_SUBTITLE );
} else if( jobj.has_string( "force_monospaced" ) ) {
category.paragraphs.emplace_back( to_translation( jobj.get_string( "force_monospaced" ) ),
MM_MONOFONT );
} else if( jobj.has_string( "seperator" ) ) {
category.paragraphs.emplace_back( no_translation( jobj.get_string( "seperator" ) ), MM_SEPERATOR );
}
}
}

return movement;
}

void help_window::note_colors()
{
ImGui::TextUnformatted( _( "Note colors: " ) );
ImGui::SameLine( 0.f, 0.f );
for( const auto &color_pair : get_note_color_names() ) {
// The color index is not translatable, but the name is.
//~ %1$s: note color abbreviation, %2$s: note color name
cataimgui::TextColoredParagraph( c_white, string_format( pgettext( "note color", "%1$s:%2$s, " ),
colorize( color_pair.first, color_pair.second.color ),
color_pair.second.name ) );
// TODO: Has a stray comma at the end
ImGui::SameLine( 0.f, 0.f );
const int modified_order = jo.get_int( "order" ) + current_order_start;
if( !help_categories.try_emplace( modified_order, category ).second ) {
jo.throw_error_at( "order", "\"order\" must be unique per source" );
}
}

Expand Down Expand Up @@ -191,6 +170,10 @@ void help_window::draw_category_option( const int &option, const help_category &
}
cat_name += category.name.translated();
if( data.read_categories.find( option ) != data.read_categories.end() ) {
if( screen_reader ) {
//~ Prefix for options that has already been viewed when using a screen reader
cat_name = _( "(read) " ) + cat_name;
}
ImGui::PushStyleColor( ImGuiCol_Text, c_light_gray );
ImGui::Selectable( remove_color_tags( cat_name ).c_str() );
ImGui::PopStyleColor();
Expand All @@ -204,7 +187,7 @@ void help_window::draw_category_option( const int &option, const help_category &

void help_window::format_title( const std::string translated_category_name )
{
if( get_option<bool>( "SCREEN_READER_MODE" ) ) {
if( screen_reader ) {
cataimgui::TextColoredParagraph( c_white, translated_category_name );
ImGui::NewLine();
return;
Expand Down Expand Up @@ -298,48 +281,64 @@ void help_window::draw_category()
cataimgui::set_scroll( s );
ImGui::TableNextRow();
ImGui::TableNextColumn();
for( const std::string &translated_paragraph : translated_paragraphs ) {
if( translated_paragraph == "<DRAW_NOTE_COLORS>" ) {
note_colors();
continue;
} else if( translated_paragraph == "<HELP_DRAW_DIRECTIONS>" ) {
static const std::string dir_grid = get_dir_grid();
cataimgui::draw_colored_text( dir_grid );
continue;
for( const std::pair<std::string, int> &translated_paragraph :
translated_paragraphs ) {
switch( translated_paragraph.second ) {
case MM_NORMAL:
cataimgui::TextColoredParagraph( c_white, translated_paragraph.first );
break;
case MM_SUBTITLE:
// BEFOREMERGE: Do something different
cataimgui::TextColoredParagraph( c_white, translated_paragraph.first );
break;
case MM_MONOFONT:
cataimgui::PushMonoFont();
cataimgui::TextColoredParagraph( c_white, translated_paragraph.first );
ImGui::PopFont();
break;
// Causing a missing EndChild() ImGui crash?
//case MM_SEPERATOR: {
// nc_color col = get_all_colors().name_to_color( translated_paragraph.first );
// ImGui::PushStyleColor( ImGuiCol_Separator, cataimgui::imvec4_from_color( col ) );
// ImGui::Separator();
// ImGui::PopStyleColor();
// break;
//}
// Temporary until crash is worked out
case MM_SEPERATOR:
ImGui::Separator();
break;
default:
debugmsg( "Unexpected help message modifier" );
continue;
}
cataimgui::TextColoredParagraph( c_white, translated_paragraph );
ImGui::NewLine();
ImGui::NewLine();
}
ImGui::EndTable();
}
}

// Would ideally be merged with parse_tags()?
void help_window::parse_tags_help_window()
// Would ideally share parse_tags() code for keybinds
void help_window::parse_keybind_tags()
{
for( std::string &translated_paragraph : translated_paragraphs ) {
if( translated_paragraph == "<DRAW_NOTE_COLORS>" ) {
continue;
} else if( translated_paragraph == "<HELP_DRAW_DIRECTIONS>" ) {
continue;
}
size_t pos = translated_paragraph.find( "<press_", 0, 7 );
for( std::pair<std::string, int> &translated_paragraph : translated_paragraphs ) {
std::string &text = translated_paragraph.first;
size_t pos = text.find( "<press_", 0, 7 );
while( pos != std::string::npos ) {
size_t pos2 = translated_paragraph.find( ">", pos, 1 );
size_t pos2 = text.find( ">", pos, 1 );

std::string action = translated_paragraph.substr( pos + 7, pos2 - pos - 7 );
std::string action = text.substr( pos + 7, pos2 - pos - 7 );
std::string replace = "<color_light_blue>" +
press_x( look_up_action( action ), "", "" ) + "</color>";

if( replace.empty() ) {
debugmsg( "Help json: Unknown action: %s", action );
} else {
translated_paragraph = string_replace( translated_paragraph, "<press_" + std::move( action ) + ">",
replace );
text = string_replace( text, "<press_" + std::move( action ) + ">", replace );
}

pos = translated_paragraph.find( "<press_", pos2, 7 );
pos = text.find( "<press_", pos2, 7 );
}
}
}
Expand Down Expand Up @@ -413,10 +412,10 @@ void help_window::swap_translated_paragraphs()
{
translated_paragraphs.clear();
const help_category &cat = data.help_categories[loaded_option];
for( const translation &paragraph : cat.paragraphs ) {
translated_paragraphs.emplace_back( paragraph.translated() );
for( const std::pair<translation, int> &paragraph : cat.paragraphs ) {
translated_paragraphs.emplace_back( paragraph.first.translated(), paragraph.second );
}
parse_tags_help_window();
parse_keybind_tags();
}

std::string get_hint()
Expand Down
8 changes: 3 additions & 5 deletions src/help.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class window;

struct help_category {
translation name;
std::vector<translation> paragraphs;
std::vector<std::pair<translation, int>> paragraphs;
};

class help
Expand Down Expand Up @@ -68,12 +68,10 @@ class help_window : public cataimgui::window
int loaded_option;

void swap_translated_paragraphs();
std::vector<std::string> translated_paragraphs;
void parse_tags_help_window();
std::vector<std::pair<std::string, int>> translated_paragraphs;
void parse_keybind_tags();

void draw_category();
void note_colors();
std::string get_dir_grid();
cataimgui::scroll s;
};

Expand Down
4 changes: 3 additions & 1 deletion src/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2029,7 +2029,9 @@ void options_manager::add_options_interface()
* Example 3: Press → while holding Shift and ← results in input rejection
*/
to_translation( "Allows diagonal movement with cursor keys using CTRL and SHIFT modifiers. Diagonal movement action keys are taken from keybindings, so you need these to be configured." ), { { "none", to_translation( "None" ) }, { "mode1", to_translation( "Mode 1: Numpad Emulation" ) }, { "mode2", to_translation( "Mode 2: CW/CCW" ) }, { "mode3", to_translation( "Mode 3: L/R Tilt" ) }, { "mode4", to_translation( "Mode 4: Diagonal Lock" ) } },
// BEFOREMERGE: Check if this works with curses
to_translation( "Allows diagonal movement with cursor keys using CTRL and SHIFT modifiers. Diagonal movement action keys are taken from keybindings, so you need these to be configured. See the movement category in the help menu for full descriptions of the options." ),
{ { "none", to_translation( "None" ) }, { "mode1", to_translation( "Mode 1: Numpad Emulation" ) }, { "mode2", to_translation( "Mode 2: CW/CCW" ) }, { "mode3", to_translation( "Mode 3: L/R Tilt" ) }, { "mode4", to_translation( "Mode 4: Diagonal Lock" ) } },
"none", COPT_CURSES_HIDE );

add_empty_line();
Expand Down

0 comments on commit db4cae5

Please sign in to comment.