From 0542ddf9a6c31cbd55ae3abb1d45ed0028ed86c2 Mon Sep 17 00:00:00 2001 From: Sheridan Kane Rathbun Date: Fri, 4 Mar 2022 18:09:43 -0800 Subject: [PATCH 1/3] Lots o' cool stuff (#637) * remove SDLNet_ResolveIP from lobbyPlayerJoinRequest() * safeguards in createReadyStone() * fix bugs and shit * When server DCs in-game, clients get disconnect prompt * fix issues starting games on clients * disable test lobby entries * yet more lobby browser improvements * minor changes * hack to make FP whip animate better * console variable on whips (default false) * port number settings works restore defaults in settings works better --- src/game.cpp | 26 ---- src/menu.hpp | 2 +- src/net.cpp | 42 ++---- src/opengl.cpp | 13 ++ src/ui/Frame.cpp | 89 +++++++---- src/ui/Frame.hpp | 13 ++ src/ui/GameUI.cpp | 2 +- src/ui/MainMenu.cpp | 357 +++++++++++++++++++++++++++++++------------- src/ui/MainMenu.hpp | 1 + 9 files changed, 363 insertions(+), 182 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 414f4e500..647ddc35a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -836,32 +836,6 @@ void gameLogic(void) { fadefinished = true; } - if ( multiplayer == SERVER && introstage == 3 ) - { - // machinegun this message to clients to make sure they get it! - for ( c = 1; c < MAXPLAYERS; c++ ) - { - if ( client_disconnected[c] || players[c]->isLocalPlayer() ) - { - continue; - } - strcpy((char*)net_packet->data, "STRT"); - SDLNet_Write32(svFlags, &net_packet->data[4]); - SDLNet_Write32(uniqueGameKey, &net_packet->data[8]); - if ( loadingsavegame == 0 ) - { - net_packet->data[12] = 0; - } - else - { - net_packet->data[12] = 1; - } - net_packet->address.host = net_clients[c - 1].host; - net_packet->address.port = net_clients[c - 1].port; - net_packet->len = 13; - sendPacket(net_sock, -1, net_packet, c - 1); - } - } } else { diff --git a/src/menu.hpp b/src/menu.hpp index a1938671e..25e78f472 100644 --- a/src/menu.hpp +++ b/src/menu.hpp @@ -317,4 +317,4 @@ enum CharacterDLCValidation : int INVALID_REQUIREDLC1, INVALID_REQUIREDLC2, INVALID_REQUIRE_ACHIEVEMENT -}; \ No newline at end of file +}; diff --git a/src/net.cpp b/src/net.cpp index ef03fe71f..50825c3a6 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -36,6 +36,7 @@ #include "colors.hpp" #include "mod_tools.hpp" #include "lobbies.hpp" +#include "ui/MainMenu.hpp" NetHandler* net_handler = nullptr; @@ -2449,18 +2450,16 @@ void clientHandlePacket() // server or player shut down else if (packetId == 'DISC') { + client_disconnected[net_packet->data[4]] = true; if (net_packet->data[4] == 0) { // server shutdown if (!victory) { printlog("The remote server has shut down.\n"); - pauseGame(2, 0); - // TODO display disconnect window - // &buttonCloseAndEndGameConfirm on okay + MainMenu::disconnectedFromServer(); } } - client_disconnected[net_packet->data[4]] = true; return; } @@ -4345,32 +4344,14 @@ void clientHandlePacket() } // game restart - if (packetId == 'STRT') + if (packetId == 'RSTR') { - if ( !intro ) - { - // intro is true if starting from main menu, otherwise we're restarting the game. - // set the main menu camera to the player camera coordinates if restarting midgame. - menucam.x = cameras[clientnum].x; - menucam.y = cameras[clientnum].y; - menucam.z = cameras[clientnum].z; - menucam.ang = cameras[clientnum].ang; - menucam.vang = cameras[clientnum].vang; - } - intro = true; - client_disconnected[0] = true; svFlags = SDLNet_Read32(&net_packet->data[4]); uniqueGameKey = SDLNet_Read32(&net_packet->data[8]); - //TODO anything we gotta do for the new UI? - //probably not buttonCloseSubwindow(). - //buttonCloseSubwindow(NULL); - numplayers = 0; - introstage = 3; - if ( net_packet->data[12] == 0 ) - { - loadingsavegame = 0; // the server said we're not loading a saved game. - } - fadeout = true; + if (net_packet->data[12] == 0) { + loadingsavegame = 0; + } + MainMenu::beginFade(MainMenu::FadeDestination::GameStart); return; } @@ -4540,6 +4521,13 @@ void serverHandlePacket() return; } + // network scan + else if (packetId == 'SCAN') + { + MainMenu::handleScanPacket(); + return; + } + // pause game else if (packetId == 'PAUS') { diff --git a/src/opengl.cpp b/src/opengl.cpp index 9f4260c81..994f9f53b 100644 --- a/src/opengl.cpp +++ b/src/opengl.cpp @@ -522,6 +522,19 @@ void glDrawVoxel(view_t* camera, Entity* entity, int mode) glRotatef(rotz, 0, 0, 1); // rotate pitch glRotatef(rotx, 1, 0, 0); // rotate roll glTranslatef(entity->focalx * 2, -entity->focalz * 2, entity->focaly * 2); +#ifndef EDITOR + static ConsoleVariable reverseWhip("/reversewhip", false); + if (*reverseWhip) { + int chop = entity->skill[0]; + if (entity->behavior == &actHudWeapon && entity->sprite == 868 && + (chop == 1 || chop == 2 || chop == 4 || chop == 5)) { + // whips get turned around when attacking + // gross hack, but it works, and we don't have quaternions. so this is way easier + glRotatef(180, 0, 1, 0); + glRotatef(60, 0, 0, 1); + } + } +#endif glScalef(entity->scalex, entity->scalez, entity->scaley); if ( mode == REALCOLORS ) { diff --git a/src/ui/Frame.cpp b/src/ui/Frame.cpp index 88071bbcc..130a15bfa 100644 --- a/src/ui/Frame.cpp +++ b/src/ui/Frame.cpp @@ -390,28 +390,31 @@ void Frame::draw(SDL_Rect _size, SDL_Rect _actualSize, const std::vectordrawColor(nullptr, dest, viewport, activatedEntryColor); + } + else if (selection == i && selectedEntryColor) { white->drawColor(nullptr, dest, viewport, selectedEntryColor); } - } + } // draw an image if applicable if (entry.text.empty()) { @@ -802,10 +805,12 @@ Frame::result_t Frame::process(SDL_Rect _size, SDL_Rect _actualSize, const std:: if (input.binary("MenuScrollRight")) { this->actualSize.x += std::min(this->actualSize.x + 5, this->actualSize.w - _size.w); usable = result.usable = false; + syncScroll(); } else if (input.binary("MenuScrollLeft")) { this->actualSize.x -= std::max(this->actualSize.x - 5, 0); usable = result.usable = false; + syncScroll(); } } @@ -814,10 +819,12 @@ Frame::result_t Frame::process(SDL_Rect _size, SDL_Rect _actualSize, const std:: if (input.binary("MenuScrollDown")) { this->actualSize.y = std::min(this->actualSize.y + 5, this->actualSize.h - _size.h); usable = result.usable = false; + syncScroll(); } else if (input.binary("MenuScrollUp")) { this->actualSize.y = std::max(this->actualSize.y - 5, 0); usable = result.usable = false; + syncScroll(); } } } @@ -832,12 +839,12 @@ Frame::result_t Frame::process(SDL_Rect _size, SDL_Rect _actualSize, const std:: if (parent != nullptr && !hollow && rectContainsPoint(fullSize, omousex, omousey) && usable) { bool mwheeldown = false; bool mwheelup = false; - if (input.consumeBinaryToggle("MenuMouseWheelDown")) { - mwheeldown = true; - } - if (input.consumeBinaryToggle("MenuMouseWheelUp")) { - mwheelup = true; - } + if (input.consumeBinaryToggle("MenuMouseWheelDown")) { + mwheeldown = true; + } + if (input.consumeBinaryToggle("MenuMouseWheelUp")) { + mwheelup = true; + } if (allowScrolling && allowScrollBinds) { if (mwheeldown || mwheelup) { usable = result.usable = false; @@ -867,8 +874,18 @@ Frame::result_t Frame::process(SDL_Rect _size, SDL_Rect _actualSize, const std:: } } - this->actualSize.x += scrollInertiaX * entrySize * 2; - this->actualSize.y += scrollInertiaY * entrySize * 2; + if (scrollInertiaX) { + this->actualSize.x += scrollInertiaX * entrySize * 2; + this->actualSize.x = std::min(std::max(0, this->actualSize.x), + std::max(0, this->actualSize.w - size.w)); + syncScroll(); + } + if (scrollInertiaY) { + this->actualSize.y += scrollInertiaY * entrySize * 2; + this->actualSize.y = std::min(std::max(0, this->actualSize.y), + std::max(0, this->actualSize.h - size.h)); + syncScroll(); + } if (fabs(scrollInertiaX) > 0.0) { scrollInertiaX *= .9; @@ -930,6 +947,7 @@ Frame::result_t Frame::process(SDL_Rect _size, SDL_Rect _actualSize, const std:: float winFactor = ((float)_size.w / (float)this->actualSize.w); this->actualSize.x = (mousex - omousex) / winFactor + oldSliderX; this->actualSize.x = std::min(std::max(0, this->actualSize.x), std::max(0, this->actualSize.w - size.w)); + syncScroll(); } usable = result.usable = false; ticks = -1; // hack to fix sliders in drop downs @@ -945,6 +963,7 @@ Frame::result_t Frame::process(SDL_Rect _size, SDL_Rect _actualSize, const std:: if (mousestatus[SDL_BUTTON_LEFT]) { this->actualSize.x += omousex < handleRect.x ? -std::min(entrySize, size.w) : std::min(entrySize, size.w); this->actualSize.x = std::min(std::max(0, this->actualSize.x), std::max(0, this->actualSize.w - size.w)); + syncScroll(); mousestatus[SDL_BUTTON_LEFT] = 0; } usable = result.usable = false; @@ -980,6 +999,7 @@ Frame::result_t Frame::process(SDL_Rect _size, SDL_Rect _actualSize, const std:: float winFactor = ((float)_size.h / (float)this->actualSize.h); this->actualSize.y = (mousey - omousey) / winFactor + oldSliderY; this->actualSize.y = std::min(std::max(0, this->actualSize.y), std::max(0, this->actualSize.h - size.h)); + syncScroll(); } usable = result.usable = false; ticks = -1; // hack to fix sliders in drop downs @@ -995,6 +1015,7 @@ Frame::result_t Frame::process(SDL_Rect _size, SDL_Rect _actualSize, const std:: if (mousestatus[SDL_BUTTON_LEFT]) { this->actualSize.y += omousey < handleRect.y ? -std::min(entrySize, size.h) : std::min(entrySize, size.h); this->actualSize.y = std::min(std::max(0, this->actualSize.y), std::max(0, this->actualSize.h - size.h)); + syncScroll(); mousestatus[SDL_BUTTON_LEFT] = 0; } usable = result.usable = false; @@ -1723,6 +1744,7 @@ void Frame::scrollToSelection(bool scroll_to_top) { } void Frame::activateEntry(entry_t& entry) { + activation = &entry; if (keystatus[SDL_SCANCODE_LCTRL] || keystatus[SDL_SCANCODE_RCTRL]) { if (entry.ctrlClick) { (*entry.ctrlClick)(entry); @@ -2178,3 +2200,20 @@ void Frame::drawImage(const image_t* image, const SDL_Rect& _size, const SDL_Rec } } } + +void Frame::addSyncScrollTarget(const char* name) { + syncScrollTargets.push_back(std::move(std::string(name))); +} + +void Frame::syncScroll() { + assert(gui); + for (auto name : syncScrollTargets) { + auto frame = gui->findFrame(name.c_str()); + if (frame) { + auto _size = frame->getActualSize(); + _size.x = actualSize.x; + _size.y = actualSize.y; + frame->setActualSize(_size); + } + } +} diff --git a/src/ui/Frame.hpp b/src/ui/Frame.hpp index 3a7a1669c..0877f4983 100644 --- a/src/ui/Frame.hpp +++ b/src/ui/Frame.hpp @@ -283,6 +283,13 @@ class Frame : public Widget { //! @param scroll_to_top if true, scroll the selection to the very top of the frame void scrollToSelection(bool scroll_to_top = false); + //! adds a frame to an internal list which will match our scroll values at all times. + //! @param name the name of the frame to sync with + void addSyncScrollTarget(const char* name); + + //! synchronizes scrolling with sync scroll targets + void syncScroll(); + virtual type_t getType() const override { return WIDGET_FRAME; } const char* getFont() const { return font.c_str(); } const int getBorder() const { return border; } @@ -319,6 +326,7 @@ class Frame : public Widget { void setHigh(bool b) { borderStyle = b ? BORDER_BEVEL_HIGH : BORDER_BEVEL_LOW; } void setColor(const Uint32& _color) { color = _color; } void setSelectedEntryColor(const Uint32& _color) { selectedEntryColor = _color; } + void setActivatedEntryColor(const Uint32& _color) { activatedEntryColor = _color; } void setBorderColor(const Uint32& _color) { borderColor = _color; } void setDisabled(const bool _disabled) { disabled = _disabled; } void setHollow(const bool _hollow) { hollow = _hollow; } @@ -332,6 +340,7 @@ class Frame : public Widget { void setClickable(const bool _clickable) { clickable = _clickable; } void setDontTickChildren(const bool b) { dontTickChildren = b; } void setEntrySize(int _size) { entrySize = _size; } + void setActivation(entry_t* entry) { activation = entry; } private: Uint32 ticks = 0; //!< number of engine ticks this frame has persisted @@ -342,6 +351,7 @@ class Frame : public Widget { border_style_t borderStyle = BORDER_BEVEL_HIGH; //!< border style Uint32 color = 0; //!< the frame's color Uint32 selectedEntryColor = 0; //!< selected entry color + Uint32 activatedEntryColor = 0; //!< activated entry color Uint32 borderColor = 0; //!< the frame's border color (only used for flat border) const char* tooltip = nullptr; //!< points to the tooltip that should be displayed by the (master) frame, or nullptr if none should be displayed bool hollow = false; //!< if true, the frame doesn't have a solid background @@ -352,6 +362,7 @@ class Frame : public Widget { bool dropDown = false; //!< if true, the frame is destroyed when specific inputs register Uint32 dropDownClicked = 0; //!< key states stored for removing drop downs int selection = -1; //!< entry selection + entry_t* activation = nullptr; //!< activated entry bool allowScrollBinds = true; //!< if true, scroll wheel + right stick can scroll frame bool allowScrolling = false; //!< must be enabled for any kind of scrolling/actualSize to work bool scrollbars = true; //!< must be true for sliders to be drawn/usable @@ -373,6 +384,8 @@ class Frame : public Widget { std::vector sliders; std::vector list; + std::vector syncScrollTargets; + //! activate the given list entry //! @param entry the entry to activate void activateEntry(entry_t& entry); diff --git a/src/ui/GameUI.cpp b/src/ui/GameUI.cpp index 9335aeb69..f7a5196bd 100644 --- a/src/ui/GameUI.cpp +++ b/src/ui/GameUI.cpp @@ -15529,7 +15529,7 @@ void doFrames() { { ++gui_ticks; } - (void)gui->process(); + (void)gui->process(); gui->predraw(); gui->draw(); diff --git a/src/ui/MainMenu.cpp b/src/ui/MainMenu.cpp index 193107cf8..28a90cea9 100644 --- a/src/ui/MainMenu.cpp +++ b/src/ui/MainMenu.cpp @@ -231,6 +231,7 @@ namespace MainMenu { bool extra_life_enabled; bool cheats_enabled; bool skipintro; + int port_number; inline bool save(); // true if video needs restart static inline AllSettings load(); static inline AllSettings reset(); @@ -1272,6 +1273,7 @@ namespace MainMenu { } sendSvFlagsOverNet(); ::skipintro = skipintro; + ::portnumber = (Uint16)port_number ? (Uint16)port_number : DEFAULT_PORT; // TODO crossplay settings #ifdef USE_EOS @@ -1351,6 +1353,7 @@ namespace MainMenu { settings.extra_life_enabled = svFlags & SV_FLAG_LIFESAVING; settings.cheats_enabled = svFlags & SV_FLAG_CHEATS; settings.skipintro = true; + settings.port_number = ::portnumber; return settings; } @@ -1407,6 +1410,7 @@ namespace MainMenu { settings.extra_life_enabled = false; settings.cheats_enabled = false; settings.skipintro = true; + settings.port_number = DEFAULT_PORT; return settings; } @@ -1465,6 +1469,7 @@ namespace MainMenu { file->property("skipintro", skipintro); file->property("use_model_cache", useModelCache); file->property("debug_keys_enabled", enableDebugKeys); + file->property("port_number", port_number); return true; } @@ -3913,15 +3918,17 @@ namespace MainMenu { "If you're a streamer and know what doxxing is, definitely switch this on.", allSettings.show_ip_address_enabled, [](Button& button){soundToggle(); allSettings.show_ip_address_enabled = button.isPressed();}); + char buf[16]; + snprintf(buf, sizeof(buf), "%hu", (Uint16)allSettings.port_number); y += settingsAddSubHeader(*settings_subwindow, y, "lan", "LAN"); y += settingsAddField(*settings_subwindow, y, "port_number", "Port", - "The port number to use when opening a network socket as a host.", - "12345", nullptr); + "The port number to use when hosting a LAN lobby.", + buf, [](Field& field){soundActivate(); allSettings.port_number = (Uint16)strtol(field.getText(), nullptr, 10);}); y += settingsAddSubHeader(*settings_subwindow, y, "crossplay", "Crossplay"); y += settingsAddBooleanWithCustomizeOption(*settings_subwindow, y, "crossplay", "Crossplay Enabled", "Enable crossplay through Epic Online Services", - false, [](Button&){}, [](Button&){}); + false, [](Button&){soundWarning();}, [](Button&){soundWarning();}); hookSettings(*settings_subwindow, {{Setting::Type::Boolean, "show_ip_address"}, @@ -4480,6 +4487,33 @@ namespace MainMenu { } } + void handleScanPacket() { + if (directConnect) { + char hostname[256] = { '\0' }; +#ifdef LINUX + (void)gethostname(hostname, sizeof(hostname)); +#else + strcpy(hostname, "Barony"); +#endif + Uint32 hostname_len = (Uint32)strlen(hostname); + SDLNet_Write32(hostname_len, &net_packet->data[4]); + for (int c = 0; c < hostname_len; ++c) { + net_packet->data[8 + c] = hostname[c]; + } + Uint32 offset = 8 + hostname_len; + int numplayers = 0; + for (int c = 0; c < MAXPLAYERS; ++c) { + if (!client_disconnected[c]) { + ++numplayers; + } + } + SDLNet_Write32(numplayers, &net_packet->data[offset]); + net_packet->data[offset + 4] = intro ? 0 : 1; + net_packet->len = offset + 5; + sendPacket(net_sock, -1, net_packet, 0); + } + } + static void handlePacketsAsServer() { #ifdef STEAMWORKS CSteamID newSteamID; @@ -4632,29 +4666,7 @@ namespace MainMenu { // network scan else if (packetId == 'SCAN') { - if (directConnect) { - char hostname[256] = { '\0' }; -#ifdef LINUX - (void)gethostname(hostname, sizeof(hostname)); -#else - strcpy(hostname, "Barony"); -#endif - Uint32 hostname_len = (Uint32)strlen(hostname); - SDLNet_Write32(hostname_len, &net_packet->data[4]); - for (int c = 0; c < hostname_len; ++c) { - net_packet->data[8 + c] = hostname[c]; - } - Uint32 offset = 8 + hostname_len; - int numplayers = 0; - for (int c = 0; c < MAXPLAYERS; ++c) { - if (!client_disconnected[c]) { - ++numplayers; - } - } - SDLNet_Write32(numplayers, &net_packet->data[offset]); - net_packet->len = offset + 4; - sendPacket(net_sock, -1, net_packet, 0); - } + handleScanPacket(); continue; } @@ -5098,10 +5110,8 @@ namespace MainMenu { // game start if (packetId == 'STRT') { - if (intro) { - destroyMainMenu(); - createDummyMainMenu(); - } + destroyMainMenu(); + createDummyMainMenu(); lobbyWindowSvFlags = SDLNet_Read32(&net_packet->data[4]); uniqueGameKey = SDLNet_Read32(&net_packet->data[8]); beginFade(FadeDestination::GameStart); @@ -5112,6 +5122,17 @@ namespace MainMenu { continue; } + // we can get an ENTU packet if the server already started and we missed it somehow + else if (packetId == 'ENTU') { + destroyMainMenu(); + createDummyMainMenu(); + beginFade(FadeDestination::GameStart); + + // TODO we may not get a unique game key or server flags this way!! + + continue; + } + // new player else if (packetId == 'JOIN') { int player = net_packet->data[4]; @@ -5274,8 +5295,7 @@ namespace MainMenu { closeNetworkInterfaces(); directConnect = true; - // TODO get port number from settings - Uint16 port = DEFAULT_PORT; + Uint16 port = ::portnumber ? ::portnumber : DEFAULT_PORT; // resolve local host's address if (SDLNet_ResolveHost(&net_server, NULL, port) == -1) { @@ -5320,6 +5340,10 @@ namespace MainMenu { } static void connectToServer(const char* address, LobbyType lobbyType) { + if (!address || address[0] == '\0') { + soundError(); + return; + } textPrompt("Connecting to server..."); // reset keepalive @@ -7473,7 +7497,6 @@ namespace MainMenu { invite->setBorderColor(0); invite->setHighlightColor(0); invite->setCallback([](Button&){buttonInviteFriends(NULL);}); - invite->select(); } static void createWaitingStone(int index) { @@ -7514,17 +7537,33 @@ namespace MainMenu { } static void createReadyStone(int index, bool local, bool ready) { - assert(main_menu_frame); + if (!main_menu_frame) { + // maybe this could happen if we got a REDY packet + // super late or something. + if (!ready) { + fadeout = false; + main_menu_fade_destination = FadeDestination::None; + } + return; + } auto lobby = main_menu_frame->findFrame("lobby"); - assert(lobby); + if (!lobby) { + // maybe this could happen if we got a REDY packet + // super late or something. + if (!ready) { + fadeout = false; + main_menu_fade_destination = FadeDestination::None; + } + return; + } auto card = lobby->findFrame((std::string("card") + std::to_string(index)).c_str()); if (card) { card->removeSelf(); } - card = lobby->addFrame((std::string("card") + std::to_string(index)).c_str()); + card = lobby->addFrame((std::string("card") + std::to_string(index)).c_str()); assert(card); card->setSize(SDL_Rect{20 + 320 * index, Frame::virtualScreenY - 146 - 100, 280, 146}); card->setActualSize(SDL_Rect{0, 0, card->getSize().w, card->getSize().h}); card->setColor(0); @@ -7540,7 +7579,7 @@ namespace MainMenu { "backdrop" ); - auto banner = card->addField("banner", 64); + auto banner = card->addField("banner", 64); assert(banner); banner->setText((std::string("PLAYER ") + std::to_string(index + 1)).c_str()); banner->setFont(banner_font); banner->setSize(SDL_Rect{(card->getSize().w - 200) / 2, 30, 200, 100}); @@ -7548,7 +7587,16 @@ namespace MainMenu { banner->setHJustify(Field::justify_t::CENTER); if (local) { - auto cancel = card->addButton("cancel_button"); + static auto cancel_fn = [](int index){ + if (main_menu_fade_destination == FadeDestination::GameStart) { + // fix servers being able to back out on the last frame + return; + } else { + createCharacterCard(index); + } + }; + + auto cancel = card->addButton("cancel_button"); assert(cancel); cancel->setText("Ready!"); cancel->setHideSelectors(true); cancel->setFont(smallfont_outline); @@ -7564,14 +7612,14 @@ namespace MainMenu { cancel->setWidgetSearchParent(card->getName()); cancel->addWidgetAction("MenuConfirm", "FraggleMaggleStiggleWortz"); // some garbage so that this glyph isn't auto-bound switch (index) { - case 0: cancel->setCallback([](Button&){createCharacterCard(0);}); break; - case 1: cancel->setCallback([](Button&){createCharacterCard(1);}); break; - case 2: cancel->setCallback([](Button&){createCharacterCard(2);}); break; - case 3: cancel->setCallback([](Button&){createCharacterCard(3);}); break; + case 0: cancel->setCallback([](Button&){cancel_fn(0);}); break; + case 1: cancel->setCallback([](Button&){cancel_fn(1);}); break; + case 2: cancel->setCallback([](Button&){cancel_fn(2);}); break; + case 3: cancel->setCallback([](Button&){cancel_fn(3);}); break; } cancel->select(); } else { - auto status = card->addField("status", 64); + auto status = card->addField("status", 64); assert(status); if (ready) { status->setText("Ready!"); } else { @@ -7615,17 +7663,19 @@ namespace MainMenu { if (countdown) { countdown->removeSelf(); } + fadeout = false; + main_menu_fade_destination = FadeDestination::None; } } static void startGame() { - destroyMainMenu(); - createDummyMainMenu(); if (multiplayer == CLIENT) { if (!fadeout || main_menu_fade_destination != FadeDestination::GameStart) { beginFade(MainMenu::FadeDestination::GameStartDummy); } } else { + destroyMainMenu(); + createDummyMainMenu(); beginFade(MainMenu::FadeDestination::GameStart); // initialize all player stats @@ -7652,7 +7702,11 @@ namespace MainMenu { if (client_disconnected[c]) { continue; } - strcpy((char*)net_packet->data, "STRT"); + if (intro) { + memcpy((char*)net_packet->data, "STRT", 4); + } else { + memcpy((char*)net_packet->data, "RSTR", 4); + } SDLNet_Write32(svFlags, &net_packet->data[4]); SDLNet_Write32(uniqueGameKey, &net_packet->data[8]); net_packet->data[12] = loadingsavegame ? 1 : 0; @@ -7667,7 +7721,6 @@ namespace MainMenu { static void createCountdownTimer() { static const char* timer_font = "fonts/pixelmix_bold.ttf#64#2"; - static float countdown_timer; auto lobby = main_menu_frame->findFrame("lobby"); assert(lobby); @@ -7676,7 +7729,9 @@ namespace MainMenu { frame->setSize(SDL_Rect{0, 0, Frame::virtualScreenX, Frame::virtualScreenY}); frame->setHollow(true); - countdown_timer = 3.f; + static Uint32 countdown_end; + countdown_end = ticks + TICKS_PER_SECOND * 3; + auto countdown = frame->addField("timer", 8); countdown->setHJustify(Field::justify_t::LEFT); countdown->setVJustify(Field::justify_t::TOP); @@ -7684,42 +7739,41 @@ namespace MainMenu { countdown->setSize(SDL_Rect{(Frame::virtualScreenX - 40) / 2, 0, 300, 200}); countdown->setTickCallback([](Widget& widget){ auto countdown = static_cast(&widget); - const float inc = 1.f / fpsLimit; - countdown_timer -= inc; - if (countdown_timer <= 0.f) { + if (ticks >= countdown_end) { startGame(); } else { - if (countdown_timer < 0.25f) { + Uint32 fourth = TICKS_PER_SECOND / 4; + if (ticks >= countdown_end - fourth) { countdown->setText("1..."); } - else if (countdown_timer < 0.5f) { + else if (ticks >= countdown_end - fourth * 2) { countdown->setText("1.."); } - else if (countdown_timer < 0.75f) { + else if (ticks >= countdown_end - fourth * 3) { countdown->setText("1."); } - else if (countdown_timer < 1.f) { + else if (ticks >= countdown_end - fourth * 4) { countdown->setText("1"); } - else if (countdown_timer < 1.25f) { + else if (ticks >= countdown_end - fourth * 5) { countdown->setText("2..."); } - else if (countdown_timer < 1.5f) { + else if (ticks >= countdown_end - fourth * 6) { countdown->setText("2.."); } - else if (countdown_timer < 1.75f) { + else if (ticks >= countdown_end - fourth * 7) { countdown->setText("2."); } - else if (countdown_timer < 2.f) { + else if (ticks >= countdown_end - fourth * 8) { countdown->setText("2"); } - else if (countdown_timer < 2.25f) { + else if (ticks >= countdown_end - fourth * 9) { countdown->setText("3..."); } - else if (countdown_timer < 2.5f) { + else if (ticks >= countdown_end - fourth * 10) { countdown->setText("3.."); } - else if (countdown_timer < 2.75f) { + else if (ticks >= countdown_end - fourth * 11) { countdown->setText("3."); } else { @@ -8459,6 +8513,9 @@ namespace MainMenu { static void createLobbyBrowser(Button& button) { soundActivate(); + static int selectedLobby; + selectedLobby = -1; + enum class BrowserMode { Online, LAN, @@ -8510,7 +8567,7 @@ namespace MainMenu { int _players = 0, int _ping = 0, bool _locked = false, - const char* _address = "localhost"): + const char* _address = ""): name(_name), players(_players), ping(_ping), @@ -8519,7 +8576,7 @@ namespace MainMenu { {} }; - static std::unordered_map lobbies; + static std::vector lobbies; lobbies.clear(); static auto add_lobby = [](const LobbyInfo& info){ @@ -8533,7 +8590,7 @@ namespace MainMenu { auto players = window->findFrame("players"); assert(players); auto pings = window->findFrame("pings"); assert(pings); - // function to make selection the same on all columns... + // function to make highlight the same on all columns... static auto selection_fn = [](Frame::entry_t& entry){ assert(main_menu_frame); auto window = main_menu_frame->findFrame("lobby_browser_window"); assert(window); @@ -8545,8 +8602,24 @@ namespace MainMenu { pings->setSelection(entry.parent.getSelection()); }; + // function to choose a specific lobby + static auto activate_fn = [](Frame::entry_t& entry){ + assert(main_menu_frame); + auto window = main_menu_frame->findFrame("lobby_browser_window"); assert(window); + auto names = window->findFrame("names"); assert(names); + auto players = window->findFrame("players"); assert(players); + auto pings = window->findFrame("pings"); assert(pings); + auto selection = entry.parent.getSelection(); + names->setActivation(names->getEntries()[selection]); + players->setActivation(players->getEntries()[selection]); + pings->setActivation(pings->getEntries()[selection]); + selectedLobby = selection; + }; + // name cell auto entry_name = names->addEntry(info.name.c_str(), true); + entry_name->click = activate_fn; + entry_name->ctrlClick = activate_fn; entry_name->highlight = selection_fn; entry_name->selected = selection_fn; entry_name->color = info.locked ? makeColor(50, 56, 67, 255) : makeColor(102, 69, 36, 255); @@ -8567,6 +8640,8 @@ namespace MainMenu { } } auto entry_players = players->addEntry(info.name.c_str(), true); + entry_players->click = activate_fn; + entry_players->ctrlClick = activate_fn; entry_players->highlight = selection_fn; entry_players->selected = selection_fn; entry_players->color = 0xffffffff; @@ -8574,6 +8649,8 @@ namespace MainMenu { // ping cell auto entry_ping = pings->addEntry(info.name.c_str(), true); + entry_ping->click = activate_fn; + entry_ping->ctrlClick = activate_fn; entry_ping->highlight = selection_fn; entry_ping->selected = selection_fn; entry_ping->color = 0xffffffff; @@ -8589,7 +8666,11 @@ namespace MainMenu { } } - lobbies.emplace(info.name, info); + auto slider = window->findSlider("scroll_slider"); + slider->setMaxValue(names->getActualSize().h - names->getSize().h); + slider->updateHandlePosition(); + + lobbies.push_back(info); }; static auto clear_lobbies = [](){ @@ -8602,6 +8683,7 @@ namespace MainMenu { players->clearEntries(); pings->clearEntries(); lobbies.clear(); + selectedLobby = -1; }; static Uint32 scan_ticks; @@ -8621,10 +8703,18 @@ namespace MainMenu { } else { // TODO } + + assert(main_menu_frame); + auto window = main_menu_frame->findFrame("lobby_browser_window"); assert(window); + auto slider = window->findSlider("scroll_slider"); + slider->setValue(0.f); + slider->setMinValue(0.f); + slider->setMaxValue(0.f); + slider->updateHandlePosition(); }; // while the window is open, listen for SCAN packets - window->setTickCallback([](Widget&){ + window->setTickCallback([](Widget& widget){ if (multiplayer != CLIENT && directConnect) { if (SDLNet_UDP_Recv(net_sock, net_packet)) { Uint32 packetId = SDLNet_Read32(net_packet->data); @@ -8645,7 +8735,7 @@ namespace MainMenu { info.name = hostname; info.players = players; info.ping = ping; - info.locked = false; + info.locked = net_packet->data[offset + 4]; Uint32 host = net_packet->address.host; char buf[16]; @@ -8852,34 +8942,29 @@ namespace MainMenu { enter_code->setCallback(enter_code_fn); static auto join_lobby_fn = [](Button& button){ - assert(main_menu_frame); - auto window = main_menu_frame->findFrame("lobby_browser_window"); assert(window); - auto names = window->findFrame("names"); assert(names); - int selection = names->getSelection(); - const auto& entries = names->getEntries(); - if (selection >= 0 && selection < entries.size()) { - const auto& entry = entries[selection]; - auto find = lobbies.find(entry->text); - if (find != lobbies.end()) { - const auto& lobby = find->second; + if (selectedLobby >= 0 && selectedLobby < lobbies.size()) { + const auto& lobby = lobbies[selectedLobby]; + if (!lobby.locked) { connectToServer(lobby.address.c_str(), LobbyType::LobbyLAN); + } else { + soundWarning(); } - } else { - monoPrompt("Select a lobby to join first.", - "Okay", - [](Button&){ - soundCancel(); - assert(main_menu_frame); - auto window = main_menu_frame->findFrame("lobby_browser_window"); assert(window); - auto names = window->findFrame("names"); assert(names); - names->select(); - auto prompt = main_menu_frame->findFrame("mono_prompt"); - if (prompt) { - auto dimmer = static_cast(prompt->getParent()); assert(dimmer); - dimmer->removeSelf(); - } - }); - } + } else { + monoPrompt("Select a lobby to join first.", + "Okay", + [](Button&){ + soundCancel(); + assert(main_menu_frame); + auto window = main_menu_frame->findFrame("lobby_browser_window"); assert(window); + auto names = window->findFrame("names"); assert(names); + names->select(); + auto prompt = main_menu_frame->findFrame("mono_prompt"); + if (prompt) { + auto dimmer = static_cast(prompt->getParent()); assert(dimmer); + dimmer->removeSelf(); + } + }); + } }; auto join_lobby = window->addButton("join_lobby"); @@ -8915,12 +9000,15 @@ namespace MainMenu { name_column_header->setText(" Lobby Name"); auto list = window->addFrame("names"); + list->setScrollBarsEnabled(false); list->setSize(SDL_Rect{342, 140, 168, 200}); + list->setActualSize(SDL_Rect{0, 0, 168, 200}); list->setFont(smallfont_no_outline); list->setColor(0); list->setBorder(0); list->setEntrySize(18); - list->setSelectedEntryColor(makeColor(22, 25, 30, 255)); + list->setSelectedEntryColor(makeColor(10, 12, 15, 255)); + list->setActivatedEntryColor(makeColor(22, 25, 30, 255)); list->setTickCallback(tick_callback); list->setWidgetSearchParent(window->getName()); list->addWidgetMovement("MenuListCancel", list->getName()); @@ -8933,6 +9021,8 @@ namespace MainMenu { list->setWidgetUp("online_tab"); list->setWidgetRight("players"); list->setWidgetDown("enter_code"); + list->addSyncScrollTarget("players"); + list->addSyncScrollTarget("pings"); list->select(); } @@ -8947,12 +9037,15 @@ namespace MainMenu { players_column_header->setText(" Players"); auto list = window->addFrame("players"); + list->setScrollBarsEnabled(false); list->setSize(SDL_Rect{516, 140, 72, 200}); + list->setActualSize(SDL_Rect{0, 0, 72, 200}); list->setFont(smallfont_no_outline); list->setColor(0); list->setBorder(0); list->setEntrySize(18); - list->setSelectedEntryColor(makeColor(22, 25, 30, 255)); + list->setSelectedEntryColor(makeColor(10, 12, 15, 255)); + list->setActivatedEntryColor(makeColor(22, 25, 30, 255)); list->setTickCallback(tick_callback); list->setWidgetSearchParent(window->getName()); list->addWidgetMovement("MenuListCancel", list->getName()); @@ -8966,6 +9059,8 @@ namespace MainMenu { list->setWidgetRight("pings"); list->setWidgetLeft("names"); list->setWidgetDown("enter_code"); + list->addSyncScrollTarget("names"); + list->addSyncScrollTarget("pings"); } // ping column @@ -8979,12 +9074,15 @@ namespace MainMenu { ping_column_header->setText(" Ping"); auto list = window->addFrame("pings"); - list->setSize(SDL_Rect{594, 140, 44, 230}); + list->setScrollBarsEnabled(false); + list->setSize(SDL_Rect{594, 140, 44, 200}); + list->setActualSize(SDL_Rect{0, 0, 44, 200}); list->setFont(smallfont_no_outline); list->setColor(0); list->setBorder(0); list->setEntrySize(18); - list->setSelectedEntryColor(makeColor(22, 25, 30, 255)); + list->setSelectedEntryColor(makeColor(10, 12, 15, 255)); + list->setActivatedEntryColor(makeColor(22, 25, 30, 255)); list->setTickCallback(tick_callback); list->setWidgetSearchParent(window->getName()); list->addWidgetMovement("MenuListCancel", list->getName()); @@ -8997,6 +9095,8 @@ namespace MainMenu { list->setWidgetUp("online_tab"); list->setWidgetLeft("players"); list->setWidgetDown("enter_code"); + list->addSyncScrollTarget("names"); + list->addSyncScrollTarget("players"); } auto slider = window->addSlider("scroll_slider"); @@ -9007,9 +9107,6 @@ namespace MainMenu { slider->setRailImage("*images/ui/Main Menus/Play/LobbyBrowser/Lobby_Slider_Backing01B.png"); slider->setHandleImage("*images/ui/Main Menus/Play/LobbyBrowser/UI_Slider_Boulder00.png"); slider->setBorder(24); - slider->setMinValue(0.f); - slider->setValue(0.f); - slider->setMaxValue(100.f); slider->setWidgetSearchParent(window->getName()); slider->addWidgetAction("MenuPageLeft", "online_tab"); slider->addWidgetAction("MenuPageRight", "lan_tab"); @@ -9020,8 +9117,38 @@ namespace MainMenu { slider->setWidgetUp("wireless_tab"); slider->setWidgetDown("join_lobby"); slider->setWidgetLeft("pings"); + slider->setCallback([](Slider& slider){ + Frame* frame = static_cast(slider.getParent()); assert(frame); + { + Frame* column = frame->findFrame("names"); assert(column); + auto actualSize = column->getActualSize(); + actualSize.y = slider.getValue(); + column->setActualSize(actualSize); + } + { + Frame* column = frame->findFrame("players"); assert(column); + auto actualSize = column->getActualSize(); + actualSize.y = slider.getValue(); + column->setActualSize(actualSize); + } + { + Frame* column = frame->findFrame("pings"); assert(column); + auto actualSize = column->getActualSize(); + actualSize.y = slider.getValue(); + column->setActualSize(actualSize); + } + slider.updateHandlePosition(); + }); + slider->setTickCallback([](Widget& widget){ + Slider* slider = static_cast(&widget); + Frame* frame = static_cast(slider->getParent()); assert(frame); + Frame* names = frame->findFrame("names"); assert(names); + auto actualSize = names->getActualSize(); + slider->setValue(actualSize.y); + slider->updateHandlePosition(); + }); - if (1) { + if (0) { // test lobbies add_lobby(LobbyInfo("Ben", 1, 50, false)); add_lobby(LobbyInfo("Sheridan", 3, 50, false)); @@ -9034,6 +9161,11 @@ namespace MainMenu { add_lobby(LobbyInfo("What is the longest name we can fit in a Barony lobby?", 4, 150, false)); add_lobby(LobbyInfo("16 PLAYER SMASH FEST", 16, 90, false)); add_lobby(LobbyInfo("ur mom", 16, 160, true)); + add_lobby(LobbyInfo("waow more lobbies", 16, 160, true)); + add_lobby(LobbyInfo("snobby lobby", 16, 260, true)); + add_lobby(LobbyInfo("gAmERs RiSe uP!!", 16, 0, false)); + add_lobby(LobbyInfo("a very unsuspicious lobby", 2, 130, false)); + add_lobby(LobbyInfo("cool lobby bro!", 3, 240, false)); } else { // scan for lobbies immediately refresh->activate(); @@ -10261,6 +10393,27 @@ namespace MainMenu { restore_defaults->setCallback([](Button& button){ soundActivate(); settingsReset(); + auto settings = static_cast(button.getParent()); assert(settings); + std::vector tabs = { + "Controls", + "Audio", + "Video", + "UI", + }; + if (intro) { + tabs.insert(tabs.begin(), "Online"); + } else { + tabs.insert(tabs.begin(), "Game"); + } + for (auto tab : tabs) { + auto button = settings->findButton(tab); assert(button); + const char* name = "*images/ui/Main Menus/Settings/Settings_Button_SubTitleSelect00.png"; + if (strcmp(button->getBackground(), name) == 0) { + button->select(); + button->activate(); + return; + } + } }); auto discard_and_exit = settings->addButton("discard_and_exit"); diff --git a/src/ui/MainMenu.hpp b/src/ui/MainMenu.hpp index ba26ca69e..f865c0aa9 100644 --- a/src/ui/MainMenu.hpp +++ b/src/ui/MainMenu.hpp @@ -84,4 +84,5 @@ namespace MainMenu { void disconnectedFromServer(); void receivedInvite(); + void handleScanPacket(); } From 5004b646e012ed3b74a450359c56138eba7998b2 Mon Sep 17 00:00:00 2001 From: WALL OF JUSTICE Date: Sat, 5 Mar 2022 13:09:57 +1100 Subject: [PATCH 2/3] More Misc fixes (#636) * * furniture magic damage fix not showing at all health values * * function to clear facehotbar conflicting bindings (allow LB/RB to be used without accidental usage) * * enemy HP bars set 2 parameters in HUD_Settings.json to quickly fade if HP 0 and you are close to the HP bar * * facemenu quickcast disable default * * add stick glyph paths for NX * * fix editor compilation * * fix backpack slots not being init to correct size if starting with brewer * * fix dummybot no world tooltip * * auto appraise enable default ON * * pressed states for sticks in getGlyphPathForBinding * * add a prompt for the expand/hide tooltip detail * add appraise functionality to gamepads * * more tooltip prompts on lang file Co-authored-by: WALL OF JUSTICE <-> --- lang/en.txt | 3 + src/game.cpp | 1 + src/input.cpp | 307 +++++++++++++++++++++++--- src/input.hpp | 3 + src/interface/drawstatus.cpp | 4 +- src/interface/interface.cpp | 344 +++++++++++++----------------- src/interface/interface.hpp | 3 +- src/interface/playerinventory.cpp | 97 ++++++++- src/magic/actmagic.cpp | 212 +++++++++--------- src/player.cpp | 3 +- src/player.hpp | 2 +- src/ui/GameUI.cpp | 60 ++++-- 12 files changed, 681 insertions(+), 358 deletions(-) diff --git a/lang/en.txt b/lang/en.txt index 1e3ded478..c66f20ee4 100644 --- a/lang/en.txt +++ b/lang/en.txt @@ -6056,5 +6056,8 @@ Cast# 4099 Took %d items from the chest.# 4100 You have no room left in your pack!# 4101 You reignite another %s.# +4102 Appraise item# +4103 View spell details# +4104 Hide spell details# 4199 end# \ No newline at end of file diff --git a/src/game.cpp b/src/game.cpp index 647ddc35a..06e505cb1 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3152,6 +3152,7 @@ void handleEvents(void) for (auto& input : Input::inputs) { input.updateReleasedBindings(); input.update(); + input.consumeBindingsSharedWithFaceHotbar(); } while ( SDL_PollEvent(&event) ) // poll SDL events diff --git a/src/input.cpp b/src/input.cpp index acc0f1aa8..13f49e3fb 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -352,14 +352,28 @@ std::string Input::getGlyphPathForInput(const char* input, bool pressed) { return rootPath + "G_Switch_R00.png"; } - if (in == "ButtonLeftStick") + if ( in == "ButtonLeftStick" ) { - return rootPath + "Stick_Switch_00B.png"; - } - if (in == "ButtonRightStick") + if ( pressed ) + { + return rootPath + "Stick_Switch_L_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_L_00.png"; + } + } + if ( in == "ButtonRightStick" ) { - return rootPath + "Stick_Switch_00B.png"; - } + if ( pressed ) + { + return rootPath + "Stick_Switch_R_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_R_00.png"; + } + } if (in == "ButtonStart") { return rootPath + "PlusMed00.png"; @@ -368,17 +382,94 @@ std::string Input::getGlyphPathForInput(const char* input, bool pressed) { return rootPath + "MinusMed00.png"; } - if (in == "StickLeftX+" || - in == "StickLeftX-" || - in == "StickLeftY+" || - in == "StickLeftY-" || - in == "StickRightX+" || - in == "StickRightX-" || - in == "StickRightY+" || - in == "StickRightY-") - { - return rootPath + "Stick_Switch_00B.png"; - } + if ( in == "StickLeftX-" ) + { + if ( pressed ) + { + return rootPath + "Stick_Switch_L_Left_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_L_Left_00.png"; + } + } + if ( in == "StickLeftX+" ) + { + if ( pressed ) + { + return rootPath + "Stick_Switch_L_Right_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_L_Right_00.png"; + } +} + if ( in == "StickLeftY-" ) + { + if ( pressed ) + { + return rootPath + "Stick_Switch_L_Up_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_L_Up_00.png"; + } + } + if ( in == "StickLeftY+" ) + { + if ( pressed ) + { + return rootPath + "Stick_Switch_L_Down_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_L_Down_00.png"; + } + } + if ( in == "StickRightX-" ) + { + if ( pressed ) + { + return rootPath + "Stick_Switch_R_Left_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_R_Left_00.png"; + } + } + if ( in == "StickRightX+" ) + { + if ( pressed ) + { + return rootPath + "Stick_Switch_R_Right_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_R_Right_00.png"; + } + } + if ( in == "StickRightY-" ) + { + if ( pressed ) + { + return rootPath + "Stick_Switch_R_Up_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_R_Up_00.png"; + } + } + if ( in == "StickRightY+" ) + { + if ( pressed ) + { + return rootPath + "Stick_Switch_R_Down_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_R_Down_00.png"; + } + } if (in == "LeftTrigger") { return rootPath + "G_Switch_ZL00.png"; @@ -659,9 +750,23 @@ std::string Input::getGlyphPathForBinding(const binding_t& binding, bool pressed case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return rootPath + "G_Switch_R00.png"; case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK: - return rootPath + "Stick_Switch_00B.png"; + if ( pressed ) + { + return rootPath + "Stick_Switch_L_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_L_00.png"; + } case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK: - return rootPath + "Stick_Switch_00B.png"; + if ( pressed ) + { + return rootPath + "Stick_Switch_R_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Switch_R_00.png"; + } case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START: return rootPath + "PlusMed00.png"; case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK: @@ -693,9 +798,23 @@ std::string Input::getGlyphPathForBinding(const binding_t& binding, bool pressed case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return rootPath + "Button_Xbox_RB_00.png"; case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK: - return rootPath + "Stick_Xbox_L_00.png"; + if ( pressed ) + { + return rootPath + "Stick_Xbox_L_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Xbox_L_00.png"; + } case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK: - return rootPath + "Stick_Xbox_R_00.png"; + if ( pressed ) + { + return rootPath + "Stick_Xbox_R_Pressed_00.png"; + } + else + { + return rootPath + "Stick_Xbox_R_00.png"; + } case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START: return rootPath + "Button_Xbox_Menu_00.png"; case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK: @@ -719,13 +838,41 @@ std::string Input::getGlyphPathForBinding(const binding_t& binding, bool pressed switch ( binding.padAxis ) { case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX: - return rootPath + "Stick_Switch_00B.png"; + if ( binding.padAxisNegative ) + { + return rootPath + "Stick_Switch_L_Left_00.png"; + } + else + { + return rootPath + "Stick_Switch_L_Right_00.png"; + } case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY: - return rootPath + "Stick_Switch_00B.png"; + if ( binding.padAxisNegative ) + { + return rootPath + "Stick_Switch_L_Up_00.png"; + } + else + { + return rootPath + "Stick_Switch_L_Down_00.png"; + } case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX: - return rootPath + "Stick_Switch_00B.png"; + if ( binding.padAxisNegative ) + { + return rootPath + "Stick_Switch_R_Left_00.png"; + } + else + { + return rootPath + "Stick_Switch_R_Right_00.png"; + } case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY: - return rootPath + "Stick_Switch_00B.png"; + if ( binding.padAxisNegative ) + { + return rootPath + "Stick_Switch_R_Up_00.png"; + } + else + { + return rootPath + "Stick_Switch_R_Down_00.png"; + } case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT: return rootPath + "G_Switch_ZL00.png"; case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT: @@ -1316,3 +1463,113 @@ Input::playerControlType_t Input::getPlayerControlType() #endif // !EDITOR return Input::PLAYER_CONTROLLED_BY_INVALID; } + +void Input::consumeBindingsSharedWithFaceHotbar() +{ +#ifndef EDITOR + if ( disabled ) + { + return; + } + if ( players[player]->hotbar.useHotbarFaceMenu ) + { + if ( players[player]->hotbar.faceMenuButtonHeld != Player::Hotbar_t::FaceMenuGroup::GROUP_NONE ) + { + const std::unordered_map faceMenuBindings = + { + std::make_pair("HotbarFacebarCancel", input("HotbarFacebarCancel")), + std::make_pair("HotbarFacebarLeft", input("HotbarFacebarLeft")), + std::make_pair("HotbarFacebarUp", input("HotbarFacebarUp")), + std::make_pair("HotbarFacebarRight", input("HotbarFacebarRight")), + std::make_pair("HotbarFacebarModifierLeft", input("HotbarFacebarModifierLeft")), + std::make_pair("HotbarFacebarModifierRight", input("HotbarFacebarModifierRight")) + }; + for ( auto& b : bindings ) + { + if ( !b.second.binary ) + { + continue; // don't pre-consume non-pressed buttons + } + if ( b.second.consumed ) + { + continue; // no need to consume again + } + for ( auto& faceMenuBinding : faceMenuBindings ) + { + if ( b.second.type == faceMenuBinding.second.type ) + { + if ( b.first == faceMenuBinding.first ) + { + continue; // skip the hotbar bindings + } + if ( b.second.type == binding_t::CONTROLLER_AXIS || + b.second.type == binding_t::CONTROLLER_BUTTON ) + { + if ( b.second.type == binding_t::CONTROLLER_BUTTON ) + { + if ( b.second.padButton == faceMenuBinding.second.padButton ) + { + b.second.consumed = true; + } + } + else + { + if ( b.second.padAxis == faceMenuBinding.second.padAxis ) + { + b.second.consumed = true; + } + } + } + else if ( + b.second.type == binding_t::JOYSTICK_AXIS || + b.second.type == binding_t::JOYSTICK_BUTTON || + b.second.type == binding_t::JOYSTICK_HAT ) + { + if ( b.second.type == binding_t::JOYSTICK_BUTTON ) + { + if ( b.second.joystickButton == faceMenuBinding.second.joystickButton ) + { + b.second.consumed = true; + } + } + else if ( b.second.type == binding_t::JOYSTICK_AXIS ) + { + if ( b.second.joystickAxis == faceMenuBinding.second.joystickAxis ) + { + b.second.consumed = true; + } + } + else + { + if ( b.second.joystickHat == faceMenuBinding.second.joystickHat ) + { + b.second.consumed = true; + } + } + } + else if ( b.second.type == binding_t::MOUSE_BUTTON ) + { + if ( b.second.mouseButton == faceMenuBinding.second.mouseButton ) + { + b.second.consumed = true; + if ( b.second.mouseButton == MOUSE_WHEEL_DOWN + || b.second.mouseButton == MOUSE_WHEEL_UP ) + { + mouseButtons[b.second.mouseButton] = false; // manually need to clear this + } + } + } + else if ( b.second.type == binding_t::KEYBOARD ) + { + if ( b.second.scancode == faceMenuBinding.second.scancode ) + { + b.second.consumed = true; + } + } + } + } + } + } + } +#endif +} \ No newline at end of file diff --git a/src/input.hpp b/src/input.hpp index 65f5842b3..1003e2354 100644 --- a/src/input.hpp +++ b/src/input.hpp @@ -202,6 +202,9 @@ class Input { static bool mouseButtons[18]; static const int MOUSE_WHEEL_UP; static const int MOUSE_WHEEL_DOWN; + + //! consume inputs related to the players face-hotbar if it is open + void consumeBindingsSharedWithFaceHotbar(); private: std::unordered_map bindings; diff --git a/src/interface/drawstatus.cpp b/src/interface/drawstatus.cpp index cc035d479..784f56c9c 100644 --- a/src/interface/drawstatus.cpp +++ b/src/interface/drawstatus.cpp @@ -2323,9 +2323,6 @@ void drawStatusNew(const int player) Input& input = Input::inputs[player]; - // enemy health - //enemyHPDamageBarHandler[player].displayCurrentHPBar(player); - int playerStatusBarWidth = 38 * uiscale_playerbars; int playerStatusBarHeight = 156 * uiscale_playerbars; @@ -3133,6 +3130,7 @@ void drawStatusNew(const int player) } players[player]->hotbar.faceMenuButtonHeld = pressed; + Input::inputs[player].consumeBindingsSharedWithFaceHotbar(); } //Moving the cursor changes the currently selected hotbar slot. diff --git a/src/interface/interface.cpp b/src/interface/interface.cpp index b8ae3d925..3a9078826 100644 --- a/src/interface/interface.cpp +++ b/src/interface/interface.cpp @@ -144,7 +144,7 @@ int autosort_inventory_categories[NUM_AUTOSORT_CATEGORIES] = { 0, 0, 0, 0, bool hotbar_numkey_quick_add = false; bool disable_messages = false; bool right_click_protect = false; -bool auto_appraise_new_items = false; +bool auto_appraise_new_items = true; bool show_game_timer_always = false; bool hide_statusbar = true; bool hide_playertags = false; @@ -162,6 +162,8 @@ GenericGUIMenu GenericGUI[MAXPLAYERS]; int EnemyHPDamageBarHandler::maxTickLifetime = 120; int EnemyHPDamageBarHandler::maxTickFurnitureLifetime = 60; +int EnemyHPDamageBarHandler::shortDistanceHPBarFadeTicks = TICKS_PER_SECOND / 2; +real_t EnemyHPDamageBarHandler::shortDistanceHPBarFadeDistance = 1.0; std::vector> EnemyHPDamageBarHandler::widthHealthBreakpointsMonsters; std::vector> EnemyHPDamageBarHandler::widthHealthBreakpointsFurniture; @@ -8022,150 +8024,151 @@ EnemyHPDamageBarHandler::EnemyHPDetails* EnemyHPDamageBarHandler::getMostRecentH void EnemyHPDamageBarHandler::displayCurrentHPBar(const int player) { - if ( HPBars.empty() ) - { - return; - } - Uint32 mostRecentTicks = 0; - auto mostRecentEntry = HPBars.end(); - auto highPriorityMostRecentEntry = HPBars.end(); - bool foundHighPriorityEntry = false; - for ( auto it = HPBars.begin(); it != HPBars.end(); ) - { - if ( ticks - (*it).second.enemy_timer >= EnemyHPDamageBarHandler::maxTickLifetime ) - { - it = HPBars.erase(it); // no need to show this bar, delete it - } - else - { - if ( (*it).second.enemy_timer > mostRecentTicks && (*it).second.shouldDisplay ) - { - if ( mostRecentEntry != HPBars.end() ) - { - // previous most recent tick should not display until updated by high priority. - // since we've found a new one to display. - (*mostRecentEntry).second.shouldDisplay = false; - } - if ( !(*it).second.lowPriorityTick ) - { - // this is a normal priority damage update (not burn/poison etc) - // if a newer tick is low priority, then defer to this one. - highPriorityMostRecentEntry = it; - foundHighPriorityEntry = true; - } - mostRecentEntry = it; - mostRecentTicks = (*it).second.enemy_timer; - } - else - { - (*it).second.shouldDisplay = false; - } - ++it; - } - } - if ( mostRecentTicks > 0 ) - { - if ( !foundHighPriorityEntry ) - { - // all low priority, just display the last added. - } - else - { - if ( (mostRecentEntry != highPriorityMostRecentEntry) && foundHighPriorityEntry ) - { - // the most recent was low priority, so defer to the most recent high priority. - mostRecentEntry = highPriorityMostRecentEntry; - } - } - - auto& HPDetails = (*mostRecentEntry).second; - HPDetails.enemy_hp = std::max(0, HPDetails.enemy_hp); - - const int barWidth = 512; - SDL_Rect pos; - pos.w = barWidth; - pos.h = 38; - //pos.y = players[player]->camera_y2() - 224; - if ( players[player]->hotbar.useHotbarFaceMenu ) - { - // anchor to the topmost position, including button glyphs - pos.y = players[player]->hotbar.faceButtonTopYPosition - pos.h - 8; - } - else - { - pos.y = players[player]->hotbar.hotbarBox.y - pos.h - 8; - } - if ( players[player]->isLocalPlayer() && players[player]->camera_width() < yres ) - { - if ( yres < 900 ) - { - pos.w *= 0.5; - } - else if ( yres < 1080 ) - { - pos.w *= 0.8; - } - } - pos.x = players[player]->camera_midx() - (pos.w / 2); - - // bar - drawTooltip(&pos); - - pos.w = pos.w - 6; - pos.x = pos.x + 3; - pos.y = pos.y + 3; - pos.h = pos.h - 6; - drawRect(&pos, SDL_MapRGB(mainsurface->format, 16, 0, 0), 255); - - if ( HPDetails.enemy_oldhp > HPDetails.enemy_hp ) - { - int timeDiff = ticks - HPDetails.enemy_timer; - if ( timeDiff > 30 || HPDetails.enemy_hp == 0 ) - { - // delay 30 ticks before background hp drop animation, or if health 0 start immediately. - // we want to complete animation with x ticks to go - int depletionTicks = (80 - timeDiff); - int healthDiff = HPDetails.enemy_oldhp - HPDetails.enemy_hp; - - // scale duration to FPS - tested @ 144hz - real_t fpsScale = (144.f / std::max(1U, fpsLimit)); - HPDetails.depletionAnimationPercent -= fpsScale * (std::max((healthDiff) / std::max(depletionTicks, 1), 1) / 100.0); - HPDetails.enemy_oldhp = HPDetails.depletionAnimationPercent * HPDetails.enemy_maxhp; // this follows the animation - } - else - { - HPDetails.depletionAnimationPercent = - HPDetails.enemy_oldhp / static_cast(HPDetails.enemy_maxhp); - } - int tmpw = pos.w; - pos.w = pos.w * HPDetails.depletionAnimationPercent; - if ( HPDetails.enemy_bar_color > 0 ) - { - drawRect(&pos, HPDetails.enemy_bar_color, 128); - } - else - { - drawRect(&pos, SDL_MapRGB(mainsurface->format, 128, 0, 0), 128); - } - pos.w = tmpw; - } - if ( HPDetails.enemy_hp > 0 ) - { - int tmpw = pos.w; - pos.w = pos.w * ((double)HPDetails.enemy_hp / HPDetails.enemy_maxhp); - drawRect(&pos, SDL_MapRGB(mainsurface->format, 128, 0, 0), 255); - if ( HPDetails.enemy_bar_color > 0 ) - { - drawRect(&pos, HPDetails.enemy_bar_color, 224); - } - pos.w = tmpw; - } - - // name - int x = players[player]->camera_midx() - longestline(HPDetails.enemy_name.c_str()) * TTF12_WIDTH / 2 + 2; - int y = pos.y + 16 - TTF12_HEIGHT / 2 + 2; - ttfPrintText(ttf12, x, y, HPDetails.enemy_name.c_str()); - } + // deprecated + //if ( HPBars.empty() ) + //{ + // return; + //} + //Uint32 mostRecentTicks = 0; + //auto mostRecentEntry = HPBars.end(); + //auto highPriorityMostRecentEntry = HPBars.end(); + //bool foundHighPriorityEntry = false; + //for ( auto it = HPBars.begin(); it != HPBars.end(); ) + //{ + // if ( ticks - (*it).second.enemy_timer >= EnemyHPDamageBarHandler::maxTickLifetime ) + // { + // it = HPBars.erase(it); // no need to show this bar, delete it + // } + // else + // { + // if ( (*it).second.enemy_timer > mostRecentTicks && (*it).second.shouldDisplay ) + // { + // if ( mostRecentEntry != HPBars.end() ) + // { + // // previous most recent tick should not display until updated by high priority. + // // since we've found a new one to display. + // (*mostRecentEntry).second.shouldDisplay = false; + // } + // if ( !(*it).second.lowPriorityTick ) + // { + // // this is a normal priority damage update (not burn/poison etc) + // // if a newer tick is low priority, then defer to this one. + // highPriorityMostRecentEntry = it; + // foundHighPriorityEntry = true; + // } + // mostRecentEntry = it; + // mostRecentTicks = (*it).second.enemy_timer; + // } + // else + // { + // (*it).second.shouldDisplay = false; + // } + // ++it; + // } + //} + //if ( mostRecentTicks > 0 ) + //{ + // if ( !foundHighPriorityEntry ) + // { + // // all low priority, just display the last added. + // } + // else + // { + // if ( (mostRecentEntry != highPriorityMostRecentEntry) && foundHighPriorityEntry ) + // { + // // the most recent was low priority, so defer to the most recent high priority. + // mostRecentEntry = highPriorityMostRecentEntry; + // } + // } + + // auto& HPDetails = (*mostRecentEntry).second; + // HPDetails.enemy_hp = std::max(0, HPDetails.enemy_hp); + + // const int barWidth = 512; + // SDL_Rect pos; + // pos.w = barWidth; + // pos.h = 38; + // //pos.y = players[player]->camera_y2() - 224; + // if ( players[player]->hotbar.useHotbarFaceMenu ) + // { + // // anchor to the topmost position, including button glyphs + // pos.y = players[player]->hotbar.faceButtonTopYPosition - pos.h - 8; + // } + // else + // { + // pos.y = players[player]->hotbar.hotbarBox.y - pos.h - 8; + // } + // if ( players[player]->isLocalPlayer() && players[player]->camera_width() < yres ) + // { + // if ( yres < 900 ) + // { + // pos.w *= 0.5; + // } + // else if ( yres < 1080 ) + // { + // pos.w *= 0.8; + // } + // } + // pos.x = players[player]->camera_midx() - (pos.w / 2); + + // // bar + // drawTooltip(&pos); + + // pos.w = pos.w - 6; + // pos.x = pos.x + 3; + // pos.y = pos.y + 3; + // pos.h = pos.h - 6; + // drawRect(&pos, SDL_MapRGB(mainsurface->format, 16, 0, 0), 255); + + // if ( HPDetails.enemy_oldhp > HPDetails.enemy_hp ) + // { + // int timeDiff = ticks - HPDetails.enemy_timer; + // if ( timeDiff > 30 || HPDetails.enemy_hp == 0 ) + // { + // // delay 30 ticks before background hp drop animation, or if health 0 start immediately. + // // we want to complete animation with x ticks to go + // int depletionTicks = (80 - timeDiff); + // int healthDiff = HPDetails.enemy_oldhp - HPDetails.enemy_hp; + + // // scale duration to FPS - tested @ 144hz + // real_t fpsScale = (144.f / std::max(1U, fpsLimit)); + // HPDetails.depletionAnimationPercent -= fpsScale * (std::max((healthDiff) / std::max(depletionTicks, 1), 1) / 100.0); + // HPDetails.enemy_oldhp = HPDetails.depletionAnimationPercent * HPDetails.enemy_maxhp; // this follows the animation + // } + // else + // { + // HPDetails.depletionAnimationPercent = + // HPDetails.enemy_oldhp / static_cast(HPDetails.enemy_maxhp); + // } + // int tmpw = pos.w; + // pos.w = pos.w * HPDetails.depletionAnimationPercent; + // if ( HPDetails.enemy_bar_color > 0 ) + // { + // drawRect(&pos, HPDetails.enemy_bar_color, 128); + // } + // else + // { + // drawRect(&pos, SDL_MapRGB(mainsurface->format, 128, 0, 0), 128); + // } + // pos.w = tmpw; + // } + // if ( HPDetails.enemy_hp > 0 ) + // { + // int tmpw = pos.w; + // pos.w = pos.w * ((double)HPDetails.enemy_hp / HPDetails.enemy_maxhp); + // drawRect(&pos, SDL_MapRGB(mainsurface->format, 128, 0, 0), 255); + // if ( HPDetails.enemy_bar_color > 0 ) + // { + // drawRect(&pos, HPDetails.enemy_bar_color, 224); + // } + // pos.w = tmpw; + // } + + // // name + // int x = players[player]->camera_midx() - longestline(HPDetails.enemy_name.c_str()) * TTF12_WIDTH / 2 + 2; + // int y = pos.y + 16 - TTF12_HEIGHT / 2 + 2; + // ttfPrintText(ttf12, x, y, HPDetails.enemy_name.c_str()); + //} } void EnemyHPDamageBarHandler::EnemyHPDetails::updateWorldCoordinates() @@ -8277,53 +8280,4 @@ void EnemyHPDamageBarHandler::addEnemyToList(Sint32 HP, Sint32 maxHP, Sint32 old } } } -} - -SDL_Rect getRectForSkillIcon(const int skill) -{ - SDL_Rect defaultRect{ 0, 0, 0, 0 }; - - int glyphHeight = 32; - int glyphWidth = 32; - const int glyphSpacing = 32; - - switch ( skill ) - { - case PRO_LOCKPICKING: - return SDL_Rect{ 1 * glyphSpacing, 3 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_STEALTH: - return SDL_Rect{ 1 * glyphSpacing, 2 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_TRADING: - return SDL_Rect{ 2 * glyphSpacing, 3 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_APPRAISAL: - return SDL_Rect{ 1 * glyphSpacing, 0 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_SWIMMING: - return SDL_Rect{ 2 * glyphSpacing, 2 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_LEADERSHIP: - return SDL_Rect{ 1 * glyphSpacing, 1 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_SPELLCASTING: - return SDL_Rect{ 0 * glyphSpacing, 1 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_MAGIC: - return SDL_Rect{ 3 * glyphSpacing, 1 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_RANGED: - return SDL_Rect{ 3 * glyphSpacing, 2 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_SWORD: - return SDL_Rect{ 0 * glyphSpacing, 3 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_MACE: - return SDL_Rect{ 2 * glyphSpacing, 1 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_AXE: - return SDL_Rect{ 2 * glyphSpacing, 0 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_POLEARM: - return SDL_Rect{ 0 * glyphSpacing, 2 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_UNARMED: - return SDL_Rect{ 3 * glyphSpacing, 3 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_SHIELD: - return SDL_Rect{ 3 * glyphSpacing, 0 * glyphSpacing, glyphWidth, glyphHeight }; - case PRO_ALCHEMY: - return SDL_Rect{ 0 * glyphSpacing, 0 * glyphSpacing, glyphWidth, glyphHeight }; - default: - break; - } - - return defaultRect; -} +} \ No newline at end of file diff --git a/src/interface/interface.hpp b/src/interface/interface.hpp index ab1c01c09..0c503f572 100644 --- a/src/interface/interface.hpp +++ b/src/interface/interface.hpp @@ -39,6 +39,8 @@ class EnemyHPDamageBarHandler public: static int maxTickLifetime; static int maxTickFurnitureLifetime; + static int shortDistanceHPBarFadeTicks; + static real_t shortDistanceHPBarFadeDistance; static std::vector>widthHealthBreakpointsMonsters; static std::vector>widthHealthBreakpointsFurniture; enum HPBarType { @@ -803,7 +805,6 @@ class FollowerRadialMenu }; extern FollowerRadialMenu FollowerMenu[MAXPLAYERS]; -SDL_Rect getRectForSkillIcon(const int skill); std::string getItemSpritePath(const int player, Item& item); enum ItemContextMenuPrompts { diff --git a/src/interface/playerinventory.cpp b/src/interface/playerinventory.cpp index 2fb08842e..e61f97ad2 100644 --- a/src/interface/playerinventory.cpp +++ b/src/interface/playerinventory.cpp @@ -3986,6 +3986,12 @@ void Player::HUD_t::updateFrameTooltip(Item* item, const int x, const int y, int tooltipDisplayedSettings.displayingShortFormTooltip = false; } + bool isItemFromInventory = false; + if ( item->node && item->node->list == &stats[player]->inventory ) + { + isItemFromInventory = true; + } + if ( ItemTooltips.itemDebug ) { if ( keystatus[SDL_SCANCODE_KP_PLUS] ) @@ -4039,9 +4045,11 @@ void Player::HUD_t::updateFrameTooltip(Item* item, const int x, const int y, int } } + bool expandBindingPressed = false; if ( !command && Input::inputs[player].consumeBinaryToggle("Expand Inventory Tooltip") ) { - if ( !players[player]->shootmode ) + expandBindingPressed = true; + if ( !players[player]->shootmode && item->identified ) { tooltipDisplayedSettings.expanded = !tooltipDisplayedSettings.expanded; } @@ -5372,7 +5380,7 @@ void Player::HUD_t::updateFrameTooltip(Item* item, const int x, const int y, int framePromptPos.y = frameValuesPos.y + frameValuesPos.h; framePromptPos.h = imgBottomBackground->pos.h; - if ( !item->identified || doShortTooltip ) + if ( (!item->identified && (!isItemFromInventory || inputs.getVirtualMouse(player)->draw_cursor)) || doShortTooltip ) { imgBottomBackground->path = "images/ui/Inventory/tooltips/Hover_B00_NoPrompt.png"; imgBottomBackgroundLeft->path = "images/ui/Inventory/tooltips/Hover_BL01_NoPrompt.png"; @@ -5415,13 +5423,33 @@ void Player::HUD_t::updateFrameTooltip(Item* item, const int x, const int y, int SDL_Rect framePromptPos = framePrompt->getSize(); framePromptPos.y = frameValuesPos.y + frameValuesPos.h; framePrompt->setSize(framePromptPos); - if ( tooltipDisplayedSettings.expanded ) + + bool doAppraisalPrompt = !item->identified && isItemFromInventory; + if ( doAppraisalPrompt ) { - txtPrompt->setText(language[4086]); // show item details + txtPrompt->setText(language[4102]); + } + else if ( !tooltipDisplayedSettings.expanded ) + { + if ( itemCategory(item) == SPELL_CAT ) + { + txtPrompt->setText(language[4103]); // show spell details + } + else + { + txtPrompt->setText(language[4086]); // show item details + } } else { - txtPrompt->setText(language[4087]); // view item details + if ( itemCategory(item) == SPELL_CAT ) + { + txtPrompt->setText(language[4104]); // hide spell details + } + else + { + txtPrompt->setText(language[4087]); // hide item details + } } // get left anchor for tooltip - if we want moving x tooltips, otherwise currently anchor to right of inventory panel @@ -5433,6 +5461,65 @@ void Player::HUD_t::updateFrameTooltip(Item* item, const int x, const int y, int newPos.x -= newPos.w; } frameMain->setSize(newPos); + + // prompt for expanding tooltip position + auto promptImg = frameMain->findImage("inventory mouse tooltip prompt img"); + promptImg->disabled = true; + if ( !players[player]->shootmode + && !txtPrompt->isDisabled() + && (!doAppraisalPrompt || (doAppraisalPrompt && stats[player]->HP > 0)) ) + { + auto& binding = Input::inputs[player].input("Expand Inventory Tooltip"); + bool pressedGlyph = false; + if ( binding.isBindingUsingGamepad() + && (binding.padButton == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK + || binding.padButton == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK) ) + { + pressedGlyph = true; + } + promptImg->path = Input::inputs[player].getGlyphPathForBinding(binding, pressedGlyph); + if ( auto imgGet = Image::get(promptImg->path.c_str()) ) + { + unsigned int largestTextWidth = 0; + std::vector languageIndexes; + if ( doAppraisalPrompt ) + { + languageIndexes.push_back(4102); + } + else if ( itemCategory(item) == SPELL_CAT ) + { + languageIndexes.push_back(4103); + languageIndexes.push_back(4104); + } + else + { + languageIndexes.push_back(4086); + languageIndexes.push_back(4087); + } + + for ( auto index : languageIndexes ) + { + if ( auto textGet = Text::get(language[index], txtPrompt->getFont(), + txtPrompt->getTextColor(), txtPrompt->getOutlineColor()) ) + { + largestTextWidth = std::max(textGet->getWidth(), largestTextWidth); + } + } + promptImg->disabled = false; + promptImg->pos.w = imgGet->getWidth(); + promptImg->pos.h = imgGet->getHeight(); + promptImg->pos.x = framePromptPos.x + framePromptPos.w - 4 - largestTextWidth - promptImg->pos.w; + promptImg->pos.y = framePromptPos.y; + if ( promptImg->pos.y + promptImg->pos.h > frameMain->getSize().h ) + { + promptImg->pos.y -= (promptImg->pos.y + promptImg->pos.h) - frameMain->getSize().h; + } + } + if ( doAppraisalPrompt && expandBindingPressed ) + { + players[player]->inventoryUI.activateItemContextMenuOption(item, ItemContextMenuPrompts::PROMPT_APPRAISE); + } + } } // position the background elements. diff --git a/src/magic/actmagic.cpp b/src/magic/actmagic.cpp index 1aa4a7f3d..5c808fac3 100644 --- a/src/magic/actmagic.cpp +++ b/src/magic/actmagic.cpp @@ -1195,37 +1195,34 @@ void actMagicMissile(Entity* my) //TODO: Verify this function. damage += (spellbookDamageBonus * damage); damage /= (1 + (int)resistance); hit.entity->furnitureHealth -= damage; - if ( hit.entity->furnitureHealth < 0 ) + if ( parent ) { - if ( parent ) + if ( parent->behavior == &actPlayer ) { - if ( parent->behavior == &actPlayer ) + switch ( hit.entity->furnitureType ) { - switch ( hit.entity->furnitureType ) - { - case FURNITURE_CHAIR: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[388]); - updateEnemyBar(parent, hit.entity, language[677], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_TABLE: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[389]); - updateEnemyBar(parent, hit.entity, language[676], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_BED: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2505]); - updateEnemyBar(parent, hit.entity, language[2505], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_BUNKBED: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2506]); - updateEnemyBar(parent, hit.entity, language[2506], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_PODIUM: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2507]); - updateEnemyBar(parent, hit.entity, language[2507], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - default: - break; - } + case FURNITURE_CHAIR: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[388]); + updateEnemyBar(parent, hit.entity, language[677], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_TABLE: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[389]); + updateEnemyBar(parent, hit.entity, language[676], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_BED: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2505]); + updateEnemyBar(parent, hit.entity, language[2505], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_BUNKBED: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2506]); + updateEnemyBar(parent, hit.entity, language[2506], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_PODIUM: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2507]); + updateEnemyBar(parent, hit.entity, language[2507], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + default: + break; } } } @@ -1338,37 +1335,34 @@ void actMagicMissile(Entity* my) //TODO: Verify this function. damage += (spellbookDamageBonus * damage); damage /= (1 + (int)resistance); hit.entity->furnitureHealth -= damage; - if ( hit.entity->furnitureHealth < 0 ) + if ( parent ) { - if ( parent ) + if ( parent->behavior == &actPlayer ) { - if ( parent->behavior == &actPlayer ) + switch ( hit.entity->furnitureType ) { - switch ( hit.entity->furnitureType ) - { - case FURNITURE_CHAIR: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[388]); - updateEnemyBar(parent, hit.entity, language[677], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_TABLE: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[389]); - updateEnemyBar(parent, hit.entity, language[676], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_BED: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2505]); - updateEnemyBar(parent, hit.entity, language[2505], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_BUNKBED: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2506]); - updateEnemyBar(parent, hit.entity, language[2506], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_PODIUM: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2507]); - updateEnemyBar(parent, hit.entity, language[2507], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - default: - break; - } + case FURNITURE_CHAIR: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[388]); + updateEnemyBar(parent, hit.entity, language[677], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_TABLE: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[389]); + updateEnemyBar(parent, hit.entity, language[676], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_BED: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2505]); + updateEnemyBar(parent, hit.entity, language[2505], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_BUNKBED: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2506]); + updateEnemyBar(parent, hit.entity, language[2506], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_PODIUM: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2507]); + updateEnemyBar(parent, hit.entity, language[2507], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + default: + break; } } } @@ -1579,37 +1573,34 @@ void actMagicMissile(Entity* my) //TODO: Verify this function. damage += (spellbookDamageBonus * damage); damage /= (1 + (int)resistance); hit.entity->furnitureHealth -= damage; - if ( hit.entity->furnitureHealth < 0 ) + if ( parent ) { - if ( parent ) + if ( parent->behavior == &actPlayer ) { - if ( parent->behavior == &actPlayer ) + switch ( hit.entity->furnitureType ) { - switch ( hit.entity->furnitureType ) - { - case FURNITURE_CHAIR: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[388]); - updateEnemyBar(parent, hit.entity, language[677], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_TABLE: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[389]); - updateEnemyBar(parent, hit.entity, language[676], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_BED: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2505]); - updateEnemyBar(parent, hit.entity, language[2505], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_BUNKBED: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2506]); - updateEnemyBar(parent, hit.entity, language[2506], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_PODIUM: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2507]); - updateEnemyBar(parent, hit.entity, language[2507], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - default: - break; - } + case FURNITURE_CHAIR: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[388]); + updateEnemyBar(parent, hit.entity, language[677], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_TABLE: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[389]); + updateEnemyBar(parent, hit.entity, language[676], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_BED: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2505]); + updateEnemyBar(parent, hit.entity, language[2505], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_BUNKBED: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2506]); + updateEnemyBar(parent, hit.entity, language[2506], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_PODIUM: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2507]); + updateEnemyBar(parent, hit.entity, language[2507], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + default: + break; } } } @@ -2025,37 +2016,34 @@ void actMagicMissile(Entity* my) //TODO: Verify this function. damage += (spellbookDamageBonus * damage); damage /= (1 + (int)resistance); hit.entity->furnitureHealth -= damage; - if ( hit.entity->furnitureHealth < 0 ) + if ( parent ) { - if ( parent ) + if ( parent->behavior == &actPlayer ) { - if ( parent->behavior == &actPlayer ) + switch ( hit.entity->furnitureType ) { - switch ( hit.entity->furnitureType ) - { - case FURNITURE_CHAIR: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[388]); - updateEnemyBar(parent, hit.entity, language[677], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_TABLE: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[389]); - updateEnemyBar(parent, hit.entity, language[676], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_BED: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2505]); - updateEnemyBar(parent, hit.entity, language[2505], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_BUNKBED: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2506]); - updateEnemyBar(parent, hit.entity, language[2506], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - case FURNITURE_PODIUM: - messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2507]); - updateEnemyBar(parent, hit.entity, language[2507], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); - break; - default: - break; - } + case FURNITURE_CHAIR: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[388]); + updateEnemyBar(parent, hit.entity, language[677], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_TABLE: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[389]); + updateEnemyBar(parent, hit.entity, language[676], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_BED: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2505]); + updateEnemyBar(parent, hit.entity, language[2505], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_BUNKBED: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2506]); + updateEnemyBar(parent, hit.entity, language[2506], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + case FURNITURE_PODIUM: + messagePlayer(parent->skill[2], MESSAGE_COMBAT, language[2508], language[2507]); + updateEnemyBar(parent, hit.entity, language[2507], hit.entity->furnitureHealth, hit.entity->furnitureMaxHealth); + break; + default: + break; } } } diff --git a/src/player.cpp b/src/player.cpp index cdb39b5d7..34daff8d5 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -3160,7 +3160,8 @@ void Player::WorldUI_t::handleTooltips() continue; } parent = uidToEntity(tooltip->parent); - if ( parent && parent->flags[INVISIBLE] ) + if ( parent && parent->flags[INVISIBLE] + && !(parent->behavior == &actMonster && parent->getMonsterTypeFromSprite() == DUMMYBOT) ) { continue; } diff --git a/src/player.hpp b/src/player.hpp index 4a37bfc52..59a89a1fd 100644 --- a/src/player.hpp +++ b/src/player.hpp @@ -1653,7 +1653,7 @@ class Player bool useHotbarRadialMenu = false; bool useHotbarFaceMenu = true; bool faceMenuInvertLayout = false; - bool faceMenuQuickCastEnabled = true; + bool faceMenuQuickCastEnabled = false; bool faceMenuQuickCast = true; bool faceMenuAlternateLayout = false; enum FaceMenuGroup : int diff --git a/src/ui/GameUI.cpp b/src/ui/GameUI.cpp index f7a5196bd..c3831907f 100644 --- a/src/ui/GameUI.cpp +++ b/src/ui/GameUI.cpp @@ -9798,7 +9798,10 @@ void createInventoryTooltipFrame(const int player) tooltipTextField->setHJustify(Field::justify_t::RIGHT); tooltipTextField->setVJustify(Field::justify_t::TOP); tooltipTextField->setColor(SDL_MapRGBA(mainsurface->format, 148, 82, 3, 255)); + } + auto tooltipPromptImg = tooltipFrame->addImage(SDL_Rect{ 0, 0, 0, 0 }, 0xFFFFFFFF, "", "inventory mouse tooltip prompt img"); + tooltipPromptImg->disabled = true; snprintf(name, sizeof(name), "player interact %d", player); if ( auto interactFrame = gui->addFrame(name) ) @@ -10866,6 +10869,21 @@ void loadHUDSettingsJSON() { EnemyHPDamageBarHandler::maxTickFurnitureLifetime = d["enemy_hp_bars"]["furniture_bar_lifetime_ticks"].GetInt(); } + if ( d["enemy_hp_bars"].HasMember("quick_fade_delay_ticks") ) + { + EnemyHPDamageBarHandler::shortDistanceHPBarFadeTicks = d["enemy_hp_bars"]["quick_fade_delay_ticks"].GetInt(); + } + if ( d["enemy_hp_bars"].HasMember("quick_fade_distance_from_player_multiplier") ) + { + if ( d["enemy_hp_bars"]["quick_fade_distance_from_player_multiplier"].IsDouble() ) + { + EnemyHPDamageBarHandler::shortDistanceHPBarFadeDistance = d["enemy_hp_bars"]["quick_fade_distance_from_player_multiplier"].GetDouble(); + } + else + { + EnemyHPDamageBarHandler::shortDistanceHPBarFadeDistance = d["enemy_hp_bars"]["quick_fade_distance_from_player_multiplier"].GetInt(); + } + } } if ( d.HasMember("colors") ) { @@ -11570,7 +11588,7 @@ void createPlayerInventory(const int player) for ( int x = 0; x < players[player]->inventoryUI.getSizeX(); ++x ) { currentSlotPos.x = baseSlotOffsetX + (x * inventorySlotSize); - for ( int y = 0; y < players[player]->inventoryUI.getSizeY(); ++y ) + for ( int y = 0; y < players[player]->inventoryUI.DEFAULT_INVENTORY_SIZEY; ++y ) { currentSlotPos.y = baseSlotOffsetY + (y * inventorySlotSize); @@ -11603,10 +11621,10 @@ void createPlayerInventory(const int player) if ( x == 0 ) { currentSlotPos.x -= 4; } // backpack has unique first/last column entries if ( x == players[player]->inventoryUI.getSizeX() - 1 ) { currentSlotPos.x += 4; } - for ( int y = players[player]->inventoryUI.getSizeY(); - y < players[player]->inventoryUI.getSizeY() + players[player]->inventoryUI.getPlayerBackpackBonusSizeY(); ++y ) + for ( int y = players[player]->inventoryUI.DEFAULT_INVENTORY_SIZEY; + y < players[player]->inventoryUI.DEFAULT_INVENTORY_SIZEY + players[player]->inventoryUI.getPlayerBackpackBonusSizeY(); ++y ) { - currentSlotPos.y = backpackBaseSlotOffsetY + ((y - players[player]->inventoryUI.getSizeY()) * inventorySlotSize); + currentSlotPos.y = backpackBaseSlotOffsetY + ((y - players[player]->inventoryUI.DEFAULT_INVENTORY_SIZEY) * inventorySlotSize); char slotname[32] = ""; snprintf(slotname, sizeof(slotname), "slot %d %d", x, y); @@ -13956,17 +13974,16 @@ void Player::HUD_t::updateEnemyBar2(Frame* whichFrame, void* enemyHPDetails) } bool bIsMostRecentHPBar = enemyHPDamageBarHandler[player.playernum].getMostRecentHPBar() == enemyDetails; - if ( bIsMostRecentHPBar && !enemyDetails->hasDistanceCheck ) - { - //enemyDetails->hasDistanceCheck = true; - auto& camera = cameras[player.playernum]; - double playerdist = sqrt(pow(camera.x * 16.0 - enemyDetails->worldX, 2) + pow(camera.y * 16.0 - enemyDetails->worldY, 2)); - if ( playerdist >= 3 * 16.0 ) - { - //enemyDetails->displayOnHUD = true; - } - } - + //if ( bIsMostRecentHPBar && !enemyDetails->hasDistanceCheck ) + //{ + // //enemyDetails->hasDistanceCheck = true; + // auto& camera = cameras[player.playernum]; + // double playerdist = sqrt(pow(camera.x * 16.0 - enemyDetails->worldX, 2) + pow(camera.y * 16.0 - enemyDetails->worldY, 2)); + // if ( playerdist >= 3 * 16.0 ) + // { + // //enemyDetails->displayOnHUD = true; + // } + //} SDL_Rect pos = whichFrame->getSize(); bool doFadeout = false; @@ -13976,6 +13993,19 @@ void Player::HUD_t::updateEnemyBar2(Frame* whichFrame, void* enemyHPDetails) doAnimation = false; } + if ( doAnimation && !enemyDetails->displayOnHUD && !enemyDetails->expired && enemyDetails->animator.setpoint <= 0 ) + { + if ( ticks - enemyDetails->enemy_timer >= EnemyHPDamageBarHandler::shortDistanceHPBarFadeTicks ) + { + auto& camera = cameras[player.playernum]; + double playerdist = sqrt(pow(camera.x * 16.0 - enemyDetails->worldX, 2) + pow(camera.y * 16.0 - enemyDetails->worldY, 2)); + if ( playerdist <= EnemyHPDamageBarHandler::shortDistanceHPBarFadeDistance * 16.0 ) + { + enemyDetails->expired = true; + } + } + } + if ( enemyDetails->expired == true ) { doFadeout = true; From f4590b6f59734b56505ee7f1f244811bc1d7cbea Mon Sep 17 00:00:00 2001 From: SheridanR Date: Fri, 4 Mar 2022 18:17:51 -0800 Subject: [PATCH 3/3] Fix minor compilation issue --- CMakeLists.txt | 8 ++++---- src/interface/playerinventory.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 416065e7e..2d44cc345 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,11 +159,11 @@ if( NOT WIN32 ) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${OPTIMIZATION_LEVEL} -ffast-math -funroll-loops -fstrict-aliasing -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g -fuse-ld=gold -fuse-linker-plugin -fsingle-precision-constant") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OPTIMIZATION_LEVEL} -ffast-math -funroll-loops -fstrict-aliasing -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g -fuse-ld=gold -fuse-linker-plugin -fsingle-precision-constant") else() - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pedantic -Wno-multichar -pg -ffast-math -funroll-loops -fstrict-aliasing") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wpedantic -Wno-multichar -pg -ffast-math -funroll-loops -fstrict-aliasing") #set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover -Wreturn-type -Werror=return-type") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pedantic -Wno-multichar -pg") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -pedantic -Wno-multichar ${OPTIMIZATION_LEVEL} -ffast-math -funroll-loops -fstrict-aliasing") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic -Wno-multichar ${OPTIMIZATION_LEVEL}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wpedantic -Wno-multichar -pg") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wpedantic -Wno-multichar ${OPTIMIZATION_LEVEL} -ffast-math -funroll-loops -fstrict-aliasing") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wpedantic -Wno-multichar ${OPTIMIZATION_LEVEL}") endif() if (APPLE) set (Apple 1) diff --git a/src/interface/playerinventory.cpp b/src/interface/playerinventory.cpp index e61f97ad2..b0b6896ec 100644 --- a/src/interface/playerinventory.cpp +++ b/src/interface/playerinventory.cpp @@ -5469,7 +5469,7 @@ void Player::HUD_t::updateFrameTooltip(Item* item, const int x, const int y, int && !txtPrompt->isDisabled() && (!doAppraisalPrompt || (doAppraisalPrompt && stats[player]->HP > 0)) ) { - auto& binding = Input::inputs[player].input("Expand Inventory Tooltip"); + auto binding = Input::inputs[player].input("Expand Inventory Tooltip"); bool pressedGlyph = false; if ( binding.isBindingUsingGamepad() && (binding.padButton == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK