Skip to content

Commit

Permalink
Clean up selection type
Browse files Browse the repository at this point in the history
  • Loading branch information
AJenbo authored and StephenCWills committed Sep 15, 2024
1 parent e58ba95 commit e949f41
Show file tree
Hide file tree
Showing 19 changed files with 409 additions and 371 deletions.
4 changes: 2 additions & 2 deletions Source/controls/plrctrls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void FindItemOrObject()
continue;
}
Item &item = Items[itemId];
if (item.isEmpty() || item._iSelFlag == 0) {
if (item.isEmpty() || item.selectionRegion == SelectionRegion::None) {
continue;
}

Expand All @@ -189,7 +189,7 @@ void FindItemOrObject()

for (WorldTilePosition targetPosition : searchArea) {
Object *object = FindObjectAtPosition(targetPosition);
if (object == nullptr || object->_oSelFlag == 0) {
if (object == nullptr || !object->canInteractWith()) {
// No object or non-interactive object
continue;
}
Expand Down
34 changes: 17 additions & 17 deletions Source/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,29 +69,29 @@ bool IsValidMonsterForSelection(const Monster &monster)

bool TrySelectMonster(bool flipflag, Point tile, tl::function_ref<bool(const Monster &)> isValidMonster)
{
auto checkPosition = [&](int8_t selectionType, Displacement displacement) {
auto checkPosition = [&](SelectionRegion selectionRegion, Displacement displacement) {
Point posToCheck = tile + displacement;
if (!InDungeonBounds(posToCheck) || dMonster[posToCheck.x][posToCheck.y] == 0)
return;
const uint16_t monsterId = std::abs(dMonster[posToCheck.x][posToCheck.y]) - 1;
const Monster &monster = Monsters[monsterId];
if (IsTileLit(posToCheck) && (monster.data().selectionType & selectionType) != 0 && isValidMonster(monster)) {
if (IsTileLit(posToCheck) && HasAnyOf(monster.data().selectionRegion, selectionRegion) && isValidMonster(monster)) {
cursPosition = posToCheck;
pcursmonst = monsterId;
}
};

if (!flipflag)
checkPosition(4, { 2, 1 });
checkPosition(SelectionRegion::Top, { 2, 1 });
if (flipflag)
checkPosition(4, { 1, 2 });
checkPosition(4, { 2, 2 });
checkPosition(SelectionRegion::Top, { 1, 2 });
checkPosition(SelectionRegion::Top, { 2, 2 });
if (!flipflag)
checkPosition(2, { 1, 0 });
checkPosition(SelectionRegion::Middle, { 1, 0 });
if (flipflag)
checkPosition(2, { 0, 1 });
checkPosition(1, { 0, 0 });
checkPosition(2, { 1, 1 });
checkPosition(SelectionRegion::Middle, { 0, 1 });
checkPosition(SelectionRegion::Bottom, { 0, 0 });
checkPosition(SelectionRegion::Middle, { 1, 1 });
return pcursmonst != -1;
}

Expand Down Expand Up @@ -181,18 +181,18 @@ bool TrySelectObject(bool flipflag, Point tile)
Point testPosition = tile + Direction::South;
Object *object = FindObjectAtPosition(testPosition);

if (object == nullptr || object->_oSelFlag < 2) {
if (object == nullptr || HasNoneOf(object->selectionRegion, SelectionRegion::Middle)) {
// Either no object or can't interact from the test position, try the current tile
testPosition = tile;
object = FindObjectAtPosition(testPosition);

if (object == nullptr || IsNoneOf(object->_oSelFlag, 1, 3)) {
if (object == nullptr || HasNoneOf(object->selectionRegion, SelectionRegion::Bottom)) {
// Still no object (that could be activated from this position), try the tile to the bottom left or right
// (whichever is closest to the cursor as determined when we set flipflag earlier)
testPosition = tile + (flipflag ? Direction::SouthWest : Direction::SouthEast);
object = FindObjectAtPosition(testPosition);

if (object != nullptr && object->_oSelFlag < 2) {
if (object != nullptr && HasNoneOf(object->selectionRegion, SelectionRegion::Middle)) {
// Found an object but it's not in range, clear the pointer
object = nullptr;
}
Expand All @@ -211,28 +211,28 @@ bool TrySelectItem(bool flipflag, int mx, int my)
{
if (!flipflag && mx + 1 < MAXDUNX && dItem[mx + 1][my] > 0) {
const uint8_t itemId = dItem[mx + 1][my] - 1;
if (Items[itemId]._iSelFlag >= 2) {
if (HasAnyOf(Items[itemId].selectionRegion, SelectionRegion::Middle)) {
cursPosition = Point { mx, my } + Displacement { 1, 0 };
pcursitem = static_cast<int8_t>(itemId);
}
}
if (flipflag && my + 1 < MAXDUNY && dItem[mx][my + 1] > 0) {
const uint8_t itemId = dItem[mx][my + 1] - 1;
if (Items[itemId]._iSelFlag >= 2) {
if (HasAnyOf(Items[itemId].selectionRegion, SelectionRegion::Middle)) {
cursPosition = Point { mx, my } + Displacement { 0, 1 };
pcursitem = static_cast<int8_t>(itemId);
}
}
if (dItem[mx][my] > 0) {
const uint8_t itemId = dItem[mx][my] - 1;
if (Items[itemId]._iSelFlag == 1 || Items[itemId]._iSelFlag == 3) {
if (HasAnyOf(Items[itemId].selectionRegion, SelectionRegion::Bottom)) {
cursPosition = { mx, my };
pcursitem = static_cast<int8_t>(itemId);
}
}
if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dItem[mx + 1][my + 1] > 0) {
const uint8_t itemId = dItem[mx + 1][my + 1] - 1;
if (Items[itemId]._iSelFlag >= 2) {
if (HasAnyOf(Items[itemId].selectionRegion, SelectionRegion::Middle)) {
cursPosition = Point { mx, my } + Displacement { 1, 1 };
pcursitem = static_cast<int8_t>(itemId);
}
Expand Down Expand Up @@ -341,7 +341,7 @@ bool TrySelectPixelBased(Point tile)
}

Object *object = FindObjectAtPosition(adjacentTile);
if (object != nullptr && object->_oSelFlag != 0) {
if (object != nullptr && object->canInteractWith()) {
const ClxSprite sprite = object->currentSprite();
Displacement renderingOffset = object->getRenderingOffset(sprite, adjacentTile);
if (checkSprite(adjacentTile, sprite, renderingOffset)) {
Expand Down
9 changes: 9 additions & 0 deletions Source/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,18 @@
#include "engine.h"
#include "engine/clx_sprite.hpp"
#include "utils/attributes.h"
#include "utils/enum_traits.h"

namespace devilution {

enum class SelectionRegion : uint8_t {
None = 0,
Bottom = 1U << 0,
Middle = 1U << 1,
Top = 1U << 2,
};
use_enum_as_flags(SelectionRegion);

enum cursor_id : uint8_t {
CURSOR_NONE,
CURSOR_HAND,
Expand Down
2 changes: 1 addition & 1 deletion Source/inv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ void CleanupItems(int ii)

if (CornerStone.isAvailable() && item.position == CornerStone.position) {
CornerStone.item.clear();
CornerStone.item._iSelFlag = 0;
CornerStone.item.selectionRegion = SelectionRegion::None;
CornerStone.item.position = { 0, 0 };
CornerStone.item._iAnimFlag = false;
CornerStone.item._iIdentified = false;
Expand Down
44 changes: 22 additions & 22 deletions Source/items.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ void AddInitItems()
SetupItem(item);
item.AnimInfo.currentFrame = item.AnimInfo.numberOfFrames - 1;
item._iAnimFlag = false;
item._iSelFlag = 1;
item.selectionRegion = SelectionRegion::Bottom;
DeltaAddItem(ii);
}
}
Expand All @@ -485,7 +485,7 @@ void SpawnNote()
}

Point position = GetRandomAvailableItemPosition();
SpawnQuestItem(id, position, 0, 1, false);
SpawnQuestItem(id, position, 0, SelectionRegion::Bottom, false);
}

void CalcSelfItems(Player &player)
Expand Down Expand Up @@ -1603,7 +1603,7 @@ void SpawnRock()
int curlv = ItemsGetCurrlevel();
GetItemAttrs(item, IDI_ROCK, curlv);
SetupItem(item);
item._iSelFlag = 2;
item.selectionRegion = SelectionRegion::Middle;
item._iPostDraw = true;
item.AnimInfo.currentFrame = 10;
item._iCreateInfo |= CF_PREGEN;
Expand Down Expand Up @@ -2433,7 +2433,7 @@ void InitItems()
item.clear();
item.position = { 0, 0 };
item._iAnimFlag = false;
item._iSelFlag = 0;
item.selectionRegion = SelectionRegion::None;
item._iIdentified = false;
item._iPostDraw = false;
}
Expand All @@ -2447,17 +2447,17 @@ void InitItems()
if (Quests[Q_ROCK].IsAvailable())
SpawnRock();
if (Quests[Q_ANVIL].IsAvailable())
SpawnQuestItem(IDI_ANVIL, SetPiece.position.megaToWorld() + Displacement { 11, 11 }, 0, 1, false);
SpawnQuestItem(IDI_ANVIL, SetPiece.position.megaToWorld() + Displacement { 11, 11 }, 0, SelectionRegion::Bottom, false);
if (sgGameInitInfo.bCowQuest != 0 && currlevel == 20)
SpawnQuestItem(IDI_BROWNSUIT, { 25, 25 }, 3, 1, false);
SpawnQuestItem(IDI_BROWNSUIT, { 25, 25 }, 3, SelectionRegion::Bottom, false);
if (sgGameInitInfo.bCowQuest != 0 && currlevel == 19)
SpawnQuestItem(IDI_GREYSUIT, { 25, 25 }, 3, 1, false);
SpawnQuestItem(IDI_GREYSUIT, { 25, 25 }, 3, SelectionRegion::Bottom, false);
// In multiplayer items spawn during level generation to avoid desyncs
if (gbIsMultiplayer) {
if (Quests[Q_MUSHROOM].IsAvailable())
SpawnQuestItem(IDI_FUNGALTM, { 0, 0 }, 5, 1, false);
SpawnQuestItem(IDI_FUNGALTM, { 0, 0 }, 5, SelectionRegion::Bottom, false);
if (currlevel == Quests[Q_VEIL]._qlevel + 1 && Quests[Q_VEIL]._qactive != QUEST_NOTAVAIL)
SpawnQuestItem(IDI_GLDNELIX, { 0, 0 }, 5, 1, false);
SpawnQuestItem(IDI_GLDNELIX, { 0, 0 }, 5, SelectionRegion::Bottom, false);
}
if (currlevel > 0 && currlevel < 16)
AddInitItems();
Expand Down Expand Up @@ -3420,7 +3420,7 @@ void SpawnItem(Monster &monster, Point position, bool sendmsg, bool spawn /*= fa
// Drop the brain as extra item to ensure that all clients see the brain drop
// When executing SpawnItem is not reliable, because another client can already have the quest state updated before SpawnItem is executed
Point posBrain = GetSuperItemLoc(position);
SpawnQuestItem(IDI_BRAIN, posBrain, 0, 0, true);
SpawnQuestItem(IDI_BRAIN, posBrain, 0, SelectionRegion::None, true);
}
// Normal monster
if ((monster.data().treasure & T_NODROP) != 0)
Expand Down Expand Up @@ -3612,7 +3612,7 @@ void CornerstoneLoad(Point position)
CornerStone.item = item;
}

void SpawnQuestItem(_item_indexes itemid, Point position, int randarea, int selflag, bool sendmsg)
void SpawnQuestItem(_item_indexes itemid, Point position, int randarea, SelectionRegion selectionRegion, bool sendmsg)
{
if (randarea > 0) {
int tries = 0;
Expand Down Expand Up @@ -3652,8 +3652,8 @@ void SpawnQuestItem(_item_indexes itemid, Point position, int randarea, int self
item._iSeed = AdvanceRndSeed();
SetRndSeed(item._iSeed);
item._iPostDraw = true;
if (selflag != 0) {
item._iSelFlag = selflag;
if (selectionRegion != SelectionRegion::None) {
item.selectionRegion = selectionRegion;
item.AnimInfo.currentFrame = item.AnimInfo.numberOfFrames - 1;
item._iAnimFlag = false;
}
Expand All @@ -3679,7 +3679,7 @@ void SpawnRewardItem(_item_indexes itemid, Point position, bool sendmsg)
int curlv = ItemsGetCurrlevel();
GetItemAttrs(item, itemid, curlv);
item.setNewAnimation(true);
item._iSelFlag = 2;
item.selectionRegion = SelectionRegion::Middle;
item._iPostDraw = true;
item._iIdentified = true;
GenerateNewSeed(item);
Expand Down Expand Up @@ -3711,9 +3711,9 @@ void RespawnItem(Item &item, bool flipFlag)
item._iRequest = false;

if (IsAnyOf(item._iCurs, ICURS_MAGIC_ROCK, ICURS_TAVERN_SIGN, ICURS_ANVIL_OF_FURY))
item._iSelFlag = 1;
item.selectionRegion = SelectionRegion::Bottom;
else if (IsAnyOf(item._iCurs, ICURS_MAP_OF_THE_STARS, ICURS_RUNE_BOMB, ICURS_THEODORE, ICURS_AURIC_AMULET))
item._iSelFlag = 2;
item.selectionRegion = SelectionRegion::Middle;

if (item._iCurs == ICURS_MAGIC_ROCK) {
PlaySfxLoc(ItemDropSnds[it], item.position);
Expand Down Expand Up @@ -3745,9 +3745,9 @@ void ProcessItems()
continue;
item.AnimInfo.processAnimation();
if (item._iCurs == ICURS_MAGIC_ROCK) {
if (item._iSelFlag == 1 && item.AnimInfo.currentFrame == 10)
if (item.selectionRegion == SelectionRegion::Bottom && item.AnimInfo.currentFrame == 10)
item.AnimInfo.currentFrame = 0;
if (item._iSelFlag == 2 && item.AnimInfo.currentFrame == 20)
if (item.selectionRegion == SelectionRegion::Middle && item.AnimInfo.currentFrame == 20)
item.AnimInfo.currentFrame = 10;
} else {
if (item.AnimInfo.currentFrame == (item.AnimInfo.numberOfFrames - 1) / 2)
Expand All @@ -3756,7 +3756,7 @@ void ProcessItems()
if (item.AnimInfo.isLastFrame()) {
item.AnimInfo.currentFrame = item.AnimInfo.numberOfFrames - 1;
item._iAnimFlag = false;
item._iSelFlag = 1;
item.selectionRegion = SelectionRegion::Bottom;
}
}
}
Expand Down Expand Up @@ -4639,7 +4639,7 @@ int ItemNoFlippy()
int r = ActiveItems[ActiveItemCount - 1];
Items[r].AnimInfo.currentFrame = Items[r].AnimInfo.numberOfFrames - 1;
Items[r]._iAnimFlag = false;
Items[r]._iSelFlag = 1;
Items[r].selectionRegion = SelectionRegion::Bottom;

return r;
}
Expand Down Expand Up @@ -4766,11 +4766,11 @@ void Item::setNewAnimation(bool showAnimation)
_iRequest = false;
if (showAnimation) {
_iAnimFlag = true;
_iSelFlag = 0;
selectionRegion = SelectionRegion::None;
} else {
AnimInfo.currentFrame = AnimInfo.numberOfFrames - 1;
_iAnimFlag = false;
_iSelFlag = 1;
selectionRegion = SelectionRegion::Bottom;
}
}

Expand Down
5 changes: 3 additions & 2 deletions Source/items.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <optional>

#include "DiabloUI/ui_flags.hpp"
#include "cursor.h"
#include "engine.h"
#include "engine/animationinfo.h"
#include "engine/point.hpp"
Expand Down Expand Up @@ -188,7 +189,7 @@ struct Item {
*/
AnimationInfo AnimInfo;
bool _iDelFlag = false; // set when item is flagged for deletion, deprecated in 1.02
uint8_t _iSelFlag = 0;
SelectionRegion selectionRegion = SelectionRegion::None;
bool _iPostDraw = false;
bool _iIdentified = false;
item_quality _iMagical = ITEM_QUALITY_NORMAL;
Expand Down Expand Up @@ -525,7 +526,7 @@ void RecreateItem(const Player &player, Item &item, _item_indexes idx, uint16_t
void RecreateEar(Item &item, uint16_t ic, uint32_t iseed, uint8_t bCursval, std::string_view heroName);
void CornerstoneSave();
void CornerstoneLoad(Point position);
void SpawnQuestItem(_item_indexes itemid, Point position, int randarea, int selflag, bool sendmsg);
void SpawnQuestItem(_item_indexes itemid, Point position, int randarea, SelectionRegion selectionRegion, bool sendmsg);
void SpawnRewardItem(_item_indexes itemid, Point position, bool sendmsg);
void SpawnMapOfDoom(Point position, bool sendmsg);
void SpawnRuneBomb(Point position, bool sendmsg);
Expand Down
2 changes: 1 addition & 1 deletion Source/levels/themes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ void Theme_Library(int t)
Object *bookstand = AddObject(OBJ_BOOKSTAND, { xp, yp });
if (!FlipCoin(2 * librnd[leveltype - 1])) {
if (bookstand != nullptr) {
bookstand->_oSelFlag = 0;
bookstand->selectionRegion = SelectionRegion::None;
bookstand->_oAnimFrame += 2;
}
}
Expand Down
8 changes: 4 additions & 4 deletions Source/loadsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ void LoadItemData(LoadHelper &file, Item &item)
item.AnimInfo.currentFrame = file.NextLENarrow<int32_t, int8_t>(-1);
file.Skip(8); // Skip _iAnimWidth and _iAnimWidth2
file.Skip(4); // Unused since 1.02
item._iSelFlag = file.NextLE<uint8_t>();
item.selectionRegion = static_cast<SelectionRegion>(file.NextLE<uint8_t>());
file.Skip(3); // Alignment
item._iPostDraw = file.NextBool32();
item._iIdentified = file.NextBool32();
Expand Down Expand Up @@ -842,7 +842,7 @@ void LoadObject(LoadHelper &file, Object &object)
object._oSolidFlag = file.NextBool32();
object._oMissFlag = file.NextBool32();

object._oSelFlag = file.NextLE<int8_t>();
object.selectionRegion = static_cast<SelectionRegion>(file.NextLE<int8_t>());
file.Skip(3); // Alignment
object._oPreFlag = file.NextBool32();
object._oTrapFlag = file.NextBool32();
Expand Down Expand Up @@ -1094,7 +1094,7 @@ void SaveItem(SaveHelper &file, const Item &item)
// write _iAnimWidth2 for vanilla compatibility
file.WriteLE<int32_t>(CalculateWidth2(ItemAnimWidth));
file.Skip<uint32_t>(); // _delFlag, unused since 1.02
file.WriteLE<uint8_t>(item._iSelFlag);
file.WriteLE<uint8_t>(static_cast<uint8_t>(item.selectionRegion));
file.Skip(3); // Alignment
file.WriteLE<uint32_t>(item._iPostDraw ? 1 : 0);
file.WriteLE<uint32_t>(item._iIdentified ? 1 : 0);
Expand Down Expand Up @@ -1626,7 +1626,7 @@ void SaveObject(SaveHelper &file, const Object &object)
file.WriteLE<uint32_t>(object._oSolidFlag ? 1 : 0);
file.WriteLE<uint32_t>(object._oMissFlag ? 1 : 0);

file.WriteLE<int8_t>(object._oSelFlag);
file.WriteLE<int8_t>(static_cast<uint8_t>(object.selectionRegion));
file.Skip(3); // Alignment
file.WriteLE<uint32_t>(object._oPreFlag ? 1 : 0);
file.WriteLE<uint32_t>(object._oTrapFlag ? 1 : 0);
Expand Down
Loading

0 comments on commit e949f41

Please sign in to comment.