From 4f785e2650193fef87cffedf4ed427a9bbe75950 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sat, 23 Nov 2019 21:12:47 -0500 Subject: [PATCH] Use enums for most of the rest of the game constants. This adds an "enum map" type that allows safe usage of an enum to index an array. (That is, it enforces that the index is of the enum type.) --- proj/vs2013/Common/Common.vcxproj | 1 + proj/vs2013/Common/Common.vcxproj.filters | 3 + src/game/boe.actions.cpp | 92 ++++++----- src/game/boe.combat.cpp | 6 +- src/game/boe.consts.hpp | 93 ++++++----- src/game/boe.dlgutil.cpp | 5 +- src/game/boe.graphics.cpp | 21 +-- src/game/boe.graphics.hpp | 2 +- src/game/boe.items.cpp | 3 +- src/game/boe.main.cpp | 5 +- src/game/boe.newgraph.cpp | 5 +- src/game/boe.party.cpp | 6 +- src/game/boe.specials.cpp | 3 +- src/game/boe.startup.cpp | 13 +- src/game/boe.text.cpp | 178 +++++++++++----------- src/game/boe.text.hpp | 8 +- src/game/boe.town.cpp | 5 +- src/game/boe.townspec.cpp | 2 +- src/tools/enum_map.hpp | 45 ++++++ 19 files changed, 287 insertions(+), 209 deletions(-) create mode 100644 src/tools/enum_map.hpp 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