Browse Source

Add Object lookup method to mimic map::at()

pull/5144/head
ephphatha 4 years ago committed by Anders Jenbo
parent
commit
0ce76a3f13
  1. 2
      Source/controls/plrctrls.cpp
  2. 6
      Source/cursor.cpp
  3. 4
      Source/debug.cpp
  4. 2
      Source/engine/path.cpp
  5. 2
      Source/engine/render/scrollrt.cpp
  6. 22
      Source/levels/setmaps.cpp
  7. 6
      Source/missiles.cpp
  8. 6
      Source/msg.cpp
  9. 22
      Source/objects.cpp
  10. 16
      Source/objects.h
  11. 6
      Source/player.cpp

2
Source/controls/plrctrls.cpp

@ -178,7 +178,7 @@ void FindItemOrObject()
}
for (Point targetPosition : searchArea) {
Object *object = ObjectAtPosition(targetPosition);
Object *object = FindObjectAtPosition(targetPosition);
if (object == nullptr || object->_oSelFlag == 0) {
// No object or non-interactive object
continue;

6
Source/cursor.cpp

@ -612,18 +612,18 @@ void CheckCursMove()
// No monsters or players under the cursor, try find an object starting with the tile below the current tile (tall
// objects like doors)
Point testPosition = currentTile + Direction::South;
Object *object = ObjectAtPosition(testPosition);
Object *object = FindObjectAtPosition(testPosition);
if (object == nullptr || object->_oSelFlag < 2) {
// Either no object or can't interact from the test position, try the current tile
testPosition = currentTile;
object = ObjectAtPosition(testPosition);
object = FindObjectAtPosition(testPosition);
if (object == nullptr || IsNoneOf(object->_oSelFlag, 1, 3)) {
// 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 = currentTile + (flipflag ? Direction::SouthWest : Direction::SouthEast);
object = ObjectAtPosition(testPosition);
object = FindObjectAtPosition(testPosition);
if (object != nullptr && object->_oSelFlag < 2) {
// Found an object but it's not in range, clear the pointer

4
Source/debug.cpp

@ -334,7 +334,7 @@ std::string ExportDun(const string_view parameter)
for (int y = 16; y < MAXDUNY - 16; y++) {
for (int x = 16; x < MAXDUNX - 16; x++) {
uint16_t objectId = 0;
Object *object = ObjectAtPosition({ x, y }, false);
Object *object = FindObjectAtPosition({ x, y }, false);
if (object != nullptr) {
for (int i = 0; i < 147; i++) {
if (ObjTypeConv[i] == object->_otype) {
@ -1077,7 +1077,7 @@ bool GetDebugGridText(Point dungeonCoords, char *debugGridTextBuffer)
return true;
case DebugGridTextItem::objectindex: {
info = 0;
Object *object = ObjectAtPosition(dungeonCoords);
Object *object = FindObjectAtPosition(dungeonCoords);
if (object != nullptr) {
info = static_cast<int>(object->_otype);
}

2
Source/engine/path.cpp

@ -327,7 +327,7 @@ bool IsTileSolid(Point position)
bool IsTileWalkable(Point position, bool ignoreDoors)
{
Object *object = ObjectAtPosition(position);
Object *object = FindObjectAtPosition(position);
if (object != nullptr) {
if (ignoreDoors && object->IsDoor()) {
return true;

2
Source/engine/render/scrollrt.cpp

@ -603,7 +603,7 @@ void DrawObject(const Surface &out, Point tilePosition, Point targetBufferPositi
return;
}
Object *object = ObjectAtPosition(tilePosition);
Object *object = FindObjectAtPosition(tilePosition);
if (object == nullptr) {
return;
}

22
Source/levels/setmaps.cpp

@ -33,29 +33,29 @@ namespace {
void AddSKingObjs()
{
constexpr Rectangle SmallSecretRoom { { 20, 7 }, { 3, 3 } };
ObjectAtPosition({ 64, 34 })->InitializeLoadedObject(SmallSecretRoom, 1);
ObjectAtPosition({ 64, 34 }).InitializeLoadedObject(SmallSecretRoom, 1);
constexpr Rectangle Gate { { 20, 14 }, { 1, 2 } };
ObjectAtPosition({ 64, 59 })->InitializeLoadedObject(Gate, 2);
ObjectAtPosition({ 64, 59 }).InitializeLoadedObject(Gate, 2);
constexpr Rectangle LargeSecretRoom { { 8, 1 }, { 7, 10 } };
ObjectAtPosition({ 27, 37 })->InitializeLoadedObject(LargeSecretRoom, 3);
ObjectAtPosition({ 46, 35 })->InitializeLoadedObject(LargeSecretRoom, 3);
ObjectAtPosition({ 49, 53 })->InitializeLoadedObject(LargeSecretRoom, 3);
ObjectAtPosition({ 27, 53 })->InitializeLoadedObject(LargeSecretRoom, 3);
ObjectAtPosition({ 27, 37 }).InitializeLoadedObject(LargeSecretRoom, 3);
ObjectAtPosition({ 46, 35 }).InitializeLoadedObject(LargeSecretRoom, 3);
ObjectAtPosition({ 49, 53 }).InitializeLoadedObject(LargeSecretRoom, 3);
ObjectAtPosition({ 27, 53 }).InitializeLoadedObject(LargeSecretRoom, 3);
}
void AddSChamObjs()
{
ObjectAtPosition({ 37, 30 })->InitializeLoadedObject({ { 17, 0 }, { 4, 5 } }, 1);
ObjectAtPosition({ 37, 46 })->InitializeLoadedObject({ { 13, 0 }, { 3, 5 } }, 2);
ObjectAtPosition({ 37, 30 }).InitializeLoadedObject({ { 17, 0 }, { 4, 5 } }, 1);
ObjectAtPosition({ 37, 46 }).InitializeLoadedObject({ { 13, 0 }, { 3, 5 } }, 2);
}
void AddVileObjs()
{
ObjectAtPosition({ 26, 45 })->InitializeLoadedObject({ { 1, 1 }, { 8, 9 } }, 1);
ObjectAtPosition({ 45, 46 })->InitializeLoadedObject({ { 11, 1 }, { 9, 9 } }, 2);
ObjectAtPosition({ 35, 36 })->InitializeLoadedObject({ { 7, 11 }, { 6, 7 } }, 3);
ObjectAtPosition({ 26, 45 }).InitializeLoadedObject({ { 1, 1 }, { 8, 9 } }, 1);
ObjectAtPosition({ 45, 46 }).InitializeLoadedObject({ { 11, 1 }, { 9, 9 } }, 2);
ObjectAtPosition({ 35, 36 }).InitializeLoadedObject({ { 7, 11 }, { 6, 7 } }, 3);
}
void SetMapTransparency(const char *path)

6
Source/missiles.cpp

@ -439,7 +439,7 @@ void CheckMissileCol(Missile &missile, int minDamage, int maxDamage, bool isDama
}
if (IsMissileBlockedByTile({ mx, my })) {
Object *object = ObjectAtPosition({ mx, my });
Object *object = FindObjectAtPosition({ mx, my });
if (object != nullptr && object->IsBreakable()) {
BreakObjectMissile(*object);
}
@ -686,7 +686,7 @@ bool IsMissileBlockedByTile(Point tile)
return true;
}
Object *object = ObjectAtPosition(tile);
Object *object = FindObjectAtPosition(tile);
// _oMissFlag is true if the object allows missiles to pass through so we need to invert the check here...
return object != nullptr && !object->_oMissFlag;
}
@ -2844,7 +2844,7 @@ void MI_Lightball(Missile &missile)
missile._mirange = j;
if (missile.position.tile == targetPosition) {
Object *object = ObjectAtPosition(targetPosition);
Object *object = FindObjectAtPosition(targetPosition);
if (object != nullptr && object->IsShrine()) {
missile._mirange = j;
}

6
Source/msg.cpp

@ -1222,7 +1222,7 @@ size_t OnObjectTileAction(const TCmd &cmd, Player &player, action_id action, boo
{
const auto &message = reinterpret_cast<const TCmdLoc &>(cmd);
const Point position { message.x, message.y };
const Object *object = ObjectAtPosition(position);
const Object *object = FindObjectAtPosition(position);
if (gbBufferMsgs != 1 && player.isOnActiveLevel() && object != nullptr) {
if (pathToObject)
@ -1641,7 +1641,7 @@ size_t OnPlayerDamage(const TCmd *pCmd, Player &player)
size_t OnOperateObject(const TCmd &pCmd, int pnum)
{
const auto &message = reinterpret_cast<const TCmdLoc &>(pCmd);
Object *object = ObjectAtPosition({ message.x, message.y });
Object *object = FindObjectAtPosition({ message.x, message.y });
if (gbBufferMsgs == 1) {
SendPacket(pnum, &message, sizeof(message));
@ -1658,7 +1658,7 @@ size_t OnOperateObject(const TCmd &pCmd, int pnum)
size_t OnBreakObject(const TCmd &pCmd, int pnum)
{
const auto &message = reinterpret_cast<const TCmdLoc &>(pCmd);
Object *breakable = ObjectAtPosition({ message.x, message.y });
Object *breakable = FindObjectAtPosition({ message.x, message.y });
if (gbBufferMsgs == 1) {
SendPacket(pnum, &message, sizeof(message));

22
Source/objects.cpp

@ -569,7 +569,7 @@ void AddObjTraps()
rndv = 25;
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) {
Object *triggerObject = ObjectAtPosition({ i, j }, false);
Object *triggerObject = FindObjectAtPosition({ i, j }, false);
if (triggerObject == nullptr || GenerateRnd(100) >= rndv)
continue;
@ -611,7 +611,7 @@ void AddChestTraps()
{
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) { // NOLINT(modernize-loop-convert)
Object *chestObject = ObjectAtPosition({ i, j }, false);
Object *chestObject = FindObjectAtPosition({ i, j }, false);
if (chestObject != nullptr && chestObject->IsUntrappedChest() && GenerateRnd(100) < 10) {
switch (chestObject->_otype) {
case OBJ_CHEST1:
@ -2192,7 +2192,7 @@ void OperateBook(Player &player, Object &book)
if (doAddMissile) {
questObject._oVar6 = 4;
ObjectAtPosition({ 35, 36 })->_oVar5++;
ObjectAtPosition({ 35, 36 })._oVar5++;
AddMissile(player.position.tile, target, Direction::South, MIS_RNDTELEPORT, TARGET_BOTH, player.getId(), 0, 0);
missileAdded = true;
}
@ -3813,7 +3813,7 @@ void BreakBarrel(const Player &player, Object &barrel, bool forcebreak, bool sen
PlayerMHit(dPlayer[xp][yp] - 1, nullptr, 0, 8, 16, MIS_FIREBOLT, false, 0, &unused);
}
// don't really need to exclude large objects as explosive barrels are single tile objects, but using considerLargeObjects == false as this matches the old logic.
Object *adjacentObject = ObjectAtPosition({ xp, yp }, false);
Object *adjacentObject = FindObjectAtPosition({ xp, yp }, false);
if (adjacentObject != nullptr && adjacentObject->isExplosive() && !adjacentObject->IsBroken()) {
BreakBarrel(player, *adjacentObject, true, sendmsg);
}
@ -4001,7 +4001,7 @@ bool Object::IsDisabled() const
return IsAnyOf(static_cast<shrine_type>(_oVar1), shrine_type::ShrineFascinating, shrine_type::ShrineOrnate, shrine_type::ShrineSacred);
}
Object *ObjectAtPosition(Point position, bool considerLargeObjects)
Object *FindObjectAtPosition(Point position, bool considerLargeObjects)
{
if (!InDungeonBounds(position)) {
return nullptr;
@ -4019,21 +4019,21 @@ Object *ObjectAtPosition(Point position, bool considerLargeObjects)
bool IsItemBlockingObjectAtPosition(Point position)
{
Object *object = ObjectAtPosition(position);
Object *object = FindObjectAtPosition(position);
if (object != nullptr && object->_oSolidFlag) {
// solid object
return true;
}
object = ObjectAtPosition(position + Direction::South);
object = FindObjectAtPosition(position + Direction::South);
if (object != nullptr && object->_oSelFlag != 0) {
// An unopened container or breakable object exists which potentially overlaps this tile, the player might not be able to pick up an item dropped here.
return true;
}
object = ObjectAtPosition(position + Direction::SouthEast, false);
object = FindObjectAtPosition(position + Direction::SouthEast, false);
if (object != nullptr) {
Object *otherDoor = ObjectAtPosition(position + Direction::SouthWest, false);
Object *otherDoor = FindObjectAtPosition(position + Direction::SouthWest, false);
if (otherDoor != nullptr && object->_oSelFlag != 0 && otherDoor->_oSelFlag != 0) {
// Two interactive objects potentially overlap both sides of this tile, as above the player might not be able to pick up an item which is dropped here.
return true;
@ -4533,7 +4533,7 @@ void OperateTrap(Object &trap)
if (trap._oVar4 != 0)
return;
Object &trigger = *ObjectAtPosition({ trap._oVar1, trap._oVar2 });
Object &trigger = ObjectAtPosition({ trap._oVar1, trap._oVar2 });
switch (trigger._otype) {
case OBJ_L1LDOOR:
case OBJ_L1RDOOR:
@ -4685,7 +4685,7 @@ void RedoPlayerVision()
void MonstCheckDoors(const Monster &monster)
{
for (Direction dir : { Direction::NorthEast, Direction::SouthWest, Direction::North, Direction::East, Direction::South, Direction::West, Direction::NorthWest, Direction::SouthEast }) {
Object *object = ObjectAtPosition(monster.position.tile + dir);
Object *object = FindObjectAtPosition(monster.position.tile + dir);
if (object == nullptr)
continue;

16
Source/objects.h

@ -265,7 +265,7 @@ extern bool LoadingMapObjects;
* this param to false if you only want the object whose base position matches this tile
* @return A pointer to the object or nullptr if no object exists at this location
*/
Object *ObjectAtPosition(Point position, bool considerLargeObjects = true);
Object *FindObjectAtPosition(Point position, bool considerLargeObjects = true);
/**
* @brief Check whether an item occupies this tile position
@ -274,7 +274,19 @@ Object *ObjectAtPosition(Point position, bool considerLargeObjects = true);
*/
inline bool IsObjectAtPosition(Point position)
{
return ObjectAtPosition(position) != nullptr;
return FindObjectAtPosition(position) != nullptr;
}
/**
* @brief Get a reference to the object located at this tile
*
* This function is unchecked. Trying to access an invalid position will result in out of bounds memory access
* @param position The map coordinate of the object
* @return a reference to the object
*/
inline Object &ObjectAtPosition(Point position)
{
return Objects[abs(dObject[position.x][position.y]) - 1];
}
/**

6
Source/player.cpp

@ -1057,7 +1057,7 @@ bool DoAttack(Player &player)
} else if (PlayerAtPosition(position) != nullptr && !player.friendlyMode) {
didhit = PlrHitPlr(player, *PlayerAtPosition(position));
} else {
Object *object = ObjectAtPosition(position, false);
Object *object = FindObjectAtPosition(position, false);
if (object != nullptr) {
didhit = PlrHitObj(player, *object);
}
@ -1321,7 +1321,7 @@ bool IsPlayerAdjacentToObject(Player &player, Object &object)
{
int x = abs(player.position.tile.x - object.position.x);
int y = abs(player.position.tile.y - object.position.y);
if (y > 1 && object.position.y >= 1 && ObjectAtPosition(object.position + Direction::NorthEast) == &object) {
if (y > 1 && object.position.y >= 1 && FindObjectAtPosition(object.position + Direction::NorthEast) == &object) {
// special case for activating a large object from the north-east side
y = abs(player.position.tile.y - object.position.y + 1);
}
@ -1341,7 +1341,7 @@ void TryDisarm(const Player &player, Object &object)
}
for (int j = 0; j < ActiveObjectCount; j++) {
Object &trap = Objects[ActiveObjects[j]];
if (trap.IsTrap() && ObjectAtPosition({ trap._oVar1, trap._oVar2 }) == &object) {
if (trap.IsTrap() && FindObjectAtPosition({ trap._oVar1, trap._oVar2 }) == &object) {
trap._oVar4 = 1;
object._oTrapFlag = false;
}

Loading…
Cancel
Save