Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions data/raw/keybindings.json
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,17 @@
"name": "Scroll down spell info",
"bindings": [ { "input_method": "keyboard_char", "key": ">" }, { "input_method": "keyboard_code", "key": ".", "mod": [ "shift" ] } ]
},
{
"type": "keybinding",
"id": "SCROLL_FAVORITE",
"category": "SPELL_MENU",
"name": "Toggle spell as favorite",
"bindings": [
{ "input_method": "keyboard_char", "key": "*" },
{ "input_method": "keyboard_code", "key": "KEYPAD_MULTIPLY" },
{ "input_method": "keyboard_code", "key": "8", "mod": [ "shift" ] }
]
},
{
"type": "keybinding",
"id": "ADD_RULE",
Expand Down
58 changes: 54 additions & 4 deletions src/magic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,7 @@ void known_magic::serialize( JsonOut &json ) const
}
json.end_array();
json.member( "invlets", invlets );
json.member( "favorites", favorites );

json.end_object();
}
Expand All @@ -1846,6 +1847,7 @@ void known_magic::deserialize( const JsonObject &data )
}
}
data.read( "invlets", invlets );
data.read( "favorites", favorites );
}

bool known_magic::knows_spell( const std::string &sp ) const
Expand Down Expand Up @@ -2156,6 +2158,19 @@ std::vector<spell> Character::spells_known_of_class( const trait_id &spell_class
return ret;
}

static void reflesh_favorite( uilist *menu, std::vector<spell *> known_spells )
{
for( uilist_entry &entry : menu->entries ) {
if( get_player_character().magic->is_favorite( known_spells[entry.retval]->id() ) ) {
entry.extratxt.left = 0;
entry.extratxt.txt = _( "*" );
entry.extratxt.color = c_white;
} else {
entry.extratxt.txt = "";
}
}
}

class spellcasting_callback : public uilist_callback
{
private:
Expand All @@ -2167,14 +2182,14 @@ class spellcasting_callback : public uilist_callback
void draw_spell_info( const uilist *menu );
public:
// invlets reserved for special functions
const std::set<int> reserved_invlets{ 'I', '=' };
const std::set<int> reserved_invlets{ 'I', '=', '*' };
bool casting_ignore;

spellcasting_callback( std::vector<spell *> &spells,
bool casting_ignore ) : known_spells( spells ),
casting_ignore( casting_ignore ) {}
bool key( const input_context &ctxt, const input_event &event, int entnum,
uilist * /*menu*/ ) override {
uilist *menu ) override {
const std::string &action = ctxt.input_to_action( event );
if( action == "CAST_IGNORE" ) {
casting_ignore = !casting_ignore;
Expand All @@ -2198,6 +2213,9 @@ class spellcasting_callback : public uilist_callback
return true;
} else if( action == "SCROLL_UP_SPELL_MENU" || action == "SCROLL_DOWN_SPELL_MENU" ) {
scroll_pos += action == "SCROLL_DOWN_SPELL_MENU" ? 1 : -1;
} else if( action == "SCROLL_FAVORITE" ) {
get_player_character().magic->toggle_favorite( known_spells[entnum]->id() );
reflesh_favorite( menu, known_spells );
}
return false;
}
Expand Down Expand Up @@ -2522,6 +2540,20 @@ void known_magic::rem_invlet( const spell_id &sp )
invlets.erase( sp );
}

void known_magic::toggle_favorite( const spell_id &sp )
{
if( favorites.count( sp ) > 0 ) {
favorites.erase( sp );
} else {
favorites.emplace( sp );
}
}

bool known_magic::is_favorite( const spell_id &sp )
{
return favorites.count( sp ) > 0;
}

int known_magic::get_invlet( const spell_id &sp, std::set<int> &used_invlets )
{
auto found = invlets.find( sp );
Expand Down Expand Up @@ -2575,20 +2607,37 @@ int known_magic::select_spell( Character &guy )
spell_menu.additional_actions.emplace_back( "CAST_IGNORE", translation() );
spell_menu.additional_actions.emplace_back( "SCROLL_UP_SPELL_MENU", translation() );
spell_menu.additional_actions.emplace_back( "SCROLL_DOWN_SPELL_MENU", translation() );
spell_menu.additional_actions.emplace_back( "SCROLL_FAVORITE", translation() );
spell_menu.hilight_disabled = true;
spellcasting_callback cb( known_spells, casting_ignore );
spell_menu.callback = &cb;
spell_menu.add_category( "all", _( "All" ) );
spell_menu.add_category( "favorites", _( "Favorites" ) );

std::vector<std::pair<std::string, std::string>> categories;
for( const spell *s : known_spells ) {
if( s->can_cast( guy ) && s->spell_class().is_valid() ) {
spell_menu.add_category( s->spell_class().str(), s->spell_class().obj().name() );
categories.emplace_back( s->spell_class().str(), s->spell_class().obj().name() );
std::sort( categories.begin(), categories.end(), []( const std::pair<std::string, std::string> &a,
const std::pair<std::string, std::string> &b ) {
return localized_compare( a.second, b.second );
} );
const auto itr = std::unique( categories.begin(), categories.end() );
categories.erase( itr, categories.end() );
}
}
spell_menu.set_category_filter( [known_spells]( const uilist_entry & entry,
for( std::pair<std::string, std::string> &cat : categories ) {
spell_menu.add_category( cat.first, cat.second );
}

spell_menu.set_category_filter( [&guy, known_spells]( const uilist_entry & entry,
const std::string & key )->bool {
if( key == "all" )
{
return true;
} else if( key == "favorites" )
{
return guy.magic->is_favorite( known_spells[entry.retval]->id() );
}
return known_spells[entry.retval]->spell_class().is_valid() && known_spells[entry.retval]->spell_class().str() == key;
} );
Expand All @@ -2600,6 +2649,7 @@ int known_magic::select_spell( Character &guy )
spell_menu.addentry( static_cast<int>( i ), known_spells[i]->can_cast( guy ),
get_invlet( known_spells[i]->id(), used_invlets ), known_spells[i]->name() );
}
reflesh_favorite( &spell_menu, known_spells );

spell_menu.query();

Expand Down
5 changes: 5 additions & 0 deletions src/magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ class known_magic
std::map<spell_id, spell> spellbook;
// invlets assigned to spell_id
std::map<spell_id, int> invlets;
// list of favorite spells
std::unordered_set<spell_id> favorites;
// the base mana a Character would start with
int mana_base = 0; // NOLINT(cata-serialize)
// current mana
Expand Down Expand Up @@ -697,6 +699,9 @@ class known_magic
// returns false if invlet is already used
bool set_invlet( const spell_id &sp, int invlet, const std::set<int> &used_invlets );
void rem_invlet( const spell_id &sp );

void toggle_favorite( const spell_id &sp );
bool is_favorite( const spell_id &sp );
private:
// gets length of longest spell name
int get_spellname_max_width();
Expand Down
12 changes: 4 additions & 8 deletions src/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,10 @@ input_context uilist::create_main_input_context() const
ctxt.register_action( "SELECT" );
}
ctxt.register_action( "UILIST.FILTER" );
ctxt.register_action( "UILIST.LEFT" );
ctxt.register_action( "UILIST.RIGHT" );
if( !categories.empty() ) {
ctxt.register_action( "UILIST.LEFT" );
ctxt.register_action( "UILIST.RIGHT" );
}
ctxt.register_action( "ANY_INPUT" );
ctxt.register_action( "HELP_KEYBINDINGS" );
uilist_scrollbar->set_draggable( ctxt );
Expand Down Expand Up @@ -1267,12 +1269,6 @@ void uilist::set_selected( int index )
void uilist::add_category( const std::string &key, const std::string &name )
{
categories.emplace_back( key, name );
std::sort( categories.begin(), categories.end(), []( const std::pair<std::string, std::string> &a,
const std::pair<std::string, std::string> &b ) {
return localized_compare( a.second, b.second );
} );
const auto itr = std::unique( categories.begin(), categories.end() );
categories.erase( itr, categories.end() );
}

void uilist::set_category( const std::string &key )
Expand Down