Browse Source

Fix speedbook navigation on gamepad

pull/3373/head
Stephen C. Wills 4 years ago committed by GitHub
parent
commit
423441c3dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 111
      Source/control.cpp
  2. 8
      Source/control.h
  3. 135
      Source/controls/plrctrls.cpp
  4. 1
      Source/controls/plrctrls.h
  5. 1
      Source/miniwin/misc_msg.cpp

111
Source/control.cpp

@ -618,65 +618,6 @@ void RemoveGold(Player &player, int goldIndex)
dropGoldValue = 0;
}
struct SpellListItem {
Point location;
spell_type type;
spell_id id;
bool isSelected;
};
std::vector<SpellListItem> GetSpellListItems()
{
std::vector<SpellListItem> spellListItems;
uint64_t mask;
int x = PANEL_X + 12 + SPLICONLENGTH * SPLROWICONLS;
int y = PANEL_Y - 17;
for (int i = RSPLTYPE_SKILL; i < RSPLTYPE_INVALID; i++) {
auto &myPlayer = Players[MyPlayerId];
switch ((spell_type)i) {
case RSPLTYPE_SKILL:
mask = myPlayer._pAblSpells;
break;
case RSPLTYPE_SPELL:
mask = myPlayer._pMemSpells;
break;
case RSPLTYPE_SCROLL:
mask = myPlayer._pScrlSpells;
break;
case RSPLTYPE_CHARGES:
mask = myPlayer._pISpells;
break;
case RSPLTYPE_INVALID:
break;
}
int8_t j = SPL_FIREBOLT;
for (uint64_t spl = 1; j < MAX_SPELLS; spl <<= 1, j++) {
if ((mask & spl) == 0)
continue;
int lx = x;
int ly = y - SPLICONLENGTH;
bool isSelected = (MousePosition.x >= lx && MousePosition.x < lx + SPLICONLENGTH && MousePosition.y >= ly && MousePosition.y < ly + SPLICONLENGTH);
spellListItems.emplace_back(SpellListItem { { x, y }, (spell_type)i, (spell_id)j, isSelected });
x -= SPLICONLENGTH;
if (x == PANEL_X + 12 - SPLICONLENGTH) {
x = PANEL_X + 12 + SPLICONLENGTH * SPLROWICONLS;
y -= SPLICONLENGTH;
}
}
if (mask != 0 && x != PANEL_X + 12 + SPLICONLENGTH * SPLROWICONLS)
x -= SPLICONLENGTH;
if (x == PANEL_X + 12 - SPLICONLENGTH) {
x = PANEL_X + 12 + SPLICONLENGTH * SPLROWICONLS;
y -= SPLICONLENGTH;
}
}
return spellListItems;
}
bool GetSpellListSelection(spell_id &pSpell, spell_type &pSplType)
{
pSpell = spell_id::SPL_INVALID;
@ -817,6 +758,58 @@ void DrawSpellList(const Surface &out)
}
}
std::vector<SpellListItem> GetSpellListItems()
{
std::vector<SpellListItem> spellListItems;
uint64_t mask;
int x = PANEL_X + 12 + SPLICONLENGTH * SPLROWICONLS;
int y = PANEL_Y - 17;
for (int i = RSPLTYPE_SKILL; i < RSPLTYPE_INVALID; i++) {
auto &myPlayer = Players[MyPlayerId];
switch ((spell_type)i) {
case RSPLTYPE_SKILL:
mask = myPlayer._pAblSpells;
break;
case RSPLTYPE_SPELL:
mask = myPlayer._pMemSpells;
break;
case RSPLTYPE_SCROLL:
mask = myPlayer._pScrlSpells;
break;
case RSPLTYPE_CHARGES:
mask = myPlayer._pISpells;
break;
case RSPLTYPE_INVALID:
break;
}
int8_t j = SPL_FIREBOLT;
for (uint64_t spl = 1; j < MAX_SPELLS; spl <<= 1, j++) {
if ((mask & spl) == 0)
continue;
int lx = x;
int ly = y - SPLICONLENGTH;
bool isSelected = (MousePosition.x >= lx && MousePosition.x < lx + SPLICONLENGTH && MousePosition.y >= ly && MousePosition.y < ly + SPLICONLENGTH);
spellListItems.emplace_back(SpellListItem { { x, y }, (spell_type)i, (spell_id)j, isSelected });
x -= SPLICONLENGTH;
if (x == PANEL_X + 12 - SPLICONLENGTH) {
x = PANEL_X + 12 + SPLICONLENGTH * SPLROWICONLS;
y -= SPLICONLENGTH;
}
}
if (mask != 0 && x != PANEL_X + 12 + SPLICONLENGTH * SPLROWICONLS)
x -= SPLICONLENGTH;
if (x == PANEL_X + 12 - SPLICONLENGTH) {
x = PANEL_X + 12 + SPLICONLENGTH * SPLROWICONLS;
y -= SPLICONLENGTH;
}
}
return spellListItems;
}
void SetSpell()
{
spell_id pSpell;

8
Source/control.h

@ -28,6 +28,13 @@ namespace devilution {
#define SPANEL_WIDTH 320
#define SPANEL_HEIGHT 352
struct SpellListItem {
Point location;
spell_type type;
spell_id id;
bool isSelected;
};
extern bool drawhpflag;
extern bool dropGoldFlag;
extern bool chrbtn[4];
@ -168,6 +175,7 @@ void ReleaseChrBtns(bool addAllStatPoints);
void DrawDurIcon(const Surface &out);
void RedBack(const Surface &out);
void DrawSpellBook(const Surface &out);
std::vector<SpellListItem> GetSpellListItems();
void CheckSBook();
void DrawGoldSplit(const Surface &out, int amount);
void control_drop_gold(char vkey);

135
Source/controls/plrctrls.cpp

@ -29,8 +29,6 @@ namespace devilution {
bool sgbTouchActive = false;
bool sgbControllerActive = false;
Point speedspellscoords[50];
int speedspellcount = 0;
int pcurstrig = -1;
int pcursmissile = -1;
quest_id pcursquest = Q_INVALID;
@ -1014,22 +1012,6 @@ void InvMove(AxisDirection dir)
SetCursorPos(mousePos);
}
/**
* check if hot spell at X Y exists
*/
bool HSExists(Point target)
{
for (int r = 0; r < speedspellcount; r++) {
if (target.x >= speedspellscoords[r].x - SPLICONLENGTH / 2
&& target.x < speedspellscoords[r].x + SPLICONLENGTH / 2
&& target.y >= speedspellscoords[r].y - SPLICONLENGTH / 2
&& target.y < speedspellscoords[r].y + SPLICONLENGTH / 2) {
return true;
}
}
return false;
}
void HotSpellMove(AxisDirection dir)
{
static AxisDirectionRepeater repeater;
@ -1037,41 +1019,55 @@ void HotSpellMove(AxisDirection dir)
if (dir.x == AxisDirectionX_NONE && dir.y == AxisDirectionY_NONE)
return;
int spbslot = Players[MyPlayerId]._pRSpell;
for (int r = 0; r < speedspellcount; r++) {
if (MousePosition.x >= speedspellscoords[r].x - SPLICONLENGTH / 2
&& MousePosition.x < speedspellscoords[r].x + SPLICONLENGTH / 2
&& MousePosition.y >= speedspellscoords[r].y - SPLICONLENGTH / 2
&& MousePosition.y < speedspellscoords[r].y + SPLICONLENGTH / 2) {
spbslot = r;
break;
auto spellListItems = GetSpellListItems();
Point position = MousePosition;
int shortestDistance = std::numeric_limits<int>::max();
for (auto &spellListItem : spellListItems) {
Point center = spellListItem.location + Displacement { SPLICONLENGTH / 2, -SPLICONLENGTH / 2 };
int distance = MousePosition.ManhattanDistance(center);
if (distance < shortestDistance) {
position = center;
shortestDistance = distance;
}
}
Point newMousePosition = speedspellscoords[spbslot];
const auto search = [&](AxisDirection dir, bool searchForward) {
if (dir.x == AxisDirectionX_NONE && dir.y == AxisDirectionY_NONE)
return;
if (dir.x == AxisDirectionX_LEFT) {
if (spbslot < speedspellcount - 1) {
newMousePosition = speedspellscoords[spbslot + 1];
}
} else if (dir.x == AxisDirectionX_RIGHT) {
if (spbslot > 0) {
newMousePosition = speedspellscoords[spbslot - 1];
}
}
for (size_t i = 0; i < spellListItems.size(); i++) {
const size_t index = i;
if (searchForward)
index = spellListItems.size() - i - 1;
if (dir.y == AxisDirectionY_UP) {
if (HSExists(newMousePosition - Displacement { 0, SPLICONLENGTH })) {
newMousePosition.y -= SPLICONLENGTH;
}
} else if (dir.y == AxisDirectionY_DOWN) {
if (HSExists(newMousePosition + Displacement { 0, SPLICONLENGTH })) {
newMousePosition.y += SPLICONLENGTH;
auto &spellListItem = spellListItems[index];
if (spellListItem.isSelected)
continue;
Point center = spellListItem.location + Displacement { SPLICONLENGTH / 2, -SPLICONLENGTH / 2 };
if (dir.x == AxisDirectionX_LEFT && center.x >= MousePosition.x)
continue;
if (dir.x == AxisDirectionX_RIGHT && center.x <= MousePosition.x)
continue;
if (dir.x == AxisDirectionX_NONE && center.x != position.x)
continue;
if (dir.y == AxisDirectionY_UP && center.y >= MousePosition.y)
continue;
if (dir.y == AxisDirectionY_DOWN && center.y <= MousePosition.y)
continue;
if (dir.y == AxisDirectionY_NONE && center.y != position.y)
continue;
position = center;
break;
}
}
};
search({ AxisDirectionX_NONE, dir.y }, dir.y == AxisDirectionY_DOWN);
search({ dir.x, AxisDirectionY_NONE }, dir.x == AxisDirectionX_RIGHT);
if (newMousePosition != MousePosition) {
SetCursorPos(newMousePosition);
if (position != MousePosition) {
SetCursorPos(position);
}
}
@ -1254,53 +1250,6 @@ struct RightStickAccumulator {
} // namespace
void StoreSpellCoords()
{
const int startX = PANEL_LEFT + 12 + SPLICONLENGTH / 2;
const int endX = startX + SPLICONLENGTH * 10;
const int endY = PANEL_TOP - 17 - SPLICONLENGTH / 2;
speedspellcount = 0;
int xo = endX;
int yo = endY;
for (int i = RSPLTYPE_SKILL; i <= RSPLTYPE_CHARGES; i++) {
std::uint64_t spells;
auto &myPlayer = Players[MyPlayerId];
switch (i) {
case RSPLTYPE_SKILL:
spells = myPlayer._pAblSpells;
break;
case RSPLTYPE_SPELL:
spells = myPlayer._pMemSpells;
break;
case RSPLTYPE_SCROLL:
spells = myPlayer._pScrlSpells;
break;
case RSPLTYPE_CHARGES:
spells = myPlayer._pISpells;
break;
}
std::uint64_t spell = 1;
for (int j = 1; j < MAX_SPELLS; j++) {
if ((spell & spells) != 0) {
speedspellscoords[speedspellcount] = { xo, yo };
++speedspellcount;
xo -= SPLICONLENGTH;
if (xo < startX) {
xo = endX;
yo -= SPLICONLENGTH;
}
}
spell <<= 1;
}
if (spells != 0 && xo != endX)
xo -= SPLICONLENGTH;
if (xo < startX) {
xo = endX;
yo -= SPLICONLENGTH;
}
}
}
bool IsAutomapActive()
{
return AutomapActive && leveltype != DTYPE_TOWN;

1
Source/controls/plrctrls.h

@ -45,7 +45,6 @@ bool TryDropItem();
void InvalidateInventorySlot();
void FocusOnInventory();
void PerformSpellAction();
void StoreSpellCoords();
extern int speedspellcount;

1
Source/miniwin/misc_msg.cpp

@ -403,7 +403,6 @@ bool FetchMessage_Real(tagMSG *lpMsg)
chrflag = false;
QuestLogIsOpen = false;
sbookflag = false;
StoreSpellCoords();
}
break;
case GameActionType_TOGGLE_CHARACTER_INFO:

Loading…
Cancel
Save