diff --git a/proj/vs2013/Common/Common.vcxproj b/proj/vs2013/Common/Common.vcxproj index 71c9ff94..bc97548a 100644 --- a/proj/vs2013/Common/Common.vcxproj +++ b/proj/vs2013/Common/Common.vcxproj @@ -326,6 +326,7 @@ + diff --git a/proj/vs2013/Common/Common.vcxproj.filters b/proj/vs2013/Common/Common.vcxproj.filters index 88d46cb6..46c45f6b 100644 --- a/proj/vs2013/Common/Common.vcxproj.filters +++ b/proj/vs2013/Common/Common.vcxproj.filters @@ -978,6 +978,9 @@ DialogXML\Dialogs + + Tools + diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index e3ec2344..1691788d 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -35,6 +35,7 @@ #include "shop.hpp" #include "prefs.hpp" #include "render_shapes.hpp" +#include "tools/enum_map.hpp" rectangle bottom_buttons[14]; rectangle item_screen_button_rects[9] = { @@ -53,20 +54,17 @@ rectangle medium_buttons[4] = { {383, 227, 401, 263}, {402, 227,420, 263} }; -rectangle item_buttons[8][6]; -// name, use, give, drip, info, sell/id -rectangle pc_buttons[6][5]; -// name, hp, sp, info, trade - -extern rectangle startup_button[6]; -extern rectangle win_to_rects[6]; +enum_map(eItemButton, rectangle) item_buttons[8]; +enum_map(ePlayerButton, rectangle) pc_buttons[6]; +extern enum_map(eStartButton, rectangle) startup_button; +extern enum_map(eGuiArea, rectangle) win_to_rects; extern bool flushingInput; extern bool fog_lifted; extern bool cartoon_happening; rectangle startup_top; -bool item_area_button_active[8][6]; -bool pc_area_button_active[6][5]; +enum_map(eItemButton, bool) item_area_button_active[8]; +enum_map(ePlayerButton, bool) pc_area_button_active[6]; short item_bottom_button_active[9] = {0,0,0,0,0, 0,1,1,1}; rectangle pc_help_button; @@ -80,8 +78,9 @@ short store_selling_values[8] = {0,0,0,0,0,0,0,0}; extern cShop active_shop; extern rectangle shop_frame; -extern short cen_x, cen_y, stat_window;//,pc_moves[6]; +extern short cen_x, cen_y;//,pc_moves[6]; extern eGameMode overall_mode; +extern eItemWinMode stat_window; extern location to_create; extern bool All_Done,spell_forced,monsters_going; extern bool party_in_memory; @@ -119,7 +118,7 @@ cCreature save_monster_type; short wand_loc_count = 0; short monst_place_count = 0; // 1 - standard place 2 - place last -rectangle shopping_rects[8][7]; +enum_map(eShopArea, rectangle) shopping_rects[8]; std::queue special_queue; bool end_scenario = false; bool current_bash_is_bash = false; @@ -131,8 +130,7 @@ void init_screen_locs() { rectangle startup_base = {281,1,329,302}; rectangle shop_base = {63,12,99,267}; - for(short i = 0; i < 7; i++) - shopping_rects[0][i] = shop_base; + std::fill(shopping_rects[0].begin(), shopping_rects[0].end(), shop_base); shopping_rects[0][SHOPRECT_ACTIVE_AREA].right -= 35; shopping_rects[0][SHOPRECT_GRAPHIC].right = shopping_rects[0][SHOPRECT_GRAPHIC].left + 28; shopping_rects[0][SHOPRECT_ITEM_NAME].top += 4; @@ -147,15 +145,15 @@ void init_screen_locs() { shopping_rects[0][SHOPRECT_ITEM_HELP].right -= 19; shopping_rects[0][SHOPRECT_ITEM_HELP].left = shopping_rects[0][SHOPRECT_ITEM_HELP].right - 14; for(short i = 1; i < 8; i++) - for(short j = 0; j < 7; j++) { + for(auto& j : shopping_rects[i].keys()) { shopping_rects[i][j] = shopping_rects[0][j]; shopping_rects[i][j].offset(0,i * 36); } - for(short i = 0; i < 6; i++) { - startup_button[i] = startup_base; - startup_button[i].offset(301 * (i / 3), 48 * (i % 3)); + for(auto btn : startup_button.keys()) { + startup_button[btn] = startup_base; + startup_button[btn].offset(301 * (btn / 3), 48 * (btn % 3)); } startup_top.top = 7; startup_top.bottom = startup_button[STARTBTN_LOAD].top; @@ -167,7 +165,7 @@ void init_screen_locs() { item_buttons[0][ITEMBTN_NAME].bottom = item_buttons[0][ITEMBTN_NAME].top + 12; item_buttons[0][ITEMBTN_NAME].left = 3; item_buttons[0][ITEMBTN_NAME].right = item_buttons[0][ITEMBTN_NAME].left + 185; - item_buttons[0][ITEMBTN_USE] = item_buttons[0][0]; + item_buttons[0][ITEMBTN_USE] = item_buttons[0][ITEMBTN_NAME]; item_buttons[0][ITEMBTN_USE].left = 196; item_buttons[0][ITEMBTN_USE].right = 210; item_buttons[0][ITEMBTN_GIVE] = item_buttons[0][ITEMBTN_NAME]; @@ -184,7 +182,7 @@ void init_screen_locs() { item_buttons[0][ITEMBTN_SPEC].right = 232; item_buttons[0][ITEMBTN_NAME].top += 3; for(short i = 1; i < 8; i++) - for(short j = 0; j < 6; j++) { + for(auto j : item_buttons[i].keys()) { item_buttons[i][j] = item_buttons[0][j]; item_buttons[i][j].offset(0,13 * i); } @@ -221,7 +219,7 @@ void init_screen_locs() { pc_buttons[0][PCBTN_TRADE].right = 262; pc_buttons[0][PCBTN_NAME].top += 3; for(short i = 1; i < 6; i++) - for(short j = 0; j < 5; j++) { + for(auto j : pc_buttons[i].keys()) { pc_buttons[i][j] = pc_buttons[0][j]; pc_buttons[i][j].offset(0,13 * i); } @@ -648,14 +646,14 @@ static void handle_switch_pc(short which_pc, bool& need_redraw) { draw_terrain(); univ.cur_pc = which_pc; combat_next_step(); - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); put_pc_screen(); } else add_string_to_buf("Set active: PC has no APs."); } else if(univ.party[which_pc].main_status != eMainStatus::ALIVE && (overall_mode != MODE_SHOPPING || active_shop.getType() != eShopType::ALLOW_DEAD)) add_string_to_buf("Set active: PC must be here & active."); else { univ.cur_pc = which_pc; - set_stat_window(which_pc); + set_stat_window_for_pc(which_pc); add_string_to_buf("Now " + std::string(overall_mode == MODE_SHOPPING ? "shopping" : "active") + ": " + univ.party[which_pc].name); adjust_spell_menus(); need_redraw = true; @@ -676,7 +674,7 @@ static void handle_switch_pc_items(short which_pc, bool& need_redraw) { need_redraw = true; } } - set_stat_window(which_pc); + set_stat_window_for_pc(which_pc); if(overall_mode == MODE_SHOPPING) { set_up_shop_array(); draw_shop_graphics(0,item_screen_button_rects[which_pc]); // rect is dummy @@ -855,7 +853,7 @@ static void handle_combat_switch(bool& did_something, bool& need_redraw, bool& n handle_wandering_specials(0,1); menu_activate(); put_pc_screen(); - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); } else add_string_to_buf("Can't end combat yet."); } else { eDirection dir = end_town_combat(); @@ -866,7 +864,7 @@ static void handle_combat_switch(bool& did_something, bool& need_redraw, bool& n } univ.party.direction = dir; center = univ.party.town_loc; - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); redraw_screen(REFRESH_TERRAIN | REFRESH_TEXT | REFRESH_STATS); play_sound(93); need_reprint = true; @@ -1245,34 +1243,34 @@ bool handle_action(sf::Event event) { cChoiceDlog("help-party").show(); } for(int i = 0; i < 6; i++) - for(int j = 0; j < 5; j++) + for(auto j : pc_buttons[i].keys()) if(pc_area_button_active[i][j] && point_in_area.in(pc_buttons[i][j])) { - if((j == 1 || j == 2) && !univ.party[i].is_alive()) + if((j == PCBTN_HP || j == PCBTN_SP) && !univ.party[i].is_alive()) break; rectangle button_rect = pc_buttons[i][j]; button_rect.offset(pc_win_ul); arrow_button_click(button_rect); switch(j) { - case 0: + case PCBTN_NAME: handle_switch_pc(i, need_redraw); need_reprint = true; break; - case 1: + case PCBTN_HP: str.str(""); str << univ.party[i].name << " has "; str << univ.party[i].cur_health << " health out of " << univ.party[i].max_health << '.'; add_string_to_buf(str.str()); break; - case 2: + case PCBTN_SP: str.str(""); str << univ.party[i].name << " has "; str << univ.party[i].cur_health << " spell pts. out of " << univ.party[i].max_health << '.'; add_string_to_buf(str.str()); break; - case 3: // pc info + case PCBTN_INFO: give_pc_info(i); break; - case 4: // trade places + case PCBTN_TRADE: if(!prime_time()) add_string_to_buf("Trade places: Finish what you're doing first."); else if(is_combat()) @@ -1288,7 +1286,7 @@ bool handle_action(sf::Event event) { put_item_screen(stat_window); if(overall_mode == MODE_SHOPPING) { set_up_shop_array(); - draw_shop_graphics(0,pc_buttons[0][0]); + draw_shop_graphics(0,pc_buttons[0][PCBTN_NAME]); } } @@ -1322,7 +1320,7 @@ bool handle_action(sf::Event event) { } if(stat_window <= ITEM_WIN_QUESTS) { for(int i = 0; i < 8; i++) - for(int j = 0; j < 6; j++) + for(auto j : item_buttons[i].keys()) if(item_area_button_active[i][j] && point_in_area.in(item_buttons[i][j])) { rectangle button_rect = item_buttons[i][j]; button_rect.offset(item_win_ul); @@ -1330,29 +1328,29 @@ bool handle_action(sf::Event event) { item_hit = item_sbar->getPosition() + i; switch(j) { - case 0: // equip + case ITEMBTN_NAME: // equip handle_equip_item(item_hit, need_redraw); break; - case 1: // use + case ITEMBTN_USE: handle_use_item(item_hit, did_something, need_redraw); break; - case 2: // give + case ITEMBTN_GIVE: handle_give_item(item_hit, did_something, need_redraw); break; - case 3: // drop + case ITEMBTN_DROP: if(stat_window == ITEM_WIN_SPECIAL) { use_spec_item(spec_item_array[item_hit]); need_redraw = true; } else handle_drop_item(item_hit, need_redraw); break; - case 4: // info + case ITEMBTN_INFO: if(stat_window == ITEM_WIN_SPECIAL) put_spec_item_info(spec_item_array[item_hit]); else if(stat_window == ITEM_WIN_QUESTS) put_quest_info(spec_item_array[item_hit]); else display_pc_item(stat_window, item_hit,univ.party[stat_window].items[item_hit],0); break; - case 5: // sell? That this code was reached indicates that the item was sellable + case ITEMBTN_SPEC: // sell? That this code was reached indicates that the item was sellable // (Based on item_area_button_active) handle_item_shop_action(item_hit); break; @@ -1386,7 +1384,7 @@ bool handle_action(sf::Event event) { //pause(2); univ.cur_pc++; combat_next_step(); - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); put_pc_screen(); } @@ -1717,7 +1715,7 @@ bool handle_keystroke(sf::Event& event){ break; case '1': case '2': case '3': case '4': case '5': case '6': - pass_point = pc_buttons[((short) chr) - 49][0].topLeft(); + pass_point = pc_buttons[((short) chr) - 49][PCBTN_NAME].topLeft(); pass_point.x += 1 + win_to_rects[WINRECT_PCSTATS].left; pass_point.y += win_to_rects[WINRECT_PCSTATS].top; pass_point = mainPtr.mapCoordsToPixel(pass_point, mainView); @@ -1779,11 +1777,11 @@ bool handle_keystroke(sf::Event& event){ break; case 'z': // Show active PC's inventory if(((overall_mode >= MODE_COMBAT) && (overall_mode < MODE_TALKING)) || (overall_mode == MODE_LOOK_COMBAT)) { - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); put_item_screen(stat_window); } else { // ... or first PC's inventory... why? - set_stat_window(0); + set_stat_window(ITEM_WIN_PC1); put_item_screen(stat_window); } break; @@ -2203,7 +2201,7 @@ void post_load() { text_sbar->show(); item_sbar->show(); shop_sbar->hide(); - set_stat_window(0); + set_stat_window(ITEM_WIN_PC1); put_pc_screen(); draw_terrain(); draw_buttons(0); @@ -2572,7 +2570,7 @@ void switch_pc(short which) { univ.cur_pc = which; else if(univ.cur_pc == which) univ.cur_pc = current_switch; - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); } else ASB("Switch: Not with self."); current_switch = 6; } @@ -2595,7 +2593,7 @@ void drop_pc(short which) { for(short i = which; i < 5; i++) univ.party.swap_pcs(i, i + 1); univ.party[5].main_status = eMainStatus::ABSENT; - set_stat_window(0); + set_stat_window(ITEM_WIN_PC1); put_pc_screen(); } diff --git a/src/game/boe.combat.cpp b/src/game/boe.combat.cpp index ef33d273..6cf54e02 100644 --- a/src/game/boe.combat.cpp +++ b/src/game/boe.combat.cpp @@ -27,7 +27,7 @@ extern eGameMode overall_mode; extern short which_combat_type; -extern short stat_window; +extern eItemWinMode stat_window; extern location center; extern short combat_active_pc; extern bool monsters_going,spell_forced; @@ -364,7 +364,7 @@ void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short nu center = univ.current_pc().combat_pos; draw_buttons(0); put_pc_screen(); - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); adjust_spell_menus(); @@ -1979,7 +1979,7 @@ bool combat_next_step() { } if((univ.cur_pc != store_pc) || (to_return)) { put_pc_screen(); - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); } return to_return; } diff --git a/src/game/boe.consts.hpp b/src/game/boe.consts.hpp index 1c268857..d3b9355c 100644 --- a/src/game/boe.consts.hpp +++ b/src/game/boe.consts.hpp @@ -77,49 +77,74 @@ enum eTrapType { TRAP_CUSTOM = 13, }; -// Startup button rects -const int STARTBTN_LOAD = 0; -const int STARTBTN_NEW = 1; -const int STARTBTN_ORDER = 2; -const int STARTBTN_JOIN = 3; -const int STARTBTN_CUSTOM = 4; +// Startup buttons +enum eStartButton { + STARTBTN_LOAD = 0, + STARTBTN_NEW = 1, + STARTBTN_ORDER = 2, + STARTBTN_JOIN = 3, + STARTBTN_CUSTOM = 4, + STARTBTN_SCROLL = 5, + MAX_eStartButton // keep last +}; // Shop rects -const int SHOPRECT_WHOLE_AREA = 0; -const int SHOPRECT_ACTIVE_AREA = 1; -const int SHOPRECT_GRAPHIC = 2; -const int SHOPRECT_ITEM_NAME = 3; -const int SHOPRECT_ITEM_COST = 4; -const int SHOPRECT_ITEM_EXTRA = 5; -const int SHOPRECT_ITEM_HELP = 6; +enum eShopArea { + SHOPRECT_WHOLE_AREA = 0, + SHOPRECT_ACTIVE_AREA = 1, + SHOPRECT_GRAPHIC = 2, + SHOPRECT_ITEM_NAME = 3, + SHOPRECT_ITEM_COST = 4, + SHOPRECT_ITEM_EXTRA = 5, + SHOPRECT_ITEM_HELP = 6, + MAX_eShopArea // keep last +}; + +// Item buttons +enum eItemButton { + ITEMBTN_NAME = 0, + ITEMBTN_USE = 1, + ITEMBTN_GIVE = 2, + ITEMBTN_DROP = 3, + ITEMBTN_INFO = 4, + ITEMBTN_SPEC = 5, // Sell, Identify, or Enchant + MAX_eItemButton // keep last +}; -// Item button rects -const int ITEMBTN_NAME = 0; -const int ITEMBTN_USE = 1; -const int ITEMBTN_GIVE = 2; -const int ITEMBTN_DROP = 3; -const int ITEMBTN_INFO = 4; -const int ITEMBTN_SPEC = 5; // Sell, Identify, or Enchant const int ITEMBTN_ALL = 10; // use, give, drop, info const int ITEMBTN_NORM = 11; // give, drop, info -// PC button rects -const int PCBTN_NAME = 0; -const int PCBTN_HP = 1; -const int PCBTN_SP = 2; -const int PCBTN_INFO = 3; -const int PCBTN_TRADE = 4; +// PC buttons +enum ePlayerButton { + PCBTN_NAME = 0, + PCBTN_HP = 1, + PCBTN_SP = 2, + PCBTN_INFO = 3, + PCBTN_TRADE = 4, + MAX_ePlayerButton // keep last +}; // Item window modes (non-PC) -const int ITEM_WIN_SPECIAL = 6; -const int ITEM_WIN_QUESTS = 7; +enum eItemWinMode { + ITEM_WIN_PC1 = 0, + ITEM_WIN_PC2 = 1, + ITEM_WIN_PC3 = 2, + ITEM_WIN_PC4 = 3, + ITEM_WIN_PC5 = 4, + ITEM_WIN_PC6 = 5, + ITEM_WIN_SPECIAL = 6, + ITEM_WIN_QUESTS = 7, +}; // Gobal window rects -const int WINRECT_TERVIEW = 0; -const int WINRECT_ACTBTNS = 1; -const int WINRECT_PCSTATS = 2; -const int WINRECT_INVEN = 3; -const int WINRECT_STATUS = 4; -const int WINRECT_TRANSCRIPT = 5; +enum eGuiArea { + WINRECT_TERVIEW = 0, + WINRECT_ACTBTNS = 1, + WINRECT_PCSTATS = 2, + WINRECT_INVEN = 3, + WINRECT_STATUS = 4, + WINRECT_TRANSCRIPT = 5, + MAX_eGuiArea // keep last +}; #endif diff --git a/src/game/boe.dlgutil.cpp b/src/game/boe.dlgutil.cpp index e0cae6d0..d247ca7d 100644 --- a/src/game/boe.dlgutil.cpp +++ b/src/game/boe.dlgutil.cpp @@ -34,8 +34,9 @@ #include "prefs.hpp" #include "shop.hpp" #include "cursors.hpp" +#include "tools/enum_map.hpp" -extern short stat_window; +extern eItemWinMode stat_window; extern eGameMode overall_mode; extern bool changed_display_mode; extern sf::RenderWindow mainPtr; @@ -87,7 +88,7 @@ extern std::vector talk_words; // n000 + i - magic store n item i // talk_area_rect and talk_help_rect used for this too eGameMode store_pre_shop_mode; -extern rectangle shopping_rects[8][7]; +extern enum_map(eShopArea, rectangle) shopping_rects[8]; rectangle bottom_help_rects[4] = {{356,6,368,250},{374,6,386,270},{386,6,398,250},{398,6,410,250}}; rectangle shop_name_str = {44,6,56,200}; rectangle shop_frame = {62,10,352,269}; diff --git a/src/game/boe.graphics.cpp b/src/game/boe.graphics.cpp index 3241b67a..10c17926 100644 --- a/src/game/boe.graphics.cpp +++ b/src/game/boe.graphics.cpp @@ -18,6 +18,7 @@ #include "sounds.hpp" #include "mathutil.hpp" #include "button.hpp" +#include "tools/enum_map.hpp" #include "boe.party.hpp" #include "boe.town.hpp" @@ -36,7 +37,7 @@ #endif extern sf::RenderWindow mainPtr; -extern short stat_window; +extern eItemWinMode stat_window; extern eGameMode overall_mode; extern short current_spell_range; extern bool anim_onscreen,party_in_memory; @@ -75,12 +76,12 @@ long anim_ticks = 0; // 0 - terrain 1 - buttons 2 - pc stats // 3 - item stats 4 - text bar 5 - text area (not right) -rectangle win_from_rects[6] = {{0,0,350,278},{0,0,37,258},{0,0,115,288},{0,0,143,288},{0,0,21,279},{0,0,0,288}}; -rectangle win_to_rects[6] = {{7,19,358,298},{385,19,423,285},{7,305,123,576},{132,305,276,576},{360,19,381,298},{285,305,423,561}}; +enum_map(eGuiArea, rectangle) win_from_rects = {{0,0,350,278},{0,0,37,258},{0,0,115,288},{0,0,143,288},{0,0,21,279},{0,0,0,288}}; +enum_map(eGuiArea, rectangle) win_to_rects = {{7,19,358,298},{385,19,423,285},{7,305,123,576},{132,305,276,576},{360,19,381,298},{285,305,423,561}}; // 0 - title 1 - button 2 - credits 3 - base button rectangle startup_from[4] = {{0,0,274,602},{274,0,322,301},{0,301,67,579},{274,301,314,341}}; -extern rectangle startup_button[6]; +extern enum_map(eStartButton, rectangle) startup_button; rectangle top_left_rec = {0,0,36,28}; short which_graphic_index[6] = {50,50,50,50,50,50}; @@ -207,9 +208,9 @@ void draw_startup(short but_type) { sf::Texture& startup_gworld = *ResMgr::get("startup"); rect_draw_some_item(startup_gworld,startup_from[0],mainPtr,startup_top); - for(short i = 0; i < 5; i++) { - rect_draw_some_item(startup_gworld,startup_from[1],mainPtr,startup_button[i]); - draw_start_button(i,but_type); + for(auto btn : startup_button.keys()) { + rect_draw_some_item(startup_gworld,startup_from[1],mainPtr,startup_button[btn]); + draw_start_button(btn,but_type); } draw_startup_anim(false); @@ -224,8 +225,8 @@ void draw_startup_anim(bool advance) { anim_from = anim_to; anim_from.offset(-1,-4 + startup_anim_pos); if(advance) startup_anim_pos = (startup_anim_pos + 1) % 542; - rect_draw_some_item(*ResMgr::get("startbut"),anim_size,mainPtr,startup_button[5]); - anim_to.offset(startup_button[5].left, startup_button[5].top); + rect_draw_some_item(*ResMgr::get("startbut"),anim_size,mainPtr,startup_button[STARTBTN_SCROLL]); + anim_to.offset(startup_button[STARTBTN_SCROLL].left, startup_button[STARTBTN_SCROLL].top); rect_draw_some_item(*ResMgr::get("startanim"),anim_from,mainPtr,anim_to,sf::BlendAlpha); } @@ -368,7 +369,7 @@ void draw_startup_stats() { -void draw_start_button(short which_position,short which_button) { +void draw_start_button(eStartButton which_position,short which_button) { rectangle from_rect,to_rect; // TODO: Change third button (Windows calls it "Support and Downloads") const char *button_labels[] = {"Load Game","Make New Party","How To Order", diff --git a/src/game/boe.graphics.hpp b/src/game/boe.graphics.hpp index bcbe278f..0da698d0 100644 --- a/src/game/boe.graphics.hpp +++ b/src/game/boe.graphics.hpp @@ -23,7 +23,7 @@ void reload_startup(); void draw_startup(short but_type); void draw_anim(); void place_anim(); -void draw_start_button(short which_position,short which_button); +void draw_start_button(eStartButton which_position,short which_button); void main_button_click(int which_button); void arrow_button_click(rectangle button_rect); void end_startup(); diff --git a/src/game/boe.items.cpp b/src/game/boe.items.cpp index cdfe7e82..edfd2ebd 100644 --- a/src/game/boe.items.cpp +++ b/src/game/boe.items.cpp @@ -26,8 +26,9 @@ #include "winutil.hpp" #include "cursors.hpp" -extern short stat_window,which_combat_type; +extern short which_combat_type; extern eGameMode overall_mode; +extern eItemWinMode stat_window; extern sf::RenderWindow mainPtr; extern bool boom_anim_active; extern rectangle d_rects[80]; diff --git a/src/game/boe.main.cpp b/src/game/boe.main.cpp index 917aa485..0ef7823f 100644 --- a/src/game/boe.main.cpp +++ b/src/game/boe.main.cpp @@ -30,6 +30,7 @@ #include "cursors.hpp" #include "prefs.hpp" #include "button.hpp" +#include "tools/enum_map.hpp" bool All_Done = false; sf::Event event; @@ -66,7 +67,7 @@ std::vector spec_item_array; short current_spell_range; eGameMode overall_mode = MODE_STARTUP; bool anim_onscreen = false,changed_display_mode = false; -short stat_window = 0; +eItemWinMode stat_window = ITEM_WIN_PC1; bool monsters_going = false,boom_anim_active = false; bool finished_init = false; @@ -626,7 +627,7 @@ static cursor_type get_mode_cursor(){ void change_cursor(location where_curs) { cursor_type cursor_needed; location cursor_direction; - extern rectangle win_to_rects[6]; + extern enum_map(eGuiArea, rectangle) win_to_rects; rectangle world_screen = win_to_rects[WINRECT_TERVIEW]; world_screen.inset(13, 13); diff --git a/src/game/boe.newgraph.cpp b/src/game/boe.newgraph.cpp index d639e4b0..17606407 100644 --- a/src/game/boe.newgraph.cpp +++ b/src/game/boe.newgraph.cpp @@ -27,6 +27,7 @@ #include "button.hpp" #include "res_image.hpp" #include "prefs.hpp" +#include "tools/enum_map.hpp" short monsters_faces[190] = { 0,1,2,3,4,5,6,7,8,9, @@ -72,7 +73,7 @@ extern bool fog_lifted; extern const short alch_difficulty[20]; extern const eItemAbil alch_ingred1[20]; extern const eItemAbil alch_ingred2[20]; -extern rectangle win_to_rects[6]; +extern enum_map(eGuiArea, rectangle) win_to_rects; // Talk vars extern eGameMode store_pre_talk_mode; @@ -88,7 +89,7 @@ std::vector talk_words; // Shop vars extern cShop active_shop; extern eGameMode store_pre_shop_mode; -extern rectangle shopping_rects[8][7]; +extern enum_map(eShopArea, rectangle) shopping_rects[8]; extern rectangle bottom_help_rects[4]; extern rectangle shop_name_str; extern rectangle shop_frame ; diff --git a/src/game/boe.party.cpp b/src/game/boe.party.cpp index 6724a5a0..9f71939f 100644 --- a/src/game/boe.party.cpp +++ b/src/game/boe.party.cpp @@ -56,7 +56,7 @@ bool spell_button_active[90]; extern short fast_bang; extern bool flushingInput; -extern short stat_window; +extern eItemWinMode stat_window; extern eGameMode overall_mode; extern fs::path progDir; extern location center; @@ -186,7 +186,7 @@ void put_party_in_scen(std::string scen_name) { update_explored(univ.scenario.where_start); overall_mode = MODE_TOWN; redraw_screen(REFRESH_ALL); - set_stat_window(0); + set_stat_window(ITEM_WIN_PC1); adjust_spell_menus(); adjust_monst_menu(); @@ -2519,7 +2519,7 @@ void kill_pc(cPlayer& which_pc,eMainStatus type) { if(univ.current_pc().main_status != eMainStatus::ALIVE) univ.cur_pc = first_active_pc(); put_pc_screen(); - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); } void set_pc_moves() { diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index fdb2200f..7797938f 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -34,7 +34,8 @@ extern sf::RenderWindow mainPtr; extern eGameMode overall_mode; -extern short which_combat_type,stat_window; +extern eItemWinMode stat_window; +extern short which_combat_type; extern location center; extern bool processing_fields,monsters_going,boom_anim_active; extern effect_pat_type single,t,square,radius2,radius3,small_square,open_square,field[8]; diff --git a/src/game/boe.startup.cpp b/src/game/boe.startup.cpp index dd5518a4..112b1d08 100644 --- a/src/game/boe.startup.cpp +++ b/src/game/boe.startup.cpp @@ -22,6 +22,7 @@ #include "prefs.hpp" #include "cursors.hpp" #include "render_image.hpp" +#include "tools/enum_map.hpp" #include using std::vector; @@ -34,7 +35,7 @@ extern cUniverse univ; extern eGameMode overall_mode; extern sf::View mainView; -rectangle startup_button[6]; +enum_map(eStartButton, rectangle) startup_button; // TODO: Always returns false, so make it void bool handle_startup_press(location the_point) { @@ -44,13 +45,13 @@ bool handle_startup_press(location the_point) { the_point = mainPtr.mapPixelToCoords(the_point, mainView); - for(short i = 0; i < 5; i++) - if(the_point.in(startup_button[i])) { - draw_start_button(i,5); + for(auto btn : startup_button.keys()) + if(the_point.in(startup_button[btn])) { + draw_start_button(btn,5); mainPtr.display(); // TODO: I suspect this won't work play_sound(37, time_in_ticks(5)); - draw_start_button(i,0); - switch(i) { + draw_start_button(btn,0); + switch(btn) { case STARTBTN_LOAD: do_load(); break; diff --git a/src/game/boe.text.cpp b/src/game/boe.text.cpp index 6bef672d..b850386e 100644 --- a/src/game/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -20,6 +20,7 @@ const int TEXT_BUF_LEN = 70; #include "res_image.hpp" #include "res_font.hpp" #include "spell.hpp" +#include "tools/enum_map.hpp" typedef struct { char line[50]; @@ -46,8 +47,9 @@ extern short had_text_freeze; extern eStatMode stat_screen_mode; // graphics globals -extern short which_combat_type,stat_window; +extern short which_combat_type; extern eGameMode overall_mode; +extern eItemWinMode stat_window; extern sf::RenderWindow mainPtr; extern rectangle more_info_button; extern short which_item_page[6]; @@ -64,12 +66,10 @@ extern sf::RenderTexture pc_stats_gworld, item_stats_gworld, text_area_gworld; extern sf::RenderTexture terrain_screen_gworld; // game globals -extern rectangle item_buttons[8][6]; -// name, use, give, drip, info, sell/id -extern rectangle pc_buttons[6][5]; -// name, hp, sp, info, trade -extern bool item_area_button_active[8][6]; -extern bool pc_area_button_active[6][5]; +extern enum_map(eItemButton, rectangle) item_buttons[8]; +extern enum_map(ePlayerButton, rectangle) pc_buttons[6]; +extern enum_map(eItemButton, bool) item_area_button_active[8]; +extern enum_map(ePlayerButton, bool) pc_area_button_active[6]; extern rectangle item_screen_button_rects[9]; extern std::vector spec_item_array; extern std::map abil_chart; @@ -91,7 +91,7 @@ void put_pc_screen() { rectangle day_rect[2] = {{103,174,114,201}, {103,147,114,172}}; rectangle title_rects[3] = {{4,4,16,180}, {4,184,16,214}, {4,214,16,237}}; rectangle bottom_bar_rect = {99,0,116,271}; - rectangle info_from = {0,1,12,13}; + rectangle info_from = {0,1,12,13}, switch_from = {0, 13, 12, 25}; pc_stats_gworld.setActive(); @@ -123,8 +123,8 @@ void put_pc_screen() { sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); for(short i = 0; i < 6; i++) { if(univ.party[i].main_status != eMainStatus::ABSENT) { - for(short j = 0; j < 5; j++) - pc_area_button_active[i][j] = 1; + for(auto& flag : pc_area_button_active[i]) + flag = true; if(i == univ.cur_pc) { style.italic = true; style.colour = sf::Color::Blue; @@ -182,18 +182,12 @@ void put_pc_screen() { style.colour = sf::Color::Black; // Now put trade and info buttons - //rect_draw_some_item(mixed_gworld,info_from,pc_stats_gworld,pc_buttons[i][3],1,0); - //rect_draw_some_item(mixed_gworld,switch_from,pc_stats_gworld,pc_buttons[i][4],1,0); - // do faster! - to_draw_rect = pc_buttons[i][PCBTN_INFO]; - to_draw_rect.right = pc_buttons[i][PCBTN_TRADE].right + 1; - from_rect = info_from; - from_rect.right = from_rect.left + to_draw_rect.right - to_draw_rect.left; - rect_draw_some_item(invenbtn_gworld,from_rect,pc_stats_gworld,to_draw_rect,sf::BlendAlpha); + rect_draw_some_item(invenbtn_gworld,info_from,pc_stats_gworld,pc_buttons[i][PCBTN_INFO],sf::BlendAlpha); + rect_draw_some_item(invenbtn_gworld,switch_from,pc_stats_gworld,pc_buttons[i][PCBTN_TRADE],sf::BlendAlpha); } else { - for(short j = 0; j < 5; j++) - pc_area_button_active[i][j] = 0; + for(auto& flag : pc_area_button_active[i]) + flag = false; } } @@ -206,21 +200,13 @@ void put_pc_screen() { // Sometimes this gets called when character is slain. when that happens, if items for // that PC are up, switch item page. if(univ.cur_pc < 6 && univ.current_pc().main_status != eMainStatus::ALIVE && stat_window == univ.cur_pc) { - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); } } // Draws item area in middle right // Screen_num is what page is visible in the item menu. -// 0 - 5 pc inventory 6 - special item 7 - missions -// Stat_screen_mode ... 0 - normal, adventuring, all buttons vis -// 1 - in shop, item info only -// 2 - in shop, identifying, shop_identify_cost is cost -// 3 - in shop, selling weapons -// 4 - in shop, selling armor -// 5 - in shop, selling all -// 6 - in shop, augmenting weapon,shop_identify_cost is type -void put_item_screen(short screen_num) { +void put_item_screen(eItemWinMode screen_num) { std::ostringstream sout; long i_num; long item_offset; @@ -239,8 +225,8 @@ void put_item_screen(short screen_num) { item_offset = item_sbar->getPosition(); for(short i = 0; i < 8; i++) - for(short j = 0; j < 6; j++) - item_area_button_active[i][j] = false; + for(auto& flag : item_area_button_active[i]) + flag = false; TextStyle style; style.lineHeight = 10; @@ -255,10 +241,10 @@ void put_item_screen(short screen_num) { if(i_num < spec_item_array.size()) { win_draw_string(item_stats_gworld,item_buttons[i][ITEMBTN_NAME],univ.scenario.special_items[spec_item_array[i_num]].name,eTextMode::WRAP,style); - place_item_button(3,i,4,0); + place_item_button(3,i,ITEMBTN_INFO); if((univ.scenario.special_items[spec_item_array[i_num]].flags % 10 == 1) && (!(is_combat()))) - place_item_button(0,i,3,0); + place_item_button(0,i,ITEMBTN_DROP); // TODO: Shouldn't this be ITEMBTN_USE? } } break; @@ -282,7 +268,7 @@ void put_item_screen(short screen_num) { draw_line(item_stats_gworld, from, to, 1, sf::Color::Green); } - place_item_button(3,i,4,0); + place_item_button(3,i,ITEMBTN_INFO); } } break; @@ -335,20 +321,20 @@ void put_item_screen(short screen_num) { // make go faster, and I got lazy. if((stat_screen_mode == MODE_SHOP) && ((is_town()) || (is_out()) || ((is_combat()) && (pc == univ.cur_pc)))) { // place give and drop and use - place_item_button(0,i,0,univ.party[pc].items[i_num].graphic_num); // item_graphic + place_item_graphic(i,univ.party[pc].items[i_num].graphic_num); if(abil_chart[univ.party[pc].items[i_num].ability]) // place use if can - place_item_button(ITEMBTN_NORM,i,1,0); - else place_item_button(ITEMBTN_ALL,i,1,0); + place_item_button(ITEMBTN_NORM,i); + else place_item_button(ITEMBTN_ALL,i); } else { - place_item_button(0,i,0,univ.party[pc].items[i_num].graphic_num); // item_graphic - place_item_button(3,i,4,0); // info button + place_item_graphic(i,univ.party[pc].items[i_num].graphic_num); + place_item_button(3,i,ITEMBTN_INFO); // info button if((stat_screen_mode == MODE_INVEN) && ((is_town()) || (is_out()) || ((is_combat()) && (pc == univ.cur_pc)))) { // place give and drop and use - place_item_button(1,i,2,0); - place_item_button(2,i,3,0); + place_item_button(1,i,ITEMBTN_GIVE); + place_item_button(2,i,ITEMBTN_DROP); if(abil_chart[item.ability]) // place use if can - place_item_button(0,i,1,0); + place_item_button(0,i,ITEMBTN_USE); } } if(stat_screen_mode != MODE_INVEN && stat_screen_mode != MODE_SHOP) { @@ -378,7 +364,7 @@ void place_buy_button(short position,short pc_num,short item_num) { if(item.variety == eItemType::NO_ITEM) return; - dest_rect = item_buttons[position][5]; + dest_rect = item_buttons[position][ITEMBTN_SPEC]; val_to_place = (item.charges > 0) ? item.charges * item.value : @@ -388,32 +374,32 @@ void place_buy_button(short position,short pc_num,short item_num) { switch(stat_screen_mode) { case MODE_IDENTIFY: if(!item.ident) { - item_area_button_active[position][5] = true; + item_area_button_active[position][ITEMBTN_SPEC] = true; source_rect = button_sources[0]; val_to_place = shop_identify_cost; } break; case MODE_SELL_WEAP: if((*item.variety).is_weapon && !pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { - item_area_button_active[position][5] = true; + item_area_button_active[position][ITEMBTN_SPEC] = true; source_rect = button_sources[1]; } break; case MODE_SELL_ARMOR: if((*item.variety).is_armour && !pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { - item_area_button_active[position][5] = true; + item_area_button_active[position][ITEMBTN_SPEC] = true; source_rect = button_sources[1]; } break; case MODE_SELL_ANY: if(!pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { - item_area_button_active[position][5] = true; + item_area_button_active[position][ITEMBTN_SPEC] = true; source_rect = button_sources[1]; } break; case MODE_ENCHANT: if((item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED) && item.ident && item.ability == eItemAbil::NONE && !item.magic) { - item_area_button_active[position][5] = true; + item_area_button_active[position][ITEMBTN_SPEC] = true; source_rect = button_sources[2]; val_to_place = max(aug_cost[shop_identify_cost] * 100, item.value * (5 + aug_cost[shop_identify_cost])); } @@ -422,10 +408,10 @@ void place_buy_button(short position,short pc_num,short item_num) { // These modes don't have buy buttons, so we shouldn't get here; bail out! return; } - if(item_area_button_active[position][5]) { + if(item_area_button_active[position][ITEMBTN_SPEC]) { sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); store_selling_values[position] = val_to_place; - dest_rect = item_buttons[position][5]; + dest_rect = item_buttons[position][ITEMBTN_SPEC]; dest_rect.right = dest_rect.left + 30; rect_draw_some_item(invenbtn_gworld, source_rect, item_stats_gworld, dest_rect, sf::BlendAlpha); TextStyle style; @@ -440,54 +426,58 @@ void place_buy_button(short position,short pc_num,short item_num) { // name, use, give, drop, info, sell/id // shortcuts - if which_button_to_put is 10, all 4 buttons now // if which_button_to_put is 11, just right 2 -void place_item_button(short which_button_to_put,short which_slot,short which_button_position,short extra_val) { +void place_item_graphic(short which_slot,short graphic) { rectangle from_rect = {0,0,18,18},to_rect; - if(which_button_position == 0) { // this means put little item graphic, extra val is which_graphic - item_area_button_active[which_slot][which_button_position] = true; - from_rect.offset((extra_val % 10) * 18,(extra_val / 10) * 18); - to_rect = item_buttons[which_slot][0]; - to_rect.right = to_rect.left + (to_rect.bottom - to_rect.top); - to_rect.inset(-1,-1); - to_rect.offset(20,1); - from_rect.inset(2,2); - if(extra_val >= 10000) { - sf::Texture* src_gw; - graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(extra_val - 10000, true); - rect_draw_some_item(*src_gw, from_rect, item_stats_gworld, to_rect,sf::BlendAlpha); - } else if(extra_val >= 1000) { - sf::Texture* src_gw; - graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(extra_val - 1000); - rect_draw_some_item(*src_gw, from_rect, item_stats_gworld, to_rect,sf::BlendAlpha); - } - else rect_draw_some_item(*ResMgr::get("tinyobj"), from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); - return; + item_area_button_active[which_slot][ITEMBTN_NAME] = true; + from_rect.offset((graphic % 10) * 18,(graphic / 10) * 18); + to_rect = item_buttons[which_slot][ITEMBTN_NAME]; + to_rect.right = to_rect.left + (to_rect.bottom - to_rect.top); + to_rect.inset(-1,-1); + to_rect.offset(20,1); + from_rect.inset(2,2); + if(graphic >= 10000) { + sf::Texture* src_gw; + graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(graphic - 10000, true); + rect_draw_some_item(*src_gw, from_rect, item_stats_gworld, to_rect,sf::BlendAlpha); + } else if(graphic >= 1000) { + sf::Texture* src_gw; + graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(graphic - 1000); + rect_draw_some_item(*src_gw, from_rect, item_stats_gworld, to_rect,sf::BlendAlpha); } + else rect_draw_some_item(*ResMgr::get("tinyobj"), from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); +} + +void place_item_button(short button_position,short which_slot,eItemButton button_type) { + rectangle from_rect = {0,0,18,18},to_rect; + sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); - if(which_button_to_put < 4) { // this means put a regular item button - item_area_button_active[which_slot][which_button_position] = true; - rect_draw_some_item(invenbtn_gworld, item_buttons_from[which_button_to_put], item_stats_gworld, item_buttons[which_slot][which_button_position], sf::BlendAlpha); - } - if(which_button_to_put == ITEMBTN_ALL) { // this means put all 4 - item_area_button_active[which_slot][1] = true; - item_area_button_active[which_slot][2] = true; - item_area_button_active[which_slot][3] = true; - item_area_button_active[which_slot][4] = true; + switch(button_position) { + default: // this means put a regular item button + item_area_button_active[which_slot][button_type] = true; + rect_draw_some_item(invenbtn_gworld, item_buttons_from[button_type], item_stats_gworld, item_buttons[which_slot][button_type], sf::BlendAlpha); + break; + case ITEMBTN_ALL: // this means put all 4 + item_area_button_active[which_slot][ITEMBTN_USE] = true; + item_area_button_active[which_slot][ITEMBTN_GIVE] = true; + item_area_button_active[which_slot][ITEMBTN_DROP] = true; + item_area_button_active[which_slot][ITEMBTN_INFO] = true; from_rect = item_buttons_from[0]; from_rect.right = item_buttons_from[3].right; - to_rect = item_buttons[which_slot][1]; + to_rect = item_buttons[which_slot][ITEMBTN_USE]; to_rect.right = to_rect.left + from_rect.right - from_rect.left; rect_draw_some_item(invenbtn_gworld, from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); - } - if(which_button_to_put == ITEMBTN_NORM) { // this means put right 3 - item_area_button_active[which_slot][2] = true; - item_area_button_active[which_slot][3] = true; - item_area_button_active[which_slot][4] = true; + break; + case ITEMBTN_NORM: // this means put right 3 + item_area_button_active[which_slot][ITEMBTN_GIVE] = true; + item_area_button_active[which_slot][ITEMBTN_DROP] = true; + item_area_button_active[which_slot][ITEMBTN_INFO] = true; from_rect = item_buttons_from[1]; from_rect.right = item_buttons_from[3].right; - to_rect = item_buttons[which_slot][2]; + to_rect = item_buttons[which_slot][ITEMBTN_GIVE]; to_rect.right = to_rect.left + from_rect.right - from_rect.left; rect_draw_some_item(invenbtn_gworld, from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); + break; } } @@ -544,12 +534,18 @@ void place_item_bottom_buttons() { rect_draw_some_item(invenbtn_gworld, help_from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); } -void set_stat_window(short new_stat) { +void set_stat_window_for_pc(int pc) { + if(pc < 0) pc = 0; + if(pc > 5) pc = 5; + set_stat_window(eItemWinMode(pc)); +} + +void set_stat_window(eItemWinMode new_stat) { short array_pos = 0; stat_window = new_stat; if(stat_window < ITEM_WIN_SPECIAL && univ.party[stat_window].main_status != eMainStatus::ALIVE) - stat_window = first_active_pc(); + stat_window = eItemWinMode(first_active_pc()); item_sbar->setPageSize(8); spec_item_array.clear(); switch(stat_window) { @@ -598,7 +594,7 @@ short first_active_pc() { void refresh_stat_areas(short mode) { sf::BlendMode x; - extern rectangle win_to_rects[6]; + extern enum_map(eGuiArea, rectangle) win_to_rects; if(mode == 1) x = sf::BlendAdd; else x = sf::BlendNone; @@ -633,7 +629,7 @@ void draw_pc_effects(short pc) { TextStyle style; name_width = string_length(univ.party[pc].name, style); - right_limit = pc_buttons[0][1].left - 5; + right_limit = pc_buttons[0][PCBTN_HP].left - 5; dest_rect.left = name_width + 33; dest_rect.right = dest_rect.left + 12; dest_rect.top += pc * 13; diff --git a/src/game/boe.text.hpp b/src/game/boe.text.hpp index 0aeed8ce..3edc9a69 100644 --- a/src/game/boe.text.hpp +++ b/src/game/boe.text.hpp @@ -4,10 +4,12 @@ class cVehicle; void put_pc_screen(); void place_buy_button(short position,short pc_num,short item_num); -void put_item_screen(short screen_num); +void put_item_screen(eItemWinMode screen_num); void place_item_bottom_buttons(); -void set_stat_window(short new_stat); -void place_item_button(short which_button_to_put,short which_slot,short which_button_position,short extra_val); +void set_stat_window(eItemWinMode new_stat); +void set_stat_window_for_pc(int pc); +void place_item_button(short button_position,short which_slot,eItemButton button_type = ITEMBTN_USE); +void place_item_graphic(short which_slot,short graphic); short first_active_pc(); void refresh_stat_areas(short mode); short total_encumbrance(short pc_num); diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index 4ee27517..1092d76f 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -29,8 +29,9 @@ #include "winutil.hpp" #include "res_image.hpp" -extern short stat_window,store_spell_target,which_combat_type,combat_active_pc; +extern short store_spell_target,which_combat_type,combat_active_pc; extern eGameMode overall_mode; +extern eItemWinMode stat_window; extern location center; extern sf::RenderWindow mainPtr; extern short store_current_pc,current_ground; @@ -704,7 +705,7 @@ void start_town_combat(eDirection direction) { center = univ.current_pc().combat_pos; draw_buttons(0); put_pc_screen(); - set_stat_window(univ.cur_pc); + set_stat_window_for_pc(univ.cur_pc); give_help(48,49); } diff --git a/src/game/boe.townspec.cpp b/src/game/boe.townspec.cpp index cd19f7ad..d5021f1c 100644 --- a/src/game/boe.townspec.cpp +++ b/src/game/boe.townspec.cpp @@ -20,7 +20,7 @@ #include "utility.hpp" extern eGameMode overall_mode; -extern short stat_window; +extern eItemWinMode stat_window; extern location center; extern sf::RenderWindow mainPtr; extern cUniverse univ; diff --git a/src/tools/enum_map.hpp b/src/tools/enum_map.hpp new file mode 100644 index 00000000..326ec656 --- /dev/null +++ b/src/tools/enum_map.hpp @@ -0,0 +1,45 @@ +// +// enum_map.hpp +// BoE +// +// Created by Celtic Minstrel on 19-11-23. +// +// + +#ifndef BoE_ENUM_MAP_HPP +#define BoE_ENUM_MAP_HPP + +#include + +// This is designed for contiguous enums, it'll waste space otherwise. +template +struct enum_map_impl : public std::array { + enum_map_impl() = default; + enum_map_impl(std::initializer_list l) { + std::copy(l.begin(), l.end(), begin()); + } + reference at(size_type pos) = delete; + const_reference at(size_type pos) const = delete; + reference operator[](size_type pos) = delete; + const_reference operator[](size_type pos) const = delete; + reference at(E pos) {return array::at(static_cast(pos));}; + const_reference at(E pos) const {return array::operator[](static_cast(pos));}; + reference operator[](E pos) {return array::operator[](static_cast(pos));}; + const_reference operator[](E pos) const = delete; + static const std::array keys() { + static std::array keys; + static bool inited = false; + if(!inited) { + for(size_t i = 0; i < n; i++) + keys[i] = static_cast(static_cast(E()) + i); + inited = true; + } + return keys; + } +}; + +#define enum_map_STR2(a, b) a ## b +#define enum_map_STR(a, b) enum_map_STR2(a, b) +#define enum_map(E, T) enum_map_impl + +#endif