Browse Source

alt highlighting (#2060)

pull/2065/head
qndel 5 years ago committed by GitHub
parent
commit
b1d74d2791
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CMakeLists.txt
  2. 4
      Source/cursor.cpp
  3. 8
      Source/diablo.cpp
  4. 25
      Source/engine.cpp
  5. 2
      Source/engine/render/cel_render.cpp
  6. 2
      Source/items.cpp
  7. 1
      Source/items.h
  8. 157
      Source/qol/itemlabels.cpp
  9. 17
      Source/qol/itemlabels.h
  10. 6
      Source/scrollrt.cpp

1
CMakeLists.txt

@ -389,6 +389,7 @@ set(libdevilutionx_SRCS
Source/qol/common.cpp
Source/qol/monhealthbar.cpp
Source/qol/xpbar.cpp
Source/qol/itemlabels.cpp
Source/utils/console.cpp
Source/utils/display.cpp
Source/utils/file_util.cpp

4
Source/cursor.cpp

@ -16,6 +16,7 @@
#include "track.h"
#include "trigs.h"
#include "utils/language.h"
#include "qol/itemlabels.h"
namespace devilution {
namespace {
@ -249,6 +250,9 @@ void CheckCursMove()
int8_t bv;
bool flipflag, flipx, flipy;
if (IsItemLabelHighlighted())
return;
sx = MouseX;
sy = MouseY;

8
Source/diablo.cpp

@ -43,6 +43,7 @@
#include "pfile.h"
#include "plrmsg.h"
#include "qol/common.h"
#include "qol/itemlabels.h"
#include "restrict.h"
#include "setmaps.h"
#include "stores.h"
@ -1070,6 +1071,10 @@ static void ReleaseKey(int vkey)
{
if (vkey == DVL_VK_SNAPSHOT)
CaptureScreen();
if (vkey == DVL_VK_MENU || vkey == DVL_VK_LMENU || vkey == DVL_VK_RMENU)
AltPressed(false);
if (vkey == DVL_VK_CONTROL || vkey == DVL_VK_LCONTROL || vkey == DVL_VK_RCONTROL)
ToggleItemLabelHighlight();
}
static void ClosePanels()
@ -1146,6 +1151,9 @@ static void PressKey(int vkey)
return;
}
if (vkey == DVL_VK_MENU || vkey == DVL_VK_LMENU || vkey == DVL_VK_RMENU)
AltPressed(true);
if (deathflag) {
if (sgnTimeoutCurs != CURSOR_NONE) {
return;

25
Source/engine.cpp

@ -55,7 +55,7 @@ void DrawHorizontalLine(const CelOutputBuffer &out, Point from, int width, std::
from.x = 0;
}
if (from.x + width > out.w())
width = (from.x + width) - out.w();
width = out.w() - from.x;
return UnsafeDrawHorizontalLine(out, from, width, colorIndex);
}
@ -116,6 +116,29 @@ static void DrawHalfTransparentStippledRectTo(const CelOutputBuffer &out, int sx
void DrawHalfTransparentRectTo(const CelOutputBuffer &out, int sx, int sy, int width, int height)
{
if (sx + width < 0)
return;
if (sy + height < 0)
return;
if (sx >= out.w())
return;
if (sy >= out.h())
return;
if (sx < 0) {
width += sx;
sx = 0;
} else if (sx + width >= out.w()) {
width = out.w() - sx;
}
if (sy < 0) {
height += sy;
sy = 0;
} else if (sy + height >= out.h()) {
height = out.h() - sy;
}
if (sgOptions.Graphics.bBlendedTransparancy) {
DrawHalfTransparentBlendedRectTo(out, sx, sy, width, height);
} else {

2
Source/engine/render/cel_render.cpp

@ -713,7 +713,7 @@ void CelBlitOutlineTo(const CelOutputBuffer &out, uint8_t col, int sx, int sy, c
std::pair<int, int> MeasureSolidHorizontalBounds(const CelSprite &cel, int frame)
{
int nDataSize;
auto src = reinterpret_cast<const uint8_t *>(CelGetFrame(cel.Data(), frame, &nDataSize));
const byte *src = CelGetFrameClipped(cel.Data(), frame, &nDataSize);
auto end = &src[nDataSize];
const int celWidth = cel.Width(frame);

2
Source/items.cpp

@ -23,8 +23,6 @@
#include "utils/language.h"
#include "utils/math.h"
#define ITEMTYPES 43
namespace devilution {
namespace {
std::optional<CelSprite> itemanims[ITEMTYPES];

1
Source/items.h

@ -15,6 +15,7 @@
namespace devilution {
#define MAXITEMS 127
#define ITEMTYPES 43
#define GOLD_SMALL_LIMIT 1000
#define GOLD_MEDIUM_LIMIT 2500

157
Source/qol/itemlabels.cpp

@ -0,0 +1,157 @@
#include <vector>
#include <string>
#include <unordered_set>
#include "inv.h"
#include "gmenu.h"
#include "cursor.h"
#include "common.h"
#include "control.h"
#include "itemlabels.h"
#include "utils/language.h"
#include "engine/render/cel_render.hpp"
namespace devilution {
namespace {
struct itemLabel {
int id, width;
Point pos;
std::string text;
};
std::vector<itemLabel> labelQueue;
bool altPressed = false;
bool isLabelHighlighted = false;
std::array<std::optional<int>, ITEMTYPES> labelCenterOffsets;
bool invertHighlightToggle = false;
} // namespace
void ToggleItemLabelHighlight()
{
invertHighlightToggle = !invertHighlightToggle;
}
void AltPressed(bool pressed)
{
altPressed = pressed;
}
bool IsItemLabelHighlighted()
{
return isLabelHighlighted;
}
bool IsHighlightingLabelsEnabled()
{
return altPressed != invertHighlightToggle;
}
void AddItemToLabelQueue(int id, int x, int y)
{
if (!IsHighlightingLabelsEnabled())
return;
ItemStruct *it = &items[id];
const char *textOnGround;
if (it->_itype == ITYPE_GOLD) {
std::sprintf(tempstr, _("%i gold"), it->_ivalue);
textOnGround = tempstr;
} else {
textOnGround = it->_iIdentified ? it->_iIName : it->_iName;
}
int nameWidth = GetLineWidth(textOnGround);
int index = ItemCAnimTbl[it->_iCurs];
if (!labelCenterOffsets[index]) {
std::pair<int, int> itemBounds = MeasureSolidHorizontalBounds(*it->_iAnimData, it->_iAnimFrame);
labelCenterOffsets[index].emplace((itemBounds.first + itemBounds.second) / 2);
}
x += *labelCenterOffsets[index];
y -= TILE_HEIGHT;
if (!zoomflag) {
x *= 2;
y *= 2;
}
x -= nameWidth / 2;
labelQueue.push_back(itemLabel { id, nameWidth, { x, y }, textOnGround });
}
bool IsMouseOverGameArea()
{
if ((invflag || sbookflag) && MouseX > RIGHT_PANEL && MouseY <= SPANEL_HEIGHT)
return false;
if ((chrflag || questlog) && MouseX < SPANEL_WIDTH && MouseY <= SPANEL_HEIGHT)
return false;
if (MouseY >= PANEL_TOP && MouseX >= PANEL_LEFT && MouseX <= PANEL_LEFT + PANEL_WIDTH)
return false;
return true;
}
void FillRect(const CelOutputBuffer &out, int x, int y, int width, int height, Uint8 col)
{
for (int j = 0; j < height; j++) {
DrawHorizontalLine(out, { x, y + j }, width, col);
}
}
void DrawItemNameLabels(const CelOutputBuffer &out)
{
isLabelHighlighted = false;
const int borderX = 5;
const int borderY = 2;
const int height = 13;
for (unsigned int i = 0; i < labelQueue.size(); ++i) {
std::unordered_set<int> backtrace;
bool canShow;
do {
canShow = true;
for (unsigned int j = 0; j < i; ++j) {
itemLabel &a = labelQueue[i], &b = labelQueue[j];
if (abs(b.pos.y - a.pos.y) < height + borderY) {
int newpos = b.pos.x;
if (b.pos.x >= a.pos.x && b.pos.x - a.pos.x < a.width + borderX) {
newpos -= a.width + borderX;
if (backtrace.find(newpos) != backtrace.end())
newpos = b.pos.x + b.width + borderX;
} else if (b.pos.x < a.pos.x && a.pos.x - b.pos.x < b.width + borderX) {
newpos += b.width + borderX;
if (backtrace.find(newpos) != backtrace.end())
newpos = b.pos.x - a.width - borderX;
} else
continue;
canShow = false;
a.pos.x = newpos;
backtrace.insert(newpos);
}
}
} while (!canShow);
}
for (const itemLabel &label : labelQueue) {
ItemStruct &itm = items[label.id];
if (MouseX >= label.pos.x && MouseX <= label.pos.x + label.width && MouseY >= label.pos.y - height && MouseY <= label.pos.y) {
if (!gmenu_is_active() && PauseMode == 0 && !deathflag && IsMouseOverGameArea()) {
isLabelHighlighted = true;
cursmx = itm.position.x;
cursmy = itm.position.y;
pcursitem = label.id;
}
}
if (pcursitem == label.id)
FillRect(out, label.pos.x, label.pos.y - height, label.width + 1, height, PAL8_BLUE + 6);
else
DrawHalfTransparentRectTo(out, label.pos.x, label.pos.y - height, label.width, height);
DrawString(out, label.text.c_str(), { label.pos.x, label.pos.y, label.width, height }, itm.getTextColor());
}
labelQueue.clear();
}
} // namespace devilution

17
Source/qol/itemlabels.h

@ -0,0 +1,17 @@
/**
* @file itemlabels.h
*
* Adds item labels QoL feature
*/
#pragma once
namespace devilution {
void ToggleItemLabelHighlight();
void AltPressed(bool pressed);
bool IsItemLabelHighlighted();
bool IsHighlightingLabelsEnabled();
void AddItemToLabelQueue(int id, int x, int y);
void DrawItemNameLabels(const CelOutputBuffer &out);
} // namespace devilution

6
Source/scrollrt.cpp

@ -25,6 +25,7 @@
#include "plrmsg.h"
#include "qol/monhealthbar.h"
#include "qol/xpbar.h"
#include "qol/itemlabels.h"
#include "stores.h"
#include "towners.h"
#include "utils/log.hpp"
@ -636,6 +637,8 @@ static void DrawItem(const CelOutputBuffer &out, int x, int y, int sx, int sy, b
CelBlitOutlineTo(out, GetOutlineColor(*pItem, false), px, sy, *cel, nCel);
}
CelClippedDrawLightTo(out, px, sy, *cel, nCel);
if (pItem->_iAnimFrame == pItem->_iAnimLen)
AddItemToLabelQueue(bItem - 1, px, sy);
}
/**
@ -1247,6 +1250,7 @@ void DrawView(const CelOutputBuffer &out, int StartX, int StartY)
DrawAutomap(out.subregionY(0, gnViewportHeight));
}
DrawMonsterHealthBar(out);
DrawItemNameLabels(out);
if (stextflag != STORE_NONE && !qtextflag)
DrawSText(out);
@ -1544,7 +1548,7 @@ void DrawAndBlit()
bool ddsdesc = false;
bool ctrlPan = false;
if (gnScreenWidth > PANEL_WIDTH || force_redraw == 255) {
if (gnScreenWidth > PANEL_WIDTH || force_redraw == 255 || IsHighlightingLabelsEnabled()) {
drawhpflag = true;
drawmanaflag = true;
drawbtnflag = true;

Loading…
Cancel
Save