1 /*-------------------------------------------------------------------------------
2
3 BARONY
4 File: interface.hpp
5 Desc: contains interface related declarations
6
7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 See LICENSE for details.
9
10 -------------------------------------------------------------------------------*/
11
12 #pragma once
13
14 #include "../main.hpp"
15 #include "../game.hpp"
16
17 class Item;
18
19 typedef struct damageIndicator_t
20 {
21 double x, y; // x and y of the attacker in world coordinates
22 double alpha; // alpha value of the indicator
23 node_t* node; // node in the damageIndicator list
24 Sint32 ticks; // birthtime of the damage indicator
25 } damageIndicator_t;
26 extern list_t damageIndicators;
27
28 #define STATUS_BAR_Y_OFFSET (status_bmp->h * uiscale_chatlog * !hide_statusbar)
29 #define INVENTORY_SLOTSIZE (40 * uiscale_inventory)
30 #define STATUS_X (xres / 2 - status_bmp->w * uiscale_chatlog / 2)
31 #define STATUS_Y (yres - STATUS_BAR_Y_OFFSET)
32 #define HOTBAR_START_X ((xres / 2) - (5 * hotbar_img->w * uiscale_hotbar))
33 extern bool hide_statusbar;
34 extern real_t uiscale_chatlog;
35 extern real_t uiscale_playerbars;
36 extern bool uiscale_charactersheet;
37 extern bool uiscale_skillspage;
38 extern real_t uiscale_hotbar;
39 extern real_t uiscale_inventory;
40
41 class EnemyHPDamageBarHandler
42 {
43 const int k_maxTickLifetime = 120;
44 public:
45
46 struct EnemyHPDetails
47 {
48 char enemy_name[128] = "";
49 Sint32 enemy_hp = 0;
50 Sint32 enemy_maxhp = 0;
51 Sint32 enemy_oldhp = 0;
52 Uint32 enemy_timer = 0;
53 Uint32 enemy_bar_color = 0;
54 bool lowPriorityTick = false;
55 bool shouldDisplay = true;
EnemyHPDetailsEnemyHPDamageBarHandler::EnemyHPDetails56 EnemyHPDetails(Sint32 HP, Sint32 maxHP, Sint32 oldHP, Uint32 color, char* name, bool isLowPriority)
57 {
58 memset(enemy_name, 0, 128);
59 enemy_hp = HP;
60 enemy_maxhp = maxHP;
61 enemy_oldhp = oldHP;
62 enemy_timer = ticks;
63 enemy_bar_color = color;
64 lowPriorityTick = isLowPriority;
65 shouldDisplay = true;
66 strcpy(enemy_name, name);
67 }
68 };
69
70 Uint32 enemy_bar_client_colors[MAXPLAYERS];
71 std::unordered_map<Uint32, EnemyHPDetails> HPBars;
72 void addEnemyToList(Sint32 HP, Sint32 maxHP, Sint32 oldHP, Uint32 color, Uint32 uid, char* name, bool isLowPriority);
73 void displayCurrentHPBar();
74 };
75 extern EnemyHPDamageBarHandler enemyHPDamageBarHandler;
76
77 extern int magicBoomerangHotbarSlot;
78
79 #ifndef SHOPWINDOW_SIZE
80 #define SHOPWINDOW_SIZE
81 #define SHOPWINDOW_SIZEX 576
82 #define SHOPWINDOW_SIZEY 324
83 #endif
84
85 static const int GUI_MODE_NONE = -1; //GUI closed, ingame & playing.
86 static const int GUI_MODE_INVENTORY = 0;
87 static const int GUI_MODE_MAGIC = 1;
88 static const int GUI_MODE_SHOP = 2;
89 extern int gui_mode;
90
91 /*
92 * So that the cursor jumps back to the hotbar instead of the inventory if a picked up hotbar item is canceled.
93 * Its value indicates which hotbar slot it's from.
94 * -1 means it's not from the hotbar.
95 */
96 extern int selectedItemFromHotbar;
97
98 extern SDL_Surface* font12x12_small_bmp;
99 extern SDL_Surface* backdrop_minotaur_bmp;
100 extern SDL_Surface* backdrop_blessed_bmp;
101 extern SDL_Surface* backdrop_cursed_bmp;
102 extern SDL_Surface* status_bmp;
103 extern SDL_Surface* character_bmp;
104 extern SDL_Surface* hunger_bmp;
105 extern SDL_Surface* hunger_blood_bmp;
106 extern SDL_Surface* hunger_boiler_bmp;
107 extern SDL_Surface* hunger_boiler_hotflame_bmp;
108 extern SDL_Surface* hunger_boiler_flame_bmp;
109 extern SDL_Surface* minotaur_bmp;
110 extern SDL_Surface* textup_bmp;
111 extern SDL_Surface* textdown_bmp;
112 extern SDL_Surface* attributesleft_bmp, *attributesleftunclicked_bmp;
113 extern SDL_Surface* attributesright_bmp, *attributesrightunclicked_bmp;
114 extern SDL_Surface* button_bmp, *smallbutton_bmp, *invup_bmp, *invdown_bmp;
115 extern SDL_Surface* inventory_bmp, *inventoryoption_bmp, *inventoryoptionChest_bmp, *equipped_bmp;
116 extern SDL_Surface* itembroken_bmp;
117 //extern SDL_Surface *category_bmp[NUMCATEGORIES];
118 extern SDL_Surface* shopkeeper_bmp;
119 extern SDL_Surface* shopkeeper2_bmp;
120 extern SDL_Surface* damage_bmp;
121 extern int textscroll;
122 extern int attributespage;
123 extern int proficienciesPage;
124 extern int inventorycategory;
125 extern int itemscroll;
126 extern view_t camera_charsheet;
127 extern real_t camera_charsheet_offsetyaw;
128
129 extern int selected_inventory_slot_x;
130 extern int selected_inventory_slot_y;
131
132 void select_inventory_slot(int x, int y);
133
134 extern SDL_Surface* inventoryChest_bmp;
135 extern SDL_Surface* invclose_bmp;
136 extern SDL_Surface* invgraball_bmp;
137 extern int chestitemscroll; //Same as itemscroll, but for the chest inventory GUI.
138 extern Entity* openedChest[MAXPLAYERS]; //One for each client. //TODO: Clientside, [0] will always point to something other than NULL when a chest is open and it will be NULL when a chest is closed.
139 extern list_t chestInv; //This is just for the client, so that it can populate the chest inventory on its end.
140 static const int kNumChestItemsToDisplay = 4;
141 extern Item* invitemschest[kNumChestItemsToDisplay];
142
143 extern bool gui_clickdrag; //True as long as an interface element is being dragged.
144 extern int dragoffset_x;
145 extern int dragoffset_y;
146 extern int buttonclick;
147
148 extern bool draw_cursor; //True if the gamepad's d-pad has been used to navigate menus and such. //TODO: Off by default on consoles and the like.
149
150 // function prototypes
151 void takeScreenshot();
152 bool loadInterfaceResources();
153 void freeInterfaceResources();
154 void clickDescription(int player, Entity* entity);
155 void consoleCommand(char const * const command);
156 void drawMinimap();
157 void handleDamageIndicators(int player);
158 void handleDamageIndicatorTicks();
159 void drawStatus();
160 void saveCommand(char* content);
161 int loadConfig(char* filename);
162 int saveConfig(char const * const filename);
163 void defaultConfig();
164 void updateChestInventory();
165 void updateAppraisalItemBox();
166 void updatePlayerInventory();
167 void updateShopWindow();
168 void updateEnemyBar(Entity* source, Entity* target, char* name, Sint32 hp, Sint32 maxhp, bool lowPriorityTick = false);
169 damageIndicator_t* newDamageIndicator(double x, double y);
170
171 void selectItemMenuSlot(const Item& item, int entry);
172 bool autoAddHotbarFilter(const Item& item);
173 void quickStackItems();
174 void sortInventoryItemsOfType(int categoryInt, bool sortRightToLeft); // sort inventory items matching category. -1 is everything, -2 is only equipped items.
175 void autosortInventory();
176 bool mouseInsidePlayerInventory();
177 bool mouseInsidePlayerHotbar();
178 bool playerLearnedSpellbook(Item* current_item);
179 extern Uint32 itemMenuItem;
180 extern bool itemMenuOpen;
181 extern int itemMenuSelected;
182
183 /*
184 * Used for two purposes:
185 * * In inventory navigation, if you pick up an item, drops it only if detects a second click, not if the button is released.
186 * * In the item context menu, toggles if it should pop open or not.
187 * This makes this variable super useful for gamepad support.
188 */
189 extern bool toggleclick;
190
191 //Inventory GUI definitions.
192 static const int INVENTORY_MODE_ITEM = 0;
193 static const int INVENTORY_MODE_SPELL = 1;
194 extern SDL_Surface* inventory_mode_item_img;
195 extern SDL_Surface* inventory_mode_item_highlighted_img;
196 extern SDL_Surface* inventory_mode_spell_img;
197 extern SDL_Surface* inventory_mode_spell_highlighted_img;
198 extern int inventory_mode;
199
200 /*
201 * Determines how item select (pick up, release) mechanic works.
202 * BEHAVIOR_MOUSE = press left button to pick up, release left button to drop,
203 * BEHAVIOR_GAMEPAD = press mapped button (x by default) to select/"grab" item, press again to drop.
204 */
205 enum selectBehavior_t
206 {
207 BEHAVIOR_MOUSE = 0,
208 BEHAVIOR_GAMEPAD = 1,
209 ENUM_LEN = 2
210 } extern itemSelectBehavior;
211
212 //Chest GUI definitions.
213 #define CHEST_INVENTORY_X (((xres / 2) - (inventoryChest_bmp->w / 2)) + chestgui_offset_x)
214 #define CHEST_INVENTORY_Y (((yres / 2) - (inventoryChest_bmp->h / 2)) + chestgui_offset_y)
215 extern int chestgui_offset_x;
216 extern int chestgui_offset_y;
217 extern bool dragging_chestGUI; //The chest GUI is being dragged.
218 /*
219 * Currently selected chest inventory slot.
220 * Same deal as with hotbar & inventory selection (exists for gamepad support).
221 * -1 = no selection (e.g. mouse out or no items in the first place).
222 */
223 extern int selectedChestSlot;
224 void selectChestSlot(int slot);
225 int numItemsInChest();
226 void warpMouseToSelectedChestSlot();
227
228 void warpMouseToSelectedInventorySlot();
229
230 //Magic GUI definitions.
231 extern SDL_Surface* magicspellList_bmp;
232 extern SDL_Surface* spell_list_titlebar_bmp;
233 extern SDL_Surface* spell_list_gui_slot_bmp;
234 extern SDL_Surface* spell_list_gui_slot_highlighted_bmp;
235 extern int spellscroll; //Same as itemscroll, but for the spell list GUI.
236 extern int magicspell_list_offset_x;
237 extern int magicspell_list_offset_y;
238 #define MAGICSPELL_LIST_X (((xres / 2) - (magicspellList_bmp->w / 2)) + magicspell_list_offset_x)
239 #define MAGICSPELL_LIST_Y (((yres / 2) - (magicspellList_bmp->h / 2)) + magicspell_list_offset_y)
240 extern bool dragging_magicspell_list_GUI; //The magic spell list GUI is being dragged.
241 /*
242 * The state of the magic GUI.
243 * 0 = spell list.
244 * 1 = spell editor.
245 */
246 extern int magic_GUI_state;
247 extern SDL_Rect magic_gui_pos; //The position of the magic GUI is stored here.
248 extern SDL_Surface* sustained_spell_generic_icon; //The goto icon when no other is available.
249
250 void renderMagicGUI(int winx, int winy, int winw, int winh);
251 void updateMagicGUI();
252 #define SUST_DIR_HORZ 0
253 #define SUST_DIR_VERT 1
254 #define SUST_SPELLS_DIRECTION SUST_DIR_VERT //0 = horizontal, 1 = vertical.
255 //sust_spells_x & sust_spells_y define the top left corner of where the sustained spells icons start drawing.
256 #define SUST_SPELLS_X 32
257 #define SUST_SPELLS_Y 32
258 #define SUST_SPELLS_RIGHT_ALIGN true //If true, overrides settings and makes the sustained spells draw alongside the right edge of the screen, vertically.
259 void drawSustainedSpells(); //Draws an icon for every sustained spell.
260
261 //Identify GUI definitions.
262 //NOTE: Make sure to always reset identifygui_appraising back to false.
263 #define IDENTIFY_GUI_X (((xres / 2) - (inventoryChest_bmp->w / 2)) + identifygui_offset_x)
264 #define IDENTIFY_GUI_Y (((yres / 2) - (inventoryChest_bmp->h / 2)) + identifygui_offset_y)
265 extern bool identifygui_active;
266 extern bool identifygui_appraising; //If this is true, the appraisal skill is controlling the identify GUI. If this is false, it originated from an identify spell.
267 extern int identifygui_offset_x;
268 extern int identifygui_offset_y;
269 extern bool dragging_identifyGUI; //The identify GUI is being dragged.
270 extern int identifyscroll;
271 static const int NUM_IDENTIFY_GUI_ITEMS = 4;
272 extern Item* identify_items[NUM_IDENTIFY_GUI_ITEMS];
273 extern SDL_Surface* identifyGUI_img;
274
275 extern int selectedIdentifySlot;
276
277 void selectIdentifySlot(int slot);
278 void warpMouseToSelectedIdentifySlot();
279
280 void CloseIdentifyGUI();
281 void updateIdentifyGUI(); //Updates the identify item GUI.
282 void identifyGUIIdentify(Item* item); //Identify the given item.
283 int getAppraisalTime(Item* item); // Return time in ticks needed to appraise an item
284 void drawSustainedSpells(); //Draws an icon for every sustained spell.
285
286 //Remove curse GUI definitions.
287 #define REMOVECURSE_GUI_X (((xres / 2) - (inventoryChest_bmp->w / 2)) + removecursegui_offset_x)
288 #define REMOVECURSE_GUI_Y (((yres / 2) - (inventoryChest_bmp->h / 2)) + removecursegui_offset_y)
289 extern bool removecursegui_active;
290 extern int removecursegui_offset_x;
291 extern int removecursegui_offset_y;
292 extern bool dragging_removecurseGUI; //The remove curse GUI is being dragged.
293 extern int removecursescroll;
294 static const int NUM_REMOVE_CURSE_GUI_ITEMS = 4;
295 extern Item* removecurse_items[NUM_REMOVE_CURSE_GUI_ITEMS];
296 //extern SDL_Surface *removecurseGUI_img; //Nah, just use the identify GUI's image. It works well enough. No need to double the resources.
297
298 void closeRemoveCurseGUI();
299 void updateRemoveCurseGUI(); //Updates the remove curse GUI.
300 void removecurseGUIRemoveCurse(Item* item); //Uncurse the given item.
301
302 //Gamepad-support related stuff.
303 extern int selectedRemoveCurseSlot;
304 void selectRemoveCurseSlot(int slot);
305 void warpMouseToSelectedRemoveCurseSlot();
306
307 enum GUICurrentType
308 {
309 GUI_TYPE_NONE,
310 GUI_TYPE_REPAIR,
311 GUI_TYPE_ALCHEMY,
312 GUI_TYPE_TINKERING,
313 GUI_TYPE_SCRIBING
314 };
315
316 // Generic GUI Stuff (repair/alchemy)
317 class GenericGUIMenu
318 {
319 int gui_starty = ((xres / 2) - (420 / 2)) + offsetx;
320 int gui_startx = ((yres / 2) - (96 / 2)) + offsety;
321 int usingScrollBeatitude = 0;
322 int offsetx;
323 int offsety;
324 int scroll;
325 GUICurrentType guiType;
326 public:
327 static const int kNumShownItems = 4;
328 bool draggingGUI; // if gui is being dragged
329 Item* itemsDisplayed[kNumShownItems];
330 bool guiActive;
331 int selectedSlot;
332
333 // Repair
334 int repairItemType;
335
336 // Alchemy
337 Item* basePotion;
338 Item* secondaryPotion;
339 Item* alembicItem;
340 bool experimentingAlchemy;
341
342 // Tinkering
343 enum TinkeringFilter
344 {
345 TINKER_FILTER_ALL,
346 TINKER_FILTER_CRAFTABLE,
347 TINKER_FILTER_SALVAGEABLE,
348 TINKER_FILTER_REPAIRABLE
349 };
350 Item* tinkeringKitItem;
351 list_t tinkeringTotalItems;
352 node_t* tinkeringTotalLastCraftableNode;
353 TinkeringFilter tinkeringFilter;
354 std::unordered_set<Uint32> tinkeringMetalScrap;
355 std::unordered_set<Uint32> tinkeringMagicScrap;
356 Item* tinkeringAutoSalvageKitItem;
357 Item* tinkeringAutoSalvageThisItem;
358 Uint32 tinkeringSfxLastTicks = 0;
359
360 // Scribing
361 Item* scribingToolItem;
362 list_t scribingTotalItems;
363 node_t* scribingTotalLastCraftableNode;
364 Item* scribingBlankScrollTarget;
365 enum ScribingFilter
366 {
367 SCRIBING_FILTER_CRAFTABLE,
368 SCRIBING_FILTER_REPAIRABLE
369 };
370 ScribingFilter scribingFilter;
371
GenericGUIMenu()372 GenericGUIMenu() :
373 guiActive(false),
374 offsetx(0),
375 offsety(0),
376 selectedSlot(-1),
377 scroll(0),
378 draggingGUI(false),
379 basePotion(nullptr),
380 secondaryPotion(nullptr),
381 alembicItem(nullptr),
382 experimentingAlchemy(false),
383 tinkeringKitItem(nullptr),
384 tinkeringTotalLastCraftableNode(nullptr),
385 tinkeringFilter(TINKER_FILTER_ALL),
386 tinkeringAutoSalvageKitItem(nullptr),
387 tinkeringAutoSalvageThisItem(nullptr),
388 scribingFilter(SCRIBING_FILTER_CRAFTABLE),
389 scribingToolItem(nullptr),
390 scribingTotalLastCraftableNode(nullptr),
391 scribingBlankScrollTarget(nullptr),
392 scribingLastUsageAmount(0),
393 scribingLastUsageDisplayTimer(0),
394 repairItemType(0)
395 {
396 for ( int i = 0; i < kNumShownItems; ++i )
397 {
398 itemsDisplayed[i] = nullptr;
399 }
400 tinkeringTotalItems.first = nullptr;
401 tinkeringTotalItems.last = nullptr;
402 scribingTotalItems.first = nullptr;
403 scribingTotalItems.last = nullptr;
404 };
405
406 void warpMouseToSelectedSlot();
407 void selectSlot(int slot);
408 void closeGUI();
409 void openGUI(int type, int scrollBeatitude, int scrollType);
410 void openGUI(int type, bool experimenting, Item* itemOpenedWith);
411 void openGUI(int type, Item* itemOpenedWith);
412 inline Item* getItemInfo(int slot);
413 void updateGUI();
414 void rebuildGUIInventory();
415 void initGUIControllerCode();
416 bool shouldDisplayItemInGUI(Item* item);
417 bool executeOnItemClick(Item* item);
418
419 // repair menu funcs
420 void repairItem(Item* item);
421 bool isItemRepairable(const Item* item, int repairScroll);
422
423 //alchemy menu funcs
424 bool isItemMixable(const Item* item);
425 void alchemyCombinePotions();
426 bool alchemyLearnRecipe(int type, bool increaseskill, bool notify = true);
427 bool isItemBaseIngredient(int type);
428 bool isItemSecondaryIngredient(int type);
429 void alchemyLearnRecipeOnLevelUp(int skill);
430
431 // tinkering menu foncs
432 bool tinkeringSalvageItem(Item* item, bool outsideInventory, int player);
433 bool tinkeringCraftItem(Item* item);
434 void tinkeringCreateCraftableItemList();
435 void tinkeringFreeLists();
436 bool isItemSalvageable(const Item* item, int player);
437 bool tinkeringGetItemValue(const Item* item, int* metal, int* magic);
438 bool tinkeringGetCraftingCost(const Item* item, int* metal, int* magic);
439 bool tinkeringPlayerCanAffordCraft(const Item* item);
440 Item* tinkeringCraftItemAndConsumeMaterials(const Item* item);
441 int tinkeringPlayerHasSkillLVLToCraft(const Item* item);
442 bool tinkeringKitDegradeOnUse(int player);
443 Item* tinkeringKitFindInInventory();
444 bool tinkeringKitRollIfShouldBreak();
445 bool tinkeringGetRepairCost(Item* item, int* metal, int* magic);
446 bool tinkeringIsItemRepairable(Item* item, int player);
447 bool tinkeringIsItemUpgradeable(const Item* item);
448 bool tinkeringRepairItem(Item* item);
449 int tinkeringUpgradeMaxStatus(Item* item);
450 bool tinkeringConsumeMaterialsForRepair(Item* item, bool upgradingItem);
451 bool tinkeringPlayerCanAffordRepair(Item* item);
452 int tinkeringRepairGeneralItemSkillRequirement(Item* item);
453 bool tinkeringPlayerHasMaterialsInventory(int metal, int magic);
454 Uint32 tinkeringRetrieveLeastScrapStack(int type);
455 int tinkeringCountScrapTotal(int type);
456
457 void scribingCreateCraftableItemList();
458 void scribingFreeLists();
459 int scribingToolDegradeOnUse(Item* itemUsedWith);
460 Item* scribingToolFindInInventory();
461 bool scribingWriteItem(Item* item);
462 int scribingLastUsageAmount;
463 int scribingLastUsageDisplayTimer;
464
isGUIOpen()465 inline bool isGUIOpen()
466 {
467 return guiActive;
468 };
isNodeTinkeringCraftableItem(node_t * node)469 inline bool isNodeTinkeringCraftableItem(node_t* node)
470 {
471 if ( !node )
472 {
473 return false;
474 }
475 return (node->list == &tinkeringTotalItems);
476 };
isNodeScribingCraftableItem(node_t * node)477 inline bool isNodeScribingCraftableItem(node_t* node)
478 {
479 if ( !node )
480 {
481 return false;
482 }
483 return (node->list == &scribingTotalItems);
484 };
isItemUsedForCurrentGUI(const Item & item)485 inline bool isItemUsedForCurrentGUI(const Item& item)
486 {
487 if ( &item == scribingToolItem || &item == tinkeringKitItem || &item == alembicItem )
488 {
489 return true;
490 }
491 return false;
492 }
clearCurrentGUIFromItem(const Item & item)493 inline void clearCurrentGUIFromItem(const Item& item)
494 {
495 if ( &item == scribingToolItem )
496 {
497 scribingToolItem = nullptr;
498 }
499 if ( &item == tinkeringKitItem )
500 {
501 tinkeringKitItem = nullptr;
502 }
503 if ( &item == alembicItem )
504 {
505 alembicItem = nullptr;
506 }
507 }
508 bool isNodeFromPlayerInventory(node_t* node);
509 };
510 extern GenericGUIMenu GenericGUI;
511
512 /*
513 * Returns true if the mouse is in the specified bounds, with x1 and y1 specifying the top left corner, and x2 and y2 specifying the bottom right corner.
514 */
515 bool mouseInBounds(int x1, int x2, int y1, int y2);
516
517 void updateCharacterSheet();
518 void drawPartySheet();
519 void drawSkillsSheet();
520
521 //Right sidebar defines.
522 #define RIGHTSIDEBAR_X (xres - rightsidebar_titlebar_img->w)
523 #define RIGHTSIDEBAR_Y 0
524 //Note: Just using the spell versions of these for now.
525 extern SDL_Surface* rightsidebar_titlebar_img;
526 extern SDL_Surface* rightsidebar_slot_img;
527 extern SDL_Surface* rightsidebar_slot_highlighted_img;
528 extern SDL_Surface* rightsidebar_slot_grayedout_img;
529 extern int rightsidebar_height;
530 extern int appraisal_timer; //There is a delay after the appraisal skill is activated before the item is identified.
531 extern int appraisal_timermax;
532 extern Uint32 appraisal_item; //The item being appraised (or rather its uid)
533
534 void updateRightSidebar(); //Updates the sidebar on the right side of the screen, the one containing spells, skills, etc.
535
536 //------book_t Defines-----
537 extern SDL_Surface* bookgui_img;
538 //extern SDL_Surface *nextpage_img;
539 //extern SDL_Surface *previouspage_img;
540 //extern SDL_Surface *bookclose_img;
541 extern SDL_Surface* book_highlighted_left_img; //Draw this when the mouse is over the left half of the book.
542 extern SDL_Surface* book_highlighted_right_img; //Draw this when the mouse is over the right half of the book.
543 extern node_t* book_page;
544 extern int bookgui_offset_x;
545 extern int bookgui_offset_y;
546 #define BOOK_GUI_X (((xres / 2) - (bookgui_img->w / 2)) + bookgui_offset_x)
547 #define BOOK_GUI_Y (((yres / 2) - (bookgui_img->h / 2)) + bookgui_offset_y)
548 extern bool dragging_book_GUI; //The book GUI is being dragged.
549 extern bool book_open; //Is there a book open?
550 struct book_t;
551 extern struct book_t* open_book;
552 extern Item* open_book_item; //A pointer to the open book's item, so that the game knows to close the book when the player drops that item.
553 #define BOOK_FONT ttf12
554 #define BOOK_FONT_WIDTH TTF12_WIDTH
555 #define BOOK_FONT_HEIGHT TTF12_HEIGHT
556 //TODO: Calculate these two automatically based off of the buttons?
557 #define BOOK_PAGE_WIDTH 248
558 #define BOOK_PAGE_HEIGHT 256
559 #define BOOK_TITLE_PADDING 2 //The amount of empty space above and below the book titlename.
560 //#define BOOK_TITLE_HEIGHT (BOOK_TITLE_FONT_SIZE + BOOK_TITLE_PADDING) //The total y space the book's title takes up. Used for calculating BOOK_DRAWSPACE_Y.
561 int bookTitleHeight(struct book_t* book); //Returns how much space the book's title will occupy.
562 //#define BOOK_DRAWSPACE_X 280
563 //#define BOOK_DRAWSPACE_X (bookgui_img->w - (BOOK_BORDER_THICKNESS * 2))
564 #define START_OF_BOOKDRAWSPACE_X (BOOK_BORDER_THICKNESS) //This is the amount to add to BOOK_GUI_X to get the render area for the text.
565 //#define BOOK_DRAWSPACE_Y 180
566 //#define BOOK_DRAWSPACE_Y (bookgui_img->h - (BOOK_BORDER_THICKNESS * 2) - std::max(previouspage_img->h, nextpage_img->h)) //NOTE: You need to manually add "- bookTitleHeight(open_book)" wherever you use this define.
567 #define START_OF_BOOK_DRAWSPACE_Y (BOOK_BORDER_THICKNESS) //This is the amount to add to BOOK_GUI_Y to get the render area for the text. //NOTE: You need to manually add "+ bookTitleHeight(open_book)" wherever you use this define.
568 #define FLIPMARGIN 240
569 #define DRAGHEIGHT_BOOK 32
570 //extern int book_characterspace_x; //How many characters can fit along the x axis.
571 //extern int book_characterspace_y; //How many characters can fit along the y axis.
572 void updateBookGUI();
573 void closeBookGUI();
574 void openBook(struct book_t* book, Item* item);
575
576 extern Entity* hudweapon; //A pointer to the hudweapon entity.
577
578
579 //------Hotbar Defines-----
580 /*
581 * The hotbar itself is an array.
582 * NOTE: If the status bar width is changed, you need to change the slot image too. Make sure the status bar width stays divisible by 10.
583 */
584
585 //NOTE: Each hotbar slot is "constructed" in loadInterfaceResources() in interface.c. If you add anything, make sure to initialize it there.
586 typedef struct hotbar_slot_t
587 {
588 /*
589 * This is an item's ID. It just resolves to NULL if an item is no longer valid.
590 */
591 Uint32 item;
592 } hotbar_slot_t;
593
594 #define HOTBAR_EMPTY 0
595 #define HOTBAR_ITEM 1
596 #define HOTBAR_SPELL 2
597
598 static const unsigned NUM_HOTBAR_SLOTS = 10; //NOTE: If you change this, you must dive into drawstatus.c and update the hotbar code. It expects 10.
599 static const unsigned NUM_HOTBAR_ALTERNATES = 5;
600 extern hotbar_slot_t hotbar[NUM_HOTBAR_SLOTS];
601 extern hotbar_slot_t hotbar_alternate[NUM_HOTBAR_ALTERNATES][NUM_HOTBAR_SLOTS];
602 extern int swapHotbarOnShapeshift;
603 extern bool hotbarShapeshiftInit[NUM_HOTBAR_ALTERNATES];
604 extern int current_hotbar; //For use with gamepads and stuff because no hotkeys like a keyboard.
605 enum HotbarLoadouts : int
606 {
607 HOTBAR_DEFAULT,
608 HOTBAR_RAT,
609 HOTBAR_SPIDER,
610 HOTBAR_TROLL,
611 HOTBAR_IMP
612 };
613
614 extern SDL_Surface* hotbar_img; //A 64x64 slot.
615 extern SDL_Surface* hotbar_spell_img; //Drawn when a spell is in the hotbar. TODO: Replace with unique images for every spell. (Or draw this by default if none found?)
616
617 //Returns a pointer to a hotbar slot if the specified coordinates are in the area of the hotbar. Used for such things as dragging and dropping items.
618 hotbar_slot_t* getHotbar(int x, int y);
619
620 void selectHotbarSlot(int slot);
621 extern bool hotbarHasFocus;
622 void warpMouseToSelectedHotbarSlot();
623
624 /*
625 * True = automatically place items you pick up in your hotbar.
626 * False = don't.
627 */
628 extern bool auto_hotbar_new_items;
629
630 extern bool auto_hotbar_categories[NUM_HOTBAR_CATEGORIES]; // true = enable auto add to hotbar. else don't add.
631
632 extern int autosort_inventory_categories[NUM_AUTOSORT_CATEGORIES]; // 0 = disable priority sort, fill rightmost first. greater than 0, fill leftmost using value as priority (0 = lowest priority)
633
634 extern bool hotbar_numkey_quick_add; // use number keys to add items to hotbar if mouse in inventory panel.
635
636 extern bool disable_messages;
637
638 extern bool right_click_protect;
639
640 extern bool auto_appraise_new_items;
641
642 extern bool lock_right_sidebar;
643
644 extern bool show_game_timer_always;
645
646 extern bool hide_playertags;
647
648 extern bool show_skill_values;
649
650 const char* getInputName(Uint32 scancode);
651 Sint8* inputPressed(Uint32 scancode);
652
653 //All the code that sets shootmode = false. Display chests, inventory, books, shopkeeper, identify, whatever.
654 void openStatusScreen(int whichGUIMode, int whichInventoryMode); //TODO: Make all the everything use this. //TODO: Make an accompanying closeStatusScreen() function.
655 enum CloseGUIShootmode : int
656 {
657 DONT_CHANGE_SHOOTMODE,
658 CLOSEGUI_ENABLE_SHOOTMODE
659 };
660 enum CloseGUIIgnore : int
661 {
662 CLOSEGUI_CLOSE_ALL,
663 CLOSEGUI_DONT_CLOSE_FOLLOWERGUI,
664 CLOSEGUI_DONT_CLOSE_CHEST,
665 CLOSEGUI_DONT_CLOSE_SHOP
666 };
667
668 void closeAllGUIs(CloseGUIShootmode shootmodeAction, CloseGUIIgnore whatToClose);
669
670 static const int SCANCODE_UNASSIGNED_BINDING = 399;
671
hotbarGamepadControlEnabled()672 inline bool hotbarGamepadControlEnabled()
673 {
674 return ( !openedChest[clientnum]
675 && gui_mode != GUI_MODE_SHOP
676 && !identifygui_active
677 && !removecursegui_active
678 && !GenericGUI.isGUIOpen() );
679 }
680
681 extern SDL_Surface *str_bmp64u;
682 extern SDL_Surface *dex_bmp64u;
683 extern SDL_Surface *con_bmp64u;
684 extern SDL_Surface *int_bmp64u;
685 extern SDL_Surface *per_bmp64u;
686 extern SDL_Surface *chr_bmp64u;
687 extern SDL_Surface *str_bmp64;
688 extern SDL_Surface *dex_bmp64;
689 extern SDL_Surface *con_bmp64;
690 extern SDL_Surface *int_bmp64;
691 extern SDL_Surface *per_bmp64;
692 extern SDL_Surface *chr_bmp64;
693
694 extern SDL_Surface *sidebar_lock_bmp;
695 extern SDL_Surface *sidebar_unlock_bmp;
696
697 extern SDL_Surface *effect_drunk_bmp;
698 extern SDL_Surface *effect_polymorph_bmp;
699 extern SDL_Surface *effect_hungover_bmp;
700
701 void printStatBonus(TTF_Font* outputFont, Sint32 stat, Sint32 statWithModifiers, int x, int y);
702 void attackHoverText(Sint32 input[6]);
703 Sint32 displayAttackPower(Sint32 output[6]);
704
705 class MinimapPing
706 {
707 public:
708 Sint32 tickStart;
709 Uint8 player;
710 Uint8 x;
711 Uint8 y;
712 bool radiusPing;
MinimapPing(Sint32 tickStart,Uint8 player,Uint8 x,Uint8 y)713 MinimapPing(Sint32 tickStart, Uint8 player, Uint8 x, Uint8 y) :
714 tickStart(tickStart),
715 player(player),
716 x(x),
717 y(y),
718 radiusPing(false) {}
719
MinimapPing(Sint32 tickStart,Uint8 player,Uint8 x,Uint8 y,bool radiusPing)720 MinimapPing(Sint32 tickStart, Uint8 player, Uint8 x, Uint8 y, bool radiusPing) :
721 tickStart(tickStart),
722 player(player),
723 x(x),
724 y(y),
725 radiusPing(radiusPing) {}
726 };
727
728 extern std::vector<MinimapPing> minimapPings;
729 void minimapPingAdd(MinimapPing newPing);
730 extern int minimapPingGimpTimer;
731
732 extern std::vector<std::pair<SDL_Surface**, std::string>> systemResourceImages;
733
734 class FollowerRadialMenu
735 {
736 public:
737 Entity* followerToCommand;
738 Entity* recentEntity;
739 Entity* entityToInteractWith;
740 int menuX; // starting mouse coordinates that are the center of the circle.
741 int menuY; // starting mouse coordinates that are the center of the circle.
742 int optionSelected; // current moused over option.
743 int optionPrevious; // previously selected option.
744 bool selectMoveTo; // player is choosing a point or target to interact with.
745 int moveToX; // x position for follower to move to.
746 int moveToY; // y position for follower to move to.
747 bool menuToggleClick; // user pressed menu key but did not select option before letting go. keeps the menu open without input.
748 bool holdWheel; // user pressed quick menu for last follower.
749 char interactText[128]; // user moused over object while selecting interact object.
750 bool accessedMenuFromPartySheet; // right click from party sheet will warp mouse back after a selection.
751 int partySheetMouseX; // store mouse x cooord for accessedMenuFromPartySheet warp.
752 int partySheetMouseY; // store mouse y cooord for accessedMenuFromPartySheet warp.
753 int sidebarScrollIndex; // entries scrolled in the sidebar list if overflowed with followers.
754 int maxMonstersToDraw;
755
FollowerRadialMenu()756 FollowerRadialMenu() :
757 followerToCommand(nullptr),
758 recentEntity(nullptr),
759 entityToInteractWith(nullptr),
760 menuX(-1),
761 menuY(-1),
762 optionSelected(-1),
763 optionPrevious(-1),
764 selectMoveTo(false),
765 moveToX(-1),
766 moveToY(-1),
767 menuToggleClick(false),
768 holdWheel(false),
769 accessedMenuFromPartySheet(false),
770 partySheetMouseX(-1),
771 partySheetMouseY(-1),
772 sidebarScrollIndex(0),
773 maxMonstersToDraw(5)
774 {
775 memset(interactText, 0, 128);
776 }
777
778 bool followerMenuIsOpen();
779 void drawFollowerMenu();
780 void initFollowerMenuGUICursor(bool openInventory = true);
781 void closeFollowerMenuGUI(bool clearRecentEntity = false);
782 void selectNextFollower();
783 int numMonstersToDrawInParty();
784 void updateScrollPartySheet();
785 bool allowedInteractEntity(Entity& selectedEntity);
786 int optionDisabledForCreature(int playerSkillLVL, int monsterType, int option);
787 bool allowedClassToggle(int monsterType);
788 bool allowedItemPickupToggle(int monsterType);
789 bool allowedInteractFood(int monsterType);
790 bool allowedInteractWorld(int monsterType);
791 bool allowedInteractItems(int monsterType);
792 bool attackCommandOnly(int monsterType);
793 void monsterGyroBotConvertCommand(int* option);
794 bool monsterGyroBotOnlyCommand(int option);
795 bool monsterGyroBotDisallowedCommands(int option);
796 bool isTinkeringFollower(int type);
797 };
798 extern FollowerRadialMenu FollowerMenu;
799 extern SDL_Rect interfaceSkillsSheet;
800 extern SDL_Rect interfacePartySheet;
801 extern SDL_Rect interfaceCharacterSheet;
802 extern SDL_Rect interfaceMessageStatusBar;