Qt paper doll's depiction of two-handed weapon

When wielding a two-handed weapon, Qt's paper doll shows uwep
in the shield slot as well as in the weapon slot to reflect
that it's occupying both hands.  Make the shield slot's copy
be a mirror image of the weapon's tile so that it looks less
like wielding two weapons.
This commit is contained in:
PatR
2020-11-08 16:38:01 -08:00
parent ea0ef81ecd
commit 6b37efa9e1
4 changed files with 67 additions and 27 deletions

View File

@@ -81,23 +81,31 @@ NetHackQtGlyphs::NetHackQtGlyphs()
setSize(tilefile_tile_W, tilefile_tile_H);
}
void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int x, int y)
void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int x, int y,
bool reversed)
{
int tile = glyph2tile[glyph];
int px = (tile % tiles_per_row) * width();
int py = tile / tiles_per_row * height();
if (!reversed) {
int tile = glyph2tile[glyph];
int px = (tile % tiles_per_row) * width();
int py = tile / tiles_per_row * height();
painter.drawPixmap(x, y, pm, px, py, width(), height());
painter.drawPixmap(x, y, pm, px, py, width(), height());
} else {
// for paper doll; mirrored image for left side of two-handed weapon
painter.drawPixmap(x, y, reversed_pixmap(glyph),
0, 0, width(), height());
}
}
void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph,
int cellx, int celly)
{
drawGlyph(painter, glyph, cellx * width(), celly * height());
drawGlyph(painter, glyph, cellx * width(), celly * height(), false);
}
void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph,
int cellx, int celly, int border)
int cellx, int celly, int border,
bool reversed)
{
int wd = width(),
ht = height(),
@@ -105,7 +113,7 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph,
lox = cellx * (wd + 2),
loy = celly * (ht + 2) + yoffset;
drawGlyph(painter, glyph, lox + 1, loy + 1);
drawGlyph(painter, glyph, lox + 1, loy + 1, reversed);
#ifdef TEXTCOLOR
if (border != NO_BORDER) {
@@ -155,9 +163,10 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph,
#endif
}
QPixmap NetHackQtGlyphs::glyph(int glyph)
// mis-named routine to get the pixmap for a particular glyph
QPixmap NetHackQtGlyphs::glyph(int glyphindx)
{
int tile = glyph2tile[glyph];
int tile = glyph2tile[glyphindx];
int px = (tile % tiles_per_row) * tilefile_tile_W;
int py = tile / tiles_per_row * tilefile_tile_H;
@@ -165,6 +174,27 @@ QPixmap NetHackQtGlyphs::glyph(int glyph)
tilefile_tile_W, tilefile_tile_H));
}
// transpose a glyph's tile horizontally, scaled for use in paper doll
QPixmap NetHackQtGlyphs::reversed_pixmap(int glyphindx)
{
QPixmap pxmp = glyph(glyphindx);
#ifdef ENHANCED_PAPERDOLL
qreal wid = (qreal) pxmp.width(),
//hgt = (qreal) pxmp.height(),
xscale = (qreal) qt_settings->dollWidth / (qreal) tilefile_tile_W,
yscale = (qreal) qt_settings->dollHeight / (qreal) tilefile_tile_H;
QTransform *mirrormatrix = new QTransform(
// negate x coordinates to flip the image across the y-axis
-1.0 * xscale, 0.0, 0.0, yscale,
// slide flipped image to the right to make things positive again
wid * xscale, 0.0
);
return pxmp.transformed(*mirrormatrix);
#else
return pxmp;
#endif
}
void NetHackQtGlyphs::setSize(int w, int h)
{
if (size == QSize(w, h))

View File

@@ -23,17 +23,21 @@ public:
void toggleSize();
void setSize(int w, int h);
void drawGlyph(QPainter&, int glyph, int pixelx, int pixely);
void drawCell(QPainter&, int glyph, int cellx, int celly);
void drawBorderedCell(QPainter&, int glyph,
int cellx, int celly, int bordercode);
QPixmap glyph(int glyph);
void drawGlyph(QPainter &, int glyph, int pixelx, int pixely,
bool reversed = false);
void drawCell(QPainter &, int glyph, int cellx, int celly);
void drawBorderedCell(QPainter &, int glyph,
int cellx, int celly, int bordercode,
bool reversed);
QPixmap glyph(int glyphindx);
QPixmap reversed_pixmap(int glyphindx);
private:
QImage img;
QPixmap pm,pm1, pm2;
QSize size;
int tiles_per_row;
//QTransform *mirrormatrix;
};
} // namespace nethack_qt_

View File

@@ -61,10 +61,11 @@ NetHackQtInvUsageWindow::~NetHackQtInvUsageWindow()
void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj,
int x, int y, // cell index, not pixels
const char *alttip, bool canbe)
const char *alttip, int flags)
{
short int glyph;
int border;
bool rev = false;
if (nhobj) {
border = BORDER_DEFAULT;
@@ -86,6 +87,8 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj,
Strcpy(tips[x][y], itmnam);
else
tips[x][y] = dupstr(itmnam);
rev = (flags == dollReverse);
#endif
glyph = obj_to_glyph(nhobj, rn2_on_display_rng);
} else {
@@ -102,9 +105,11 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj,
#else
nhUse(alttip);
#endif
glyph = canbe ? cmap_to_glyph(S_room) : GLYPH_UNEXPLORED;
// an empty slot is shown as floor tile unless it's always empty
glyph = (flags != dollUnused) ? cmap_to_glyph(S_room)
: GLYPH_UNEXPLORED;
}
qt_settings->glyphs().drawBorderedCell(painter, glyph, x, y, border);
qt_settings->glyphs().drawBorderedCell(painter, glyph, x, y, border, rev);
}
// called to update the paper doll inventory subset
@@ -135,16 +140,14 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*)
// show lit lamp/lantern/candle/candelabrum on lower right side;
// show leash-in-use on lower left side
//
// Possible enhancement: for two-handed weapon, show the left hand
// instance as a mirror image of the normal right hand one.
//
// Actually indexed by grid[column][row].
#ifdef ENHANCED_PAPERDOLL
if (iflags.wc_ascii_map)
qt_settings->doll_is_shown = false;
if (!qt_settings->doll_is_shown)
return;
// set glyphs() for the paperdoll; might be different size than map's
// set glyphs() for the paper doll; might be different size than map's
qt_settings->glyphs().setSize(qt_settings->dollWidth,
qt_settings->dollHeight);
@@ -165,15 +168,15 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*)
never be Null when the corresponding tests pass */
if (u.twoweap)
drawWorn(painter, uswapwep, 0, 1, NULL); // secondary weapon, in use
else if (uwep && bimanual(uwep))
drawWorn(painter, uwep, 0, 1, NULL); // two-handed uwep shown twice
else if (uwep && bimanual(uwep)) // show two-handed uwep twice
drawWorn(painter, uwep, 0, 1, NULL, dollReverse); // uwep on left
else
drawWorn(painter, uarms, 0, 1, "no shield");
drawWorn(painter, uarmg, 0, 2, "no gloves");
drawWorn(painter, uleft, 0, 3, "no left ring");
/* light source and leash aren't unique and don't have pointers defined */
drawWorn(painter, find_tool(LEASH), 0, 4, "no leashes in use");
drawWorn(painter, NULL, 0, 5, NULL, false); // always blank
drawWorn(painter, NULL, 0, 5, NULL, dollUnused); // always blank
// middle column; no unused slots
drawWorn(painter, uarmh, 1, 0, "no helmet");
@@ -198,7 +201,7 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*)
(and might also duplicate Sunsword when it is wielded--hence lit--
depending upon whether another light source precedes it in invent) */
drawWorn(painter, find_tool(OIL_LAMP), 2, 4, "no active light sources");
drawWorn(painter, NULL, 2, 5, NULL, false); // always blank
drawWorn(painter, NULL, 2, 5, NULL, dollUnused); // always blank
painter.end();

View File

@@ -10,6 +10,9 @@
namespace nethack_qt_ {
// for calls to drawWorn
enum drawWornFlag { dollNoFlag = 0, dollUnused = 1, dollReverse = 2 };
class NetHackQtInvUsageWindow : public QWidget {
public:
NetHackQtInvUsageWindow(QWidget* parent);
@@ -23,7 +26,7 @@ protected:
private:
void drawWorn(QPainter &painter, obj *nhobj, int x, int y,
const char *alttip, bool canbe=true);
const char *alttip, int flags = dollNoFlag);
bool tooltip_event(QHelpEvent *tipevent);
char *tips[3][6]; // PAPERDOLL is a grid of 3x6 cells for tiles