Browse Source

Merge pull request #7 from ATGillespie25/fix/auto-walk-tracker

pull/8474/head
mojsior 2 months ago committed by GitHub
parent
commit
e6f0c9ac47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 518
      Source/controls/plrctrls.cpp
  2. 8545
      Source/diablo.cpp
  3. 1
      Source/diablo.h

518
Source/controls/plrctrls.cpp

@ -1,14 +1,14 @@
#include "controls/plrctrls.h"
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <list>
#include <string>
#ifdef USE_SDL3
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_gamepad.h>
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <list>
#include <string>
#ifdef USE_SDL3
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_gamepad.h>
#include <SDL3/SDL_timer.h>
#else
#include <SDL.h>
@ -16,20 +16,21 @@
#ifdef USE_SDL1
#include "utils/sdl2_to_1_2_backports.h"
#endif
#endif
#include <fmt/format.h>
#include "automap.h"
#include "control/control.hpp"
#include "controls/controller_motion.h"
#ifndef USE_SDL1
#endif
#include <fmt/format.h>
#include "automap.h"
#include "control/control.hpp"
#include "controls/controller_motion.h"
#ifndef USE_SDL1
#include "controls/devices/game_controller.h"
#endif
#include "controls/control_mode.hpp"
#include "controls/game_controls.h"
#include "controls/touch/gamepad.h"
#include "cursor.h"
#include "diablo.h"
#include "doom.h"
#include "engine/point.hpp"
#include "engine/points_in_rectangle_range.hpp"
@ -49,16 +50,16 @@
#include "panels/ui_panels.hpp"
#include "qol/chatlog.h"
#include "qol/stash.h"
#include "stores.h"
#include "towners.h"
#include "track.h"
#include "utils/format_int.hpp"
#include "utils/is_of.hpp"
#include "utils/language.h"
#include "utils/log.hpp"
#include "utils/screen_reader.hpp"
#include "utils/sdl_compat.h"
#include "utils/str_cat.hpp"
#include "stores.h"
#include "towners.h"
#include "track.h"
#include "utils/format_int.hpp"
#include "utils/is_of.hpp"
#include "utils/language.h"
#include "utils/log.hpp"
#include "utils/screen_reader.hpp"
#include "utils/sdl_compat.h"
#include "utils/str_cat.hpp"
namespace devilution {
@ -675,104 +676,104 @@ Point GetSlotCoord(int slot)
/**
* Return the item id of the current slot
*/
int GetItemIdOnSlot(int slot)
{
if (slot >= SLOTXY_INV_FIRST && slot <= SLOTXY_INV_LAST) {
return std::abs(MyPlayer->InvGrid[slot - SLOTXY_INV_FIRST]);
}
return 0;
}
StringOrView GetInventorySlotNameForSpeech(int slot)
{
switch (slot) {
case SLOTXY_HEAD:
return _("Head");
case SLOTXY_RING_LEFT:
return _("Left ring");
case SLOTXY_RING_RIGHT:
return _("Right ring");
case SLOTXY_AMULET:
return _("Amulet");
case SLOTXY_HAND_LEFT:
return _("Left hand");
case SLOTXY_HAND_RIGHT:
return _("Right hand");
case SLOTXY_CHEST:
return _("Chest");
default:
break;
}
if (slot >= SLOTXY_BELT_FIRST && slot <= SLOTXY_BELT_LAST)
return StrCat(_("Belt"), " ", slot - SLOTXY_BELT_FIRST + 1);
return _("Inventory");
}
void SpeakInventorySlotForAccessibility()
{
if (MyPlayer == nullptr)
return;
const Player &player = *MyPlayer;
const Item *item = nullptr;
if (Slot >= SLOTXY_BELT_FIRST && Slot <= SLOTXY_BELT_LAST) {
item = &player.SpdList[Slot - SLOTXY_BELT_FIRST];
} else if (Slot >= SLOTXY_INV_FIRST && Slot <= SLOTXY_INV_LAST) {
const int invId = GetItemIdOnSlot(Slot);
if (invId != 0)
item = &player.InvList[invId - 1];
} else {
switch (Slot) {
case SLOTXY_HEAD:
item = &player.InvBody[INVLOC_HEAD];
break;
case SLOTXY_RING_LEFT:
item = &player.InvBody[INVLOC_RING_LEFT];
break;
case SLOTXY_RING_RIGHT:
item = &player.InvBody[INVLOC_RING_RIGHT];
break;
case SLOTXY_AMULET:
item = &player.InvBody[INVLOC_AMULET];
break;
case SLOTXY_HAND_LEFT:
item = &player.InvBody[INVLOC_HAND_LEFT];
break;
case SLOTXY_HAND_RIGHT: {
const Item &left = player.InvBody[INVLOC_HAND_LEFT];
if (!left.isEmpty() && player.GetItemLocation(left) == ILOC_TWOHAND)
item = &left;
else
item = &player.InvBody[INVLOC_HAND_RIGHT];
} break;
case SLOTXY_CHEST:
item = &player.InvBody[INVLOC_CHEST];
break;
default:
break;
}
}
if (item != nullptr && !item->isEmpty()) {
if (item->_itype == ItemType::Gold) {
const int nGold = item->_ivalue;
SpeakText(fmt::format(fmt::runtime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold)), FormatInteger(nGold)), /*force=*/true);
} else {
SpeakText(item->getName(), /*force=*/true);
}
return;
}
SpeakText(StrCat(GetInventorySlotNameForSpeech(Slot), ": ", _("empty")), /*force=*/true);
}
/**
* Get item size (grid size) on the slot specified. Returns 1x1 if none exists.
*/
int GetItemIdOnSlot(int slot)
{
if (slot >= SLOTXY_INV_FIRST && slot <= SLOTXY_INV_LAST) {
return std::abs(MyPlayer->InvGrid[slot - SLOTXY_INV_FIRST]);
}
return 0;
}
StringOrView GetInventorySlotNameForSpeech(int slot)
{
switch (slot) {
case SLOTXY_HEAD:
return _("Head");
case SLOTXY_RING_LEFT:
return _("Left ring");
case SLOTXY_RING_RIGHT:
return _("Right ring");
case SLOTXY_AMULET:
return _("Amulet");
case SLOTXY_HAND_LEFT:
return _("Left hand");
case SLOTXY_HAND_RIGHT:
return _("Right hand");
case SLOTXY_CHEST:
return _("Chest");
default:
break;
}
if (slot >= SLOTXY_BELT_FIRST && slot <= SLOTXY_BELT_LAST)
return StrCat(_("Belt"), " ", slot - SLOTXY_BELT_FIRST + 1);
return _("Inventory");
}
void SpeakInventorySlotForAccessibility()
{
if (MyPlayer == nullptr)
return;
const Player &player = *MyPlayer;
const Item *item = nullptr;
if (Slot >= SLOTXY_BELT_FIRST && Slot <= SLOTXY_BELT_LAST) {
item = &player.SpdList[Slot - SLOTXY_BELT_FIRST];
} else if (Slot >= SLOTXY_INV_FIRST && Slot <= SLOTXY_INV_LAST) {
const int invId = GetItemIdOnSlot(Slot);
if (invId != 0)
item = &player.InvList[invId - 1];
} else {
switch (Slot) {
case SLOTXY_HEAD:
item = &player.InvBody[INVLOC_HEAD];
break;
case SLOTXY_RING_LEFT:
item = &player.InvBody[INVLOC_RING_LEFT];
break;
case SLOTXY_RING_RIGHT:
item = &player.InvBody[INVLOC_RING_RIGHT];
break;
case SLOTXY_AMULET:
item = &player.InvBody[INVLOC_AMULET];
break;
case SLOTXY_HAND_LEFT:
item = &player.InvBody[INVLOC_HAND_LEFT];
break;
case SLOTXY_HAND_RIGHT: {
const Item &left = player.InvBody[INVLOC_HAND_LEFT];
if (!left.isEmpty() && player.GetItemLocation(left) == ILOC_TWOHAND)
item = &left;
else
item = &player.InvBody[INVLOC_HAND_RIGHT];
} break;
case SLOTXY_CHEST:
item = &player.InvBody[INVLOC_CHEST];
break;
default:
break;
}
}
if (item != nullptr && !item->isEmpty()) {
if (item->_itype == ItemType::Gold) {
const int nGold = item->_ivalue;
SpeakText(fmt::format(fmt::runtime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold)), FormatInteger(nGold)), /*force=*/true);
} else {
SpeakText(item->getName(), /*force=*/true);
}
return;
}
SpeakText(StrCat(GetInventorySlotNameForSpeech(Slot), ": ", _("empty")), /*force=*/true);
}
/**
* Get item size (grid size) on the slot specified. Returns 1x1 if none exists.
*/
Size GetItemSizeOnSlot(int slot)
{
if (slot >= SLOTXY_INV_FIRST && slot <= SLOTXY_INV_LAST) {
@ -1238,14 +1239,14 @@ void InventoryMove(AxisDirection dir)
mousePos.y += ((itemSize.height - 1) * InventorySlotSizeInPixels.height) / 2;
}
if (mousePos == MousePosition) {
SpeakInventorySlotForAccessibility();
return; // Avoid wobbling when scaled
}
SetCursorPos(mousePos);
SpeakInventorySlotForAccessibility();
}
if (mousePos == MousePosition) {
SpeakInventorySlotForAccessibility();
return; // Avoid wobbling when scaled
}
SetCursorPos(mousePos);
SpeakInventorySlotForAccessibility();
}
/**
* Move the cursor around in the inventory
@ -1443,12 +1444,12 @@ void StashMove(AxisDirection dir)
FocusOnInventory();
}
void HotSpellMoveInternal(AxisDirection dir)
{
static AxisDirectionRepeater repeater;
dir = repeater.Get(dir);
if (dir.x == AxisDirectionX_NONE && dir.y == AxisDirectionY_NONE)
return;
void HotSpellMoveInternal(AxisDirection dir)
{
static AxisDirectionRepeater repeater;
dir = repeater.Get(dir);
if (dir.x == AxisDirectionX_NONE && dir.y == AxisDirectionY_NONE)
return;
auto spellListItems = GetSpellListItems();
@ -1591,14 +1592,14 @@ void StoreMove(AxisDirection moveDir)
using HandleLeftStickOrDPadFn = void (*)(devilution::AxisDirection);
HandleLeftStickOrDPadFn GetLeftStickOrDPadGameUIHandler()
{
if (SpellSelectFlag) {
return &HotSpellMoveInternal;
}
if (IsStashOpen) {
return &StashMove;
}
HandleLeftStickOrDPadFn GetLeftStickOrDPadGameUIHandler()
{
if (SpellSelectFlag) {
return &HotSpellMoveInternal;
}
if (IsStashOpen) {
return &StashMove;
}
if (invflag) {
return &CheckInventoryMove;
}
@ -1826,16 +1827,16 @@ void LogGamepadChange(GamepadLayout newGamepad)
}
#endif
} // namespace
void HotSpellMove(AxisDirection dir)
{
HotSpellMoveInternal(dir);
}
void DetectInputMethod(const SDL_Event &event, const ControllerButtonEvent &gamepadEvent)
{
ControlTypes inputType = GetInputTypeFromEvent(event);
} // namespace
void HotSpellMove(AxisDirection dir)
{
HotSpellMoveInternal(dir);
}
void DetectInputMethod(const SDL_Event &event, const ControllerButtonEvent &gamepadEvent)
{
ControlTypes inputType = GetInputTypeFromEvent(event);
if (inputType == ControlTypes::None)
return;
@ -2005,20 +2006,20 @@ void InvalidateInventorySlot()
/**
* @brief Moves the mouse to the first inventory slot.
*/
void FocusOnInventory()
{
Slot = SLOTXY_INV_FIRST;
ResetInvCursorPosition();
SpeakInventorySlotForAccessibility();
}
void InventoryMoveFromKeyboard(AxisDirection dir)
{
if (!invflag)
return;
CheckInventoryMove(dir);
}
void FocusOnInventory()
{
Slot = SLOTXY_INV_FIRST;
ResetInvCursorPosition();
SpeakInventorySlotForAccessibility();
}
void InventoryMoveFromKeyboard(AxisDirection dir)
{
if (!invflag)
return;
CheckInventoryMove(dir);
}
bool PointAndClickState = false;
@ -2090,10 +2091,10 @@ void plrctrls_after_game_logic()
Movement(*MyPlayer);
}
void UseBeltItem(BeltItemType type)
{
for (int i = 0; i < MaxBeltItems; i++) {
const Item &item = MyPlayer->SpdList[i];
void UseBeltItem(BeltItemType type)
{
for (int i = 0; i < MaxBeltItems; i++) {
const Item &item = MyPlayer->SpdList[i];
if (item.isEmpty()) {
continue;
}
@ -2105,55 +2106,56 @@ void UseBeltItem(BeltItemType type)
if ((type == BeltItemType::Healing && isHealing) || (type == BeltItemType::Mana && isMana)) {
UseInvItem(INVITEM_BELT_FIRST + i);
break;
}
}
}
namespace {
void UpdateTargetsForKeyboardAction()
{
// Clear focus set by cursor.
PlayerUnderCursor = nullptr;
pcursmonst = -1;
pcursitem = -1;
ObjectUnderCursor = nullptr;
pcursmissile = nullptr;
pcurstrig = -1;
pcursquest = Q_INVALID;
cursPosition = { -1, -1 };
if (MyPlayer == nullptr)
return;
if (MyPlayer->_pInvincible)
return;
if (DoomFlag)
return;
if (invflag)
return;
InfoString = StringOrView {};
FindActor();
FindItemOrObject();
FindTrigger();
}
} // namespace
void PerformPrimaryActionAutoTarget()
{
if (ControlMode == ControlTypes::KeyboardAndMouse && !IsPointAndClick()) {
UpdateTargetsForKeyboardAction();
}
PerformPrimaryAction();
}
void PerformPrimaryAction()
{
if (SpellSelectFlag) {
SetSpell();
return;
}
}
}
namespace {
void UpdateTargetsForKeyboardAction()
{
// Clear focus set by cursor.
PlayerUnderCursor = nullptr;
pcursmonst = -1;
pcursitem = -1;
ObjectUnderCursor = nullptr;
pcursmissile = nullptr;
pcurstrig = -1;
pcursquest = Q_INVALID;
cursPosition = { -1, -1 };
if (MyPlayer == nullptr)
return;
if (MyPlayer->_pInvincible)
return;
if (DoomFlag)
return;
if (invflag)
return;
InfoString = StringOrView {};
FindActor();
FindItemOrObject();
FindTrigger();
}
} // namespace
void PerformPrimaryActionAutoTarget()
{
CancelAutoWalk();
if (ControlMode == ControlTypes::KeyboardAndMouse && !IsPointAndClick()) {
UpdateTargetsForKeyboardAction();
}
PerformPrimaryAction();
}
void PerformPrimaryAction()
{
if (SpellSelectFlag) {
SetSpell();
return;
}
if (invflag) { // inventory is open
@ -2176,9 +2178,9 @@ void PerformPrimaryAction()
ReleaseChrBtns(false);
return;
}
Interact();
}
Interact();
}
bool SpellHasActorTarget()
{
@ -2322,11 +2324,11 @@ void CtrlUseInvItem()
}
}
void CtrlUseStashItem()
{
if (pcursstashitem == StashStruct::EmptyCell) {
return;
}
void CtrlUseStashItem()
{
if (pcursstashitem == StashStruct::EmptyCell) {
return;
}
const Item &item = Stash.stashList[pcursstashitem];
if (item.isScroll()) {
@ -2342,31 +2344,33 @@ void CtrlUseStashItem()
CheckStashItem(MousePosition, true, false); // Auto-equip if it's equipment
} else {
UseStashItem(pcursstashitem);
}
// Todo reset cursor position if item is moved
}
void PerformSecondaryActionAutoTarget()
{
if (ControlMode == ControlTypes::KeyboardAndMouse && !IsPointAndClick()) {
UpdateTargetsForKeyboardAction();
}
PerformSecondaryAction();
}
void PerformSpellActionAutoTarget()
{
if (ControlMode == ControlTypes::KeyboardAndMouse && !IsPointAndClick()) {
UpdateTargetsForKeyboardAction();
}
PerformSpellAction();
}
void PerformSecondaryAction()
{
Player &myPlayer = *MyPlayer;
if (invflag) {
if (pcurs > CURSOR_HAND && pcurs < CURSOR_FIRSTITEM) {
}
// Todo reset cursor position if item is moved
}
void PerformSecondaryActionAutoTarget()
{
CancelAutoWalk();
if (ControlMode == ControlTypes::KeyboardAndMouse && !IsPointAndClick()) {
UpdateTargetsForKeyboardAction();
}
PerformSecondaryAction();
}
void PerformSpellActionAutoTarget()
{
CancelAutoWalk();
if (ControlMode == ControlTypes::KeyboardAndMouse && !IsPointAndClick()) {
UpdateTargetsForKeyboardAction();
}
PerformSpellAction();
}
void PerformSecondaryAction()
{
Player &myPlayer = *MyPlayer;
if (invflag) {
if (pcurs > CURSOR_HAND && pcurs < CURSOR_FIRSTITEM) {
TryIconCurs();
NewCursor(CURSOR_HAND);
} else if (IsStashOpen) {

8545
Source/diablo.cpp

File diff suppressed because it is too large Load Diff

1
Source/diablo.h

@ -102,6 +102,7 @@ void DisableInputEventHandler(const SDL_Event &event, uint16_t modState);
tl::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir);
bool IsDiabloAlive(bool playSFX);
void PrintScreen(SDL_Keycode vkey);
void CancelAutoWalk();
/**
* @param bStartup Process additional ticks before returning

Loading…
Cancel
Save