From 65bae536c6a6756ff802a250846f905de731dc51 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Tue, 11 Feb 2025 15:12:27 -0600 Subject: [PATCH] optionalize `dfCursor` and `dfSelection` This switches these two objects to a `std::optional`-wrapped `Crd3D` and switches logic for detecting invalid coordinates to point of initialization instead of point of use --- GUI.cpp | 30 +++++++++++++++++++----------- GameState.h | 4 ++-- MapLoading.cpp | 8 ++++---- TrackingModes.cpp | 8 ++++---- UserInput.cpp | 6 +++--- WorldSegment.cpp | 2 +- commonTypes.h | 25 +++++++++++++++++++++++++ 7 files changed, 58 insertions(+), 25 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index 6610d762..19718a4f 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -510,9 +510,9 @@ namespace void drawSelectionCursor(WorldSegment* segment) { auto& ssConfig = stonesenseState.ssConfig; - Crd3D& selection = segment->segState.dfSelection; - if ((selection.x != -30000 && ssConfig.config.follow_DFcursor)) { - drawCursorAt(segment, selection, uiColor(3)); + auto selection = segment->segState.dfSelection; + if (selection && ssConfig.config.follow_DFcursor) { + drawCursorAt(segment, *selection, uiColor(3)); } else { return; @@ -521,8 +521,9 @@ namespace void drawDebugCursor(WorldSegment* segment) { - Crd3D& cursor = segment->segState.dfCursor; - drawCursorAt(segment, cursor, uiColor(2)); + auto& cursor = segment->segState.dfCursor; + if (cursor) + drawCursorAt(segment, *cursor, uiColor(2)); } void drawAdvmodeMenuTalk(const ALLEGRO_FONT* font, int x, int y) @@ -562,18 +563,25 @@ namespace auto fontHeight = al_get_font_line_height(font); auto& contentLoader = stonesenseState.contentLoader; + if (!segment->segState.dfCursor) + { + draw_textf_border(font, uiColor(1), 2, (10 * fontHeight), 0, + "Coord: invalid"); + return; + } + //get tile info Tile* b = segment->getTile( - segment->segState.dfCursor.x, - segment->segState.dfCursor.y, - segment->segState.dfCursor.z); + segment->segState.dfCursor->x, + segment->segState.dfCursor->y, + segment->segState.dfCursor->z); int i = 10; if (b) { draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, "Tile 0x%x (%i,%i,%i)", b, b->x, b->y, b->z); } draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, - "Coord:(%i,%i,%i)", segment->segState.dfCursor.x, segment->segState.dfCursor.y, segment->segState.dfCursor.z); + "Coord:(%i,%i,%i)", segment->segState.dfCursor->x, segment->segState.dfCursor->y, segment->segState.dfCursor->z); if (!b) { return; @@ -947,8 +955,8 @@ void paintboard() } if(ssConfig.config.follow_DFcursor && ssConfig.config.debug_mode) { top += fontHeight; - if(segment->segState.dfCursor.x != -30000) { - draw_textf_border(font, uiColor(1), ssState.ScreenW/2,top, ALLEGRO_ALIGN_CENTRE, "Following DF Cursor at: %d,%d,%d", segment->segState.dfCursor.x,segment->segState.dfCursor.y,segment->segState.dfCursor.z); + if(segment->segState.dfCursor) { + draw_textf_border(font, uiColor(1), ssState.ScreenW/2,top, ALLEGRO_ALIGN_CENTRE, "Following DF Cursor at: %d,%d,%d", segment->segState.dfCursor->x,segment->segState.dfCursor->y,segment->segState.dfCursor->z); } } if(ssConfig.single_layer_view) { diff --git a/GameState.h b/GameState.h index 4bcd3a3e..ca3178b3 100644 --- a/GameState.h +++ b/GameState.h @@ -15,9 +15,9 @@ struct GameState{ Crd3D RegionDim; //position of the cursor - Crd3D dfCursor; + OptCrd3D dfCursor; //position of the selection cursor - Crd3D dfSelection; + OptCrd3D dfSelection; //the width and height of the stonesense window int ScreenW; diff --git a/MapLoading.cpp b/MapLoading.cpp index e97788f2..4793cdfc 100644 --- a/MapLoading.cpp +++ b/MapLoading.cpp @@ -947,10 +947,10 @@ void read_segment( void *arg) auto& ssState = stonesenseState.ssState; //read cursor if (stonesenseState.ssConfig.config.follow_DFcursor) { - DFHack::Gui::getCursorCoords(ssState.dfCursor.x, ssState.dfCursor.y, ssState.dfCursor.z); - ssState.dfSelection.x = df::global::selection_rect->start_x; - ssState.dfSelection.y = df::global::selection_rect->start_y; - ssState.dfSelection.z = df::global::selection_rect->start_z; + df::coord t; + DFHack::Gui::getCursorCoords(t); + ssState.dfCursor = t; + ssState.dfSelection = { df::global::selection_rect->start_x, df::global::selection_rect->start_y, df::global::selection_rect->start_z }; } if (firstLoad || stonesenseState.ssConfig.config.track_mode != Config::TRACKING_NONE) { diff --git a/TrackingModes.cpp b/TrackingModes.cpp index 68eb2f1e..2ee409b2 100644 --- a/TrackingModes.cpp +++ b/TrackingModes.cpp @@ -28,10 +28,10 @@ void followCurrentDFFocus() auto& ssConfig = stonesenseState.ssConfig; auto& ssState = stonesenseState.ssState; - if(ssState.dfCursor.x != -30000) { - ssState.Position.x = ssState.dfCursor.x - (ssState.Size.x / 2) + ssConfig.config.viewOffset.x; - ssState.Position.y = ssState.dfCursor.y - (ssState.Size.y / 2) + ssConfig.config.viewOffset.y; - ssState.Position.z = ssState.dfCursor.z + ssConfig.config.viewOffset.z + 1; + if(ssState.dfCursor) { + ssState.Position.x = ssState.dfCursor->x - (ssState.Size.x / 2) + ssConfig.config.viewOffset.x; + ssState.Position.y = ssState.dfCursor->y - (ssState.Size.y / 2) + ssConfig.config.viewOffset.y; + ssState.Position.z = ssState.dfCursor->z + ssConfig.config.viewOffset.z + 1; } else { followCurrentDFCenter(); } diff --git a/UserInput.cpp b/UserInput.cpp index 170c8780..77bcda81 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -201,9 +201,9 @@ void doMouse() tiley = tiley + ssState.Position.y; tilez = tilez + ssState.Position.z - 1; - ssState.dfCursor.x = tilex; - ssState.dfCursor.y = tiley; - ssState.dfCursor.z = tilez; + ssState.dfCursor->x = tilex; + ssState.dfCursor->y = tiley; + ssState.dfCursor->z = tilez; } stonesenseState.timeToReloadSegment = true; } diff --git a/WorldSegment.cpp b/WorldSegment.cpp index b1071da5..b83a7380 100644 --- a/WorldSegment.cpp +++ b/WorldSegment.cpp @@ -8,7 +8,7 @@ const GameState SegmentWrap::zeroState = { - {0,0,0},0,{0,0,0},{0,0,0},{0,0,0},0,0 + {0,0,0},0,{0,0,0},{0,0,0},{},{},0 }; void WorldSegment::CorrectTileForSegmentOffset(int32_t& xin, int32_t& yin, int32_t& zin) diff --git a/commonTypes.h b/commonTypes.h index 60657981..8156d1df 100644 --- a/commonTypes.h +++ b/commonTypes.h @@ -81,6 +81,7 @@ struct t_SpriteWithOffset { struct Crd2D { int32_t x,y; }; + struct Crd3D { int32_t x,y,z; constexpr Crd3D operator+(const Crd3D rhs) @@ -89,6 +90,30 @@ struct Crd3D { } }; +struct OptCrd3D : public std::optional +{ + operator df::coord() const { + return has_value() ? df::coord{ uint16_t(value().x), uint16_t(value().y), uint16_t(value().z) } : df::coord{}; + } + OptCrd3D() {}; + OptCrd3D(const df::coord& c) { + *this = c; + } + OptCrd3D(const int x, const int y, const int z) + { + if (x > 0 && y > 0 && z > 0) + emplace(x, y, z); + else + reset(); + } + OptCrd3D& operator= (const df::coord& c) { + if (c.isValid()) + emplace(c.x, c.y, c.z); + else + reset(); + return *this; + } +}; class dfColors {