diff --git a/Source/engine/displacement.hpp b/Source/engine/displacement.hpp index 53741f2d0..4a1cad9db 100644 --- a/Source/engine/displacement.hpp +++ b/Source/engine/displacement.hpp @@ -3,6 +3,7 @@ #include #include "direction.hpp" +#include "size.hpp" #include "utils/stdcompat/abs.hpp" namespace devilution { @@ -11,6 +12,20 @@ struct Displacement { int deltaX; int deltaY; + Displacement() = default; + + constexpr Displacement(int deltaX, int deltaY) + : deltaX(deltaX) + , deltaY(deltaY) + { + } + + explicit constexpr Displacement(const Size &size) + : deltaX(size.width) + , deltaY(size.height) + { + } + constexpr bool operator==(const Displacement &other) const { return deltaX == other.deltaX && deltaY == other.deltaY; diff --git a/Source/objects.cpp b/Source/objects.cpp index d00787435..d51cc303e 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -509,7 +509,7 @@ void AddBookLever(int x1, int y1, int x2, int y2, _speech_id msg) AddObject(OBJ_BLOODBOOK, { xp, yp }); } int ob = dObject[xp][yp] - 1; - SetObjMapRange(ob, x1, y1, x2, y2, leverid); + Objects[ob].SetMapRange({ x1, y1 }, { x2, y2 }, leverid); SetBookMsg(ob, msg); leverid++; Objects[ob]._oVar6 = Objects[ob]._oAnimFrame + 1; @@ -748,7 +748,7 @@ void LoadMapObjects(const char *path, Point start, Rectangle mapRange, int lever if (objectId != 0) { Point mapPos = start + Displacement { i, j }; AddObject(ObjTypeConv[objectId], mapPos); - SetObjMapRange(ObjIndex(mapPos), mapRange.position.x, mapRange.position.y, mapRange.position.x + mapRange.size.width, mapRange.position.y + mapRange.size.height, leveridx); + ObjectAtPosition(mapPos).SetMapRange(mapRange, leveridx); } } } @@ -1247,15 +1247,6 @@ void SetupObject(int i, Point position, _object_id ot) Objects[i]._oDoorFlag = false; } -void SetObjMapRange(int i, int x1, int y1, int x2, int y2, int v) -{ - Objects[i]._oVar1 = x1; - Objects[i]._oVar2 = y1; - Objects[i]._oVar3 = x2; - Objects[i]._oVar4 = y2; - Objects[i]._oVar8 = v; -} - void SetBookMsg(int i, _speech_id msg) { Objects[i]._oVar7 = msg; diff --git a/Source/objects.h b/Source/objects.h index 5aee1f02f..da852f038 100644 --- a/Source/objects.h +++ b/Source/objects.h @@ -8,6 +8,7 @@ #include #include "engine/point.hpp" +#include "engine/rectangle.hpp" #include "itemdat.h" #include "objdat.h" #include "textdat.h" @@ -49,6 +50,36 @@ struct ObjectStruct { uint32_t _oVar6; _speech_id _oVar7; int _oVar8; + + /** + * @brief Marks the map region to be refreshed when the player interacts with the object. + * + * Some objects will cause a map region to change when a player interacts with them (e.g. Skeleton King + * antechamber levers). The coordinates used for this region are based on a 40*40 grid overlaying the central + * 80*80 region of the dungeon. + * + * @param topLeft corner of the map region closest to the origin + * @param bottomRight corner of the map region furthest from the origin + * @param v ID/discriminator for the object type? Needs to be investigated further + */ + constexpr void SetMapRange(Point topLeft, Point bottomRight, int v) + { + _oVar1 = topLeft.x; + _oVar2 = topLeft.y; + _oVar3 = bottomRight.x; + _oVar4 = bottomRight.y; + _oVar8 = v; + } + + /** + * @brief Convenience function for SetMapRange(Point, Point, int) + * @param mapRange A rectangle defining the top left corner and size of the affected region + * @param v Object subtype/discriminator + */ + constexpr void SetMapRange(Rectangle mapRange, int v) + { + SetMapRange(mapRange.position, mapRange.position + Displacement { mapRange.size }, v); + } }; extern ObjectStruct Objects[MAXOBJECTS]; @@ -64,7 +95,6 @@ void AddL1Objs(int x1, int y1, int x2, int y2); void AddL2Objs(int x1, int y1, int x2, int y2); void InitObjects(); void SetMapObjects(const uint16_t *dunData, int startx, int starty); -void SetObjMapRange(int i, int x1, int y1, int x2, int y2, int v); void SetBookMsg(int i, _speech_id msg); void GetRndObjLoc(int randarea, int *xx, int *yy); void AddMushPatch(); diff --git a/Source/setmaps.cpp b/Source/setmaps.cpp index 574650268..1efad8ac9 100644 --- a/Source/setmaps.cpp +++ b/Source/setmaps.cpp @@ -82,37 +82,37 @@ const char *const QuestLevelNames[] = { N_("Archbishop Lazarus' Lair"), }; -int ObjIndex(Point position) +ObjectStruct &ObjectAtPosition(Point position) { for (int i = 0; i < ActiveObjectCount; i++) { int oi = ActiveObjects[i]; if (Objects[oi].position == position) - return oi; + return Objects[oi]; } - app_fatal("ObjIndex: Active object not found at (%i,%i)", position.x, position.y); + app_fatal("ObjectAtPosition: Active object not found at (%i,%i)", position.x, position.y); } void AddSKingObjs() { - SetObjMapRange(ObjIndex({ 64, 34 }), 20, 7, 23, 10, 1); - SetObjMapRange(ObjIndex({ 64, 59 }), 20, 14, 21, 16, 2); - SetObjMapRange(ObjIndex({ 27, 37 }), 8, 1, 15, 11, 3); - SetObjMapRange(ObjIndex({ 46, 35 }), 8, 1, 15, 11, 3); - SetObjMapRange(ObjIndex({ 49, 53 }), 8, 1, 15, 11, 3); - SetObjMapRange(ObjIndex({ 27, 53 }), 8, 1, 15, 11, 3); + ObjectAtPosition({ 64, 34 }).SetMapRange({ 20, 7 }, { 23, 10 }, 1); + ObjectAtPosition({ 64, 59 }).SetMapRange({ 20, 14 }, { 21, 16 }, 2); + ObjectAtPosition({ 27, 37 }).SetMapRange({ 8, 1 }, { 15, 11 }, 3); + ObjectAtPosition({ 46, 35 }).SetMapRange({ 8, 1 }, { 15, 11 }, 3); + ObjectAtPosition({ 49, 53 }).SetMapRange({ 8, 1 }, { 15, 11 }, 3); + ObjectAtPosition({ 27, 53 }).SetMapRange({ 8, 1 }, { 15, 11 }, 3); } void AddSChamObjs() { - SetObjMapRange(ObjIndex({ 37, 30 }), 17, 0, 21, 5, 1); - SetObjMapRange(ObjIndex({ 37, 46 }), 13, 0, 16, 5, 2); + ObjectAtPosition({ 37, 30 }).SetMapRange({ 17, 0 }, { 21, 5 }, 1); + ObjectAtPosition({ 37, 46 }).SetMapRange({ 13, 0 }, { 16, 5 }, 2); } void AddVileObjs() { - SetObjMapRange(ObjIndex({ 26, 45 }), 1, 1, 9, 10, 1); - SetObjMapRange(ObjIndex({ 45, 46 }), 11, 1, 20, 10, 2); - SetObjMapRange(ObjIndex({ 35, 36 }), 7, 11, 13, 18, 3); + ObjectAtPosition({ 26, 45 }).SetMapRange({ 1, 1 }, { 9, 10 }, 1); + ObjectAtPosition({ 45, 46 }).SetMapRange({ 11, 1 }, { 20, 10 }, 2); + ObjectAtPosition({ 35, 36 }).SetMapRange({ 7, 11 }, { 13, 18 }, 3); } void DRLG_SetMapTrans(const char *path) diff --git a/Source/setmaps.h b/Source/setmaps.h index 34df9af62..f9aeefac0 100644 --- a/Source/setmaps.h +++ b/Source/setmaps.h @@ -6,16 +6,18 @@ #pragma once #include "engine.h" +#include "engine/point.hpp" +#include "objects.h" namespace devilution { /** - * @brief Find the index of an object given a point in map coordinates + * @brief Find an object given a point in map coordinates * * @param position The map coordinate to test - * @return The index of the object at the given position + * @return A reference to the object */ -int ObjIndex(Point position); +ObjectStruct &ObjectAtPosition(Point position); void LoadSetMap(); /* rdata */