Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draw a mimicry of DF's selection rectangle and tooltip #213

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
87 changes: 77 additions & 10 deletions GUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ void DrawCurrentLevelOutline(bool backPart)

namespace
{
void drawCursorAt(WorldSegment* segment, Crd3D& cursor, const ALLEGRO_COLOR& color)
void drawCursorAt(WorldSegment* segment, Crd3D cursor, const ALLEGRO_COLOR& color)
{
auto& ssConfig = stonesenseState.ssConfig;
segment->CorrectTileForSegmentOffset(cursor.x, cursor.y, cursor.z);
Expand All @@ -509,22 +509,88 @@ 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));
if (selection.x >= 0) {
drawCursorAt(segment, selection, uiColor(4));
}
else {
return;
}
}

void drawDebugCursor(WorldSegment* segment)
void drawMainCursor(WorldSegment* segment)
{
Crd3D& cursor = segment->segState.dfCursor;
drawCursorAt(segment, cursor, uiColor(2));
drawCursorAt(segment, cursor, uiColor(3));
}

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

Crd3D p1 = segment->segState.dfCursor;
Crd3D p2 = segment->segState.dfSelection;
Crd3D ruler = {
std::abs(p1.x - p2.x) + 1,
std::abs(p1.y - p2.y) + 1,
std::abs(p1.z - p2.z) + 1
};
if (p2.x >= 0) {
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(1),
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) {
Crd3D p1 = segment->segState.dfCursor;
Crd3D p2 = segment->segState.dfSelection;
if (p1.x >= 0 && p2.x >= 0) {
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(2);
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 @@ -896,6 +962,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 @@ -921,10 +992,6 @@ void paintboard()
al_hold_bitmap_drawing(true);
draw_textf_border(font, uiColor(1), 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
12 changes: 6 additions & 6 deletions MapLoading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -946,12 +946,12 @@ 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 mouseTemp = DFHack::Gui::getMousePos();
ssState.dfCursor = { mouseTemp.x, mouseTemp.y, mouseTemp.z };
DFHack::Gui::getDesignationCoords(
ssState.dfSelection.x,
ssState.dfSelection.y,
ssState.dfSelection.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