Bugfix:
(1) Add function
Code: Select all
int GetRowAtTile(int viewport_y, Point tile);
(2) Remove the static keyword for this function in viewport.cpp
(3) Add an include for viewport_func.h in smallmap_gui.cpp
(4) Replace function smallMapCenterOnCurrentPos in smallmap_gui.cpp as follows:
Code: Select all
void SmallMapCenterOnCurrentPos()
{
// Goal: Given the viewport coordinates of the middle of the map window, find
// out which tile is displayed there.
// First find out which tile would be there if we ignore height
const ViewPort *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
Point pt = InverseRemapCoords(vp->virtual_left + vp->virtual_width / 2, vp->virtual_top + vp->virtual_height / 2);
Point ptWithoutHeight = {pt.x / TILE_SIZE, pt.y / TILE_SIZE};
// Problem: There are mountains. So the tile actually displayed at the given position
// might be the high mountain of 30 tiles south.
// Unfortunately, there is no closed formula for finding such a tile.
// We call GetRowAtTile originally implemented for the viewport code, which performs
// a interval search. For details, see its documentation.
int rowWithoutHeight = ptWithoutHeight.x + ptWithoutHeight.y;
int rowWithHeight = GetRowAtTile(vp->virtual_top + vp->virtual_height / 2, ptWithoutHeight);
int rowOffset = rowWithHeight - rowWithoutHeight;
Point ptWithHeight = {ptWithoutHeight.x + rowOffset / 2, ptWithoutHeight.y + rowOffset / 2};
// And finally scroll to that position.
int sub;
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(SM_WIDGET_MAP);
Point sxy = this->ComputeScroll(ptWithHeight.x, ptWithHeight.y,
max(0, (int)wid->current_x / 2 - 2), wid->current_y / 2, &sub);
this->SetNewScroll(sxy.x, sxy.y, sub);
this->SetDirty();
}