Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
84 changes: 75 additions & 9 deletions GUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,23 +524,88 @@ namespace

void drawSelectionCursor(WorldSegment* segment)
{
auto& ssConfig = stonesenseState.ssConfig;
auto selection = segment->segState.dfSelection;
if (selection && ssConfig.config.follow_DFcursor) {
if (selection) {
drawCursorAt(segment, *selection, uiColor(dfColors::lgreen));
}
else {
return;
}
}

void drawDebugCursor(WorldSegment* segment)
{
void drawMainCursor(WorldSegment* segment) {
auto& cursor = segment->segState.dfCursor;
if (cursor)
drawCursorAt(segment, *cursor, uiColor(dfColors::yellow));
drawCursorAt(segment, *cursor, uiColor(dfColors::lblue));
}

void drawRulerTooltip(WorldSegment* segment) {
auto& font = stonesenseState.font;
auto fontHeight = al_get_font_line_height(font);

OptCrd3D p1 = segment->segState.dfCursor;
OptCrd3D p2 = segment->segState.dfSelection;
OptCrd3D ruler = {
std::abs(p1->x - p2->x) + 1,
std::abs(p1->y - p2->y) + 1,
std::abs(p1->z - p2->z) + 1
};
if (p2) {
df::coord mouseCoord = DFHack::Gui::getMousePos();
Crd3D mousePos = { mouseCoord.x, mouseCoord.y, mouseCoord.z };
segment->CorrectTileForSegmentOffset(mousePos.x, mousePos.y, mousePos.z);
segment->CorrectTileForSegmentRotation(mousePos.x, mousePos.y, mousePos.z);
Crd2D mousePoint = LocalTileToScreen(mousePos.x, mousePos.y, mousePos.z);
draw_text_border(
font, uiColor(dfColors::white),
mousePoint.x + al_get_text_width(font, "------"),
mousePoint.y + fontHeight, ALLEGRO_ALIGN_LEFT,
(
std::to_string(ruler->x) + "x" +
std::to_string(ruler->y) + "x" +
std::to_string(ruler->z)).c_str());
}
}

void drawVolume(WorldSegment* segment) {
OptCrd3D p1 = segment->segState.dfCursor;
OptCrd3D p2 = segment->segState.dfSelection;
if (p1 && p2) {
int minX = std::min(p1->x, p2->x), maxX = std::max(p1->x, p2->x);
int minY = std::min(p1->y, p2->y), maxY = std::max(p1->y, p2->y);
int minZ = std::min(p1->z, p2->z), maxZ = std::max(p1->z, p2->z);

ALLEGRO_COLOR fadeColor = al_map_rgba(0, 0, 0, 0); // Fully transparent black

for (int x = minX; x <= maxX; ++x) {
for (int y = minY; y <= maxY; ++y) {
for (int z = minZ; z <= maxZ; ++z) {
int edgeCount = 0;
if (x == minX || x == maxX) edgeCount++;
if (y == minY || y == maxY) edgeCount++;
if (z == minZ || z == maxZ) edgeCount++;

if (edgeCount >= 2) { // Only draw points on edges
// Compute fade effect based on distance from the highest Z point
int maxFadeDistance = std::max(10, (maxZ - minZ));

auto fadePercent = ((std::max(p1->z, p2->z) - z) * 100) / maxFadeDistance; // Closer = lower fade

// Blend between base color and fade color
auto baseColor = uiColor(dfColors::yellow);
ALLEGRO_COLOR finalColor = partialBlend(baseColor, fadeColor, fadePercent);

Crd3D point = { x, y, z };
drawCursorAt(segment, point, finalColor);
}
}
}
}
drawRulerTooltip(segment);
}
}


void drawAdvmodeMenuTalk(const ALLEGRO_FONT* font, int x, int y)
{
//df::adventure * menu = df::global::adventure;
Expand Down Expand Up @@ -919,6 +984,11 @@ void paintboard()
stonesenseState.stoneSenseTimers.frame_total.update(donetime - stonesenseState.stoneSenseTimers.prev_frame_time);
stonesenseState.stoneSenseTimers.prev_frame_time = donetime;


drawVolume(segment);
drawSelectionCursor(segment);
drawMainCursor(segment);

if (ssConfig.show_announcements) {
al_hold_bitmap_drawing(true);
draw_announcements(font, ssState.ScreenW, ssState.ScreenH - 10 - al_get_font_line_height(font), ALLEGRO_ALIGN_RIGHT, df::global::world->status.announcements);
Expand All @@ -944,10 +1014,6 @@ void paintboard()
al_hold_bitmap_drawing(true);
draw_textf_border(font, uiColor(dfColors::white), 10,fontHeight, 0, "%i,%i,%i, r%i, z%i", ssState.Position.x,ssState.Position.y,ssState.Position.z, ssState.Rotation, ssConfig.zoom);

drawSelectionCursor(segment);

drawDebugCursor(segment);

drawAdvmodeMenuTalk(font, 5, ssState.ScreenH - 5);

if(ssConfig.config.debug_mode) {
Expand Down
7 changes: 4 additions & 3 deletions MapLoading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -946,10 +946,11 @@ void read_segment( void *arg)

auto& ssState = stonesenseState.ssState;
//read cursor
if (stonesenseState.ssConfig.config.follow_DFcursor) {
ssState.dfCursor = DFHack::Gui::getCursorPos();
ssState.dfSelection = OptCrd3D { df::global::selection_rect->start_x, df::global::selection_rect->start_y, df::global::selection_rect->start_z };
df::coord mouseTemp = DFHack::Gui::getMousePos();
if (mouseTemp.isValid()) {
ssState.dfCursor = { mouseTemp.x, mouseTemp.y, mouseTemp.z };
}
ssState.dfSelection = OptCrd3D { 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) {
firstLoad = 0;
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Template for new versions:
# Future

## New Features
- `stonesense`: Stonesense now shows a selection rectangle much like DF does and also a cursor following DF's mouse position

## Fixes
- `stonesense`: megashots no longer leave stonesense unresponsive
Expand Down
Loading