Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement quick spell cycling #6861

Merged
merged 6 commits into from
Dec 14, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Source/diablo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,33 @@ void SpellBookKeyPressed()
CloseInventory();
}

void CycleSpellHotkeys(bool next)
{
StaticVector<size_t, NumHotkeys> validHotKeyIndexes;
std::optional<size_t> currentIndex;
for (size_t slot = 0; slot < NumHotkeys; slot++) {
if (!IsValidSpeedSpell(slot))
continue;
if (MyPlayer->_pRSpell == MyPlayer->_pSplHotKey[slot] && MyPlayer->_pRSplType == MyPlayer->_pSplTHotKey[slot]) {
// found current
currentIndex = validHotKeyIndexes.size();
}
validHotKeyIndexes.emplace_back(slot);
}
if (validHotKeyIndexes.size() == 0)
return;

size_t newIndex;
if (!currentIndex) {
newIndex = next ? 0 : (validHotKeyIndexes.size() - 1);
} else if (next) {
newIndex = (*currentIndex == validHotKeyIndexes.size() - 1) ? 0 : (*currentIndex + 1);
} else {
newIndex = *currentIndex == 0 ? (validHotKeyIndexes.size() - 1) : (*currentIndex - 1);
}
ToggleSpell(validHotKeyIndexes[newIndex]);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks.... more complicated than it needs to be, at least at first glance.

Have you considered just creating 2 separate functions, "NextSkill" and "PreviousSkill", instead of combining both here?

Also, isn't there something in C++ like a "circular iterator" that we could tap into? Then, it would be a matter of walking forward or backward on it, while checking for the first valid spell occurrence using those predicate lambdas.

I don't know..... this might be me just misremembering how awful C++ is, but this looks incredibly convoluted for such a simple operation conceptually. Maybe we are just lacking some abstraction here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't given it much thought.
But I don't know anything about a circular iterator.
If you want you can give it a try to improve it. 🙂


bool IsPlayerDead()
{
return MyPlayer->_pmode == PM_DEATH || MyPlayerIsDead;
Expand Down Expand Up @@ -1680,6 +1707,22 @@ void InitKeymapActions()
CanPlayerTakeAction,
i + 1);
}
sgOptions.Keymapper.AddAction(
"QuickSpellPrevious",
N_("Previous quick spell"),
N_("Selects the previous quick spell (cycles)."),
MouseScrollUpButton,
[] { CycleSpellHotkeys(false); },
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
"QuickSpellNext",
N_("Next quick spell"),
N_("Selects the next quick spell (cycles)."),
MouseScrollDownButton,
[] { CycleSpellHotkeys(true); },
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
"UseHealthPotion",
N_("Use health potion"),
Expand Down
Loading