Skip to content

Commit 621841d

Browse files
Pick object to follow early
Pick the object to follow when the activity window is shown.
1 parent 556c1d2 commit 621841d

4 files changed

Lines changed: 70 additions & 73 deletions

File tree

libs/s25main/ingameWindows/iwAction.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ iwAction::iwAction(GameInterface& gi, GameWorldView& gwv, const Tabs& tabs, MapP
297297
curPos.x += btSize.x;
298298
group->AddImageButton(4, curPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 107),
299299
_("Notify allies of this location"));
300+
301+
// try to pick a movable object at the cursor now, in case the user activates the observation window later
302+
if(iwObservate::PickMovableObjectAtCursor(gwv, pickedObject_))
303+
pickedObject_.ExpireIn(PickedMovableObject::EXPIRATION);
300304
}
301305

302306
main_tab->SetSelection(0, true);
@@ -706,8 +710,7 @@ void iwAction::Msg_ButtonClick_TabWatch(const unsigned ctrl_id)
706710
switch(ctrl_id)
707711
{
708712
case 1:
709-
// TODO: bestimen, was an der position selected ist
710-
WINDOWMANAGER.Show(std::make_unique<iwObservate>(gwv, selectedPt));
713+
WINDOWMANAGER.Show(std::make_unique<iwObservate>(gwv, selectedPt, pickedObject_));
711714
DisableMousePosResetOnClose();
712715
Close();
713716
break;
@@ -731,3 +734,12 @@ void iwAction::DisableMousePosResetOnClose()
731734
{
732735
mousePosAtOpen_ = DrawPoint::Invalid();
733736
}
737+
738+
void iwAction::Draw_()
739+
{
740+
IngameWindow::Draw_();
741+
742+
// track picked object for a while
743+
if(pickedObject_.IsValid() && !pickedObject_.HasExpired())
744+
iwObservate::TrackPickedMovableObject(gwv, pickedObject_);
745+
}

libs/s25main/ingameWindows/iwAction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include "IngameWindow.h"
8+
#include "ingameWindows/iwObservate.h"
89
#include "gameTypes/MapCoordinates.h"
910
#include <boost/variant.hpp>
1011
#include <array>
@@ -69,6 +70,8 @@ class iwAction : public IngameWindow
6970
/// Die einzelnen Höhen für die einzelnen Tabs im Bautab
7071
std::array<unsigned short, 4> building_tab_heights;
7172

73+
PickedMovableObject pickedObject_;
74+
7275
public:
7376
iwAction(GameInterface& gi, GameWorldView& gwv, const Tabs& tabs, MapPoint selectedPt, const DrawPoint& mousePos,
7477
Params params, bool military_buildings);
@@ -98,4 +101,6 @@ class iwAction : public IngameWindow
98101
void AddAttackControls(ctrlGroup* group, unsigned attackers_count);
99102
void AddUpgradeRoad(ctrlGroup* group, unsigned& x, unsigned& width);
100103
bool DoUpgradeRoad();
104+
105+
void Draw_() override;
101106
};

libs/s25main/ingameWindows/iwObservate.cpp

Lines changed: 47 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
#include "Loader.h"
88
#include "Settings.h"
99
#include "WindowManager.h"
10+
#include "controls/ctrlButton.h"
1011
#include "controls/ctrlImageButton.h"
12+
#include "desktops/dskGameInterface.h"
1113
#include "driver/MouseCoords.h"
1214
#include "drivers/VideoDriverWrapper.h"
1315
#include "ogl/glArchivItem_Bitmap.h"
@@ -42,13 +44,13 @@ void PickedMovableObject::ExpireIn(unsigned long ticks)
4244
expiration = VIDEODRIVER.GetTickCount() + ticks;
4345
}
4446

45-
iwObservate::iwObservate(GameWorldView& gwv, const MapPoint selectedPt)
47+
iwObservate::iwObservate(GameWorldView& gwv, const MapPoint selectedPt, const PickedMovableObject& pmo)
4648
: IngameWindow(CGI_OBSERVATION, IngameWindow::posAtMouse, SmallWndSize, _("Observation window"), nullptr, false,
4749
CloseBehavior::NoRightClick),
4850
parentView(gwv),
4951
view(new GameWorldView(gwv.GetViewer(), Position(GetDrawPos() * DrawPoint(10, 15)), GetSize() - Extent::all(20))),
5052
selectedPt(selectedPt), lastWindowPos(Point<unsigned short>::Invalid()), isScrolling(false), zoomLvl(0),
51-
followMovableId(0)
53+
pickedObject(pmo)
5254
{
5355
view->MoveToMapPt(selectedPt);
5456
view->SetZoomFactor(1.9f, false);
@@ -60,7 +62,9 @@ iwObservate::iwObservate(GameWorldView& gwv, const MapPoint selectedPt)
6062
AddImageButton(1, btPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 36), _("Zoom"));
6163
// Kamera (Folgen): 43
6264
btPos.x += btSize.x;
63-
AddImageButton(2, btPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 43), _("Follow object"));
65+
auto* button = AddImageButton(2, btPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 43), _("Follow object"));
66+
if(pickedObject.IsValid() && !pickedObject.HasExpired())
67+
button->SetTooltip((boost::format(_("Follow %s")) % typeid(*pickedObject.movable).name()).str());
6468
// Zum Ort
6569
btPos.x += btSize.x;
6670
AddImageButton(3, btPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 107), _("Go to place"));
@@ -89,50 +93,29 @@ void iwObservate::Msg_ButtonClick(const unsigned ctrl_id)
8993
break;
9094
case 2:
9195
{
92-
if(followMovableId)
93-
followMovableId = 0;
96+
if(followingObject)
97+
followingObject = false;
9498
else
9599
{
96-
const DrawPoint centerDrawPt = DrawPoint(view->GetSize() / 2u);
97-
98-
double minDistance = std::numeric_limits<double>::max();
99-
100-
for(int y = view->GetFirstPt().y; y <= view->GetLastPt().y; ++y)
100+
if(pickedObject.IsValid() && !pickedObject.HasExpired())
101+
// start following currently picked object
102+
followingObject = true;
103+
else
101104
{
102-
for(int x = view->GetFirstPt().x; x <= view->GetLastPt().x; ++x)
103-
{
104-
Position curOffset;
105-
const MapPoint curPt =
106-
view->GetViewer().GetTerrainRenderer().ConvertCoords(Position(x, y), &curOffset);
107-
DrawPoint curDrawPt = view->GetWorld().GetNodePos(curPt) - view->GetOffset() + curOffset;
108-
109-
if(view->GetViewer().GetVisibility(curPt) != Visibility::Visible)
110-
continue;
111-
112-
for(const noBase& obj : view->GetWorld().GetFigures(curPt))
113-
{
114-
const auto* movable = dynamic_cast<const noMovable*>(&obj);
115-
if(!movable)
116-
continue;
117-
118-
DrawPoint objDrawPt = curDrawPt;
119-
120-
if(movable->IsMoving())
121-
objDrawPt += movable->CalcWalkingRelative();
122-
123-
DrawPoint diffToCenter = objDrawPt - centerDrawPt;
124-
double distance = sqrt(pow(diffToCenter.x, 2) + pow(diffToCenter.y, 2));
125-
126-
if(distance < minDistance)
127-
{
128-
followMovableId = movable->GetObjId();
129-
minDistance = distance;
130-
}
131-
}
132-
}
105+
// pick new object at center of view
106+
const auto& world = view->GetWorld();
107+
const auto centerMapPt = world.MakeMapPoint((view->GetFirstPt() + view->GetLastPt()) / 2);
108+
const auto centerDrawPt = DrawPoint(view->GetSize() / 2u);
109+
followingObject = PickMovableObject(*view, pickedObject, centerMapPt, centerDrawPt);
133110
}
134111
}
135112

113+
auto* button = GetCtrl<ctrlImageButton>(2);
114+
if(followingObject)
115+
button->SetTooltip(
116+
(boost::format(_("Stop following %s")) % typeid(*pickedObject.movable).name()).str());
117+
else
118+
button->SetTooltip(_("Follow object"));
136119
break;
137120
}
138121
case 3:
@@ -178,10 +161,17 @@ void iwObservate::Draw_()
178161
lastWindowPos = GetPos();
179162
}
180163

181-
if(followMovableId)
164+
if(followingObject)
182165
{
183166
if(!MoveToFollowedObj())
184-
followMovableId = 0;
167+
followingObject = false;
168+
} else if(pickedObject.IsValid())
169+
{
170+
if(!TrackPickedMovableObject(*view, pickedObject) || pickedObject.HasExpired())
171+
{
172+
auto* button = GetCtrl<ctrlImageButton>(2);
173+
button->SetTooltip(_("Follow object"));
174+
}
185175
}
186176

187177
if(!IsMinimized())
@@ -191,7 +181,7 @@ void iwObservate::Draw_()
191181

192182
view->Draw(road, parentView.GetSelectedPt(), false);
193183
// Draw indicator for center point
194-
if(!followMovableId)
184+
if(followingObject)
195185
LOADER.GetMapTexture(23)->DrawFull(view->GetPos() + view->GetSize() / 2u);
196186
}
197187

@@ -200,36 +190,26 @@ void iwObservate::Draw_()
200190

201191
bool iwObservate::MoveToFollowedObj()
202192
{
203-
// First look around the center (figure is normally still there)
204-
const GameWorldBase& world = view->GetWorld();
205-
const MapPoint centerPt = world.MakeMapPoint((view->GetFirstPt() + view->GetLastPt()) / 2);
206-
const std::vector<MapPoint> centerPts = world.GetPointsInRadiusWithCenter(centerPt, 2);
207-
for(const MapPoint& curPt : centerPts)
208-
{
209-
if(MoveToFollowedObj(curPt))
210-
return true;
211-
}
212-
213-
// Not at the center (normally due to lags) -> Check full area
214-
for(int y = view->GetFirstPt().y; y <= view->GetLastPt().y; ++y)
215-
{
216-
for(int x = view->GetFirstPt().x; x <= view->GetLastPt().x; ++x)
217-
{
218-
const MapPoint curPt = world.MakeMapPoint(Position(x, y));
219-
if(MoveToFollowedObj(curPt))
220-
return true;
221-
}
222-
}
223-
return false;
193+
const auto& world = view->GetWorld();
194+
const auto centerPt = world.MakeMapPoint((view->GetFirstPt() + view->GetLastPt()) / 2);
195+
bool result = false;
196+
world.CheckPointsInRadius(centerPt, 3, [&, this](MapPoint curPt, unsigned) {
197+
result = MoveToFollowedObj(curPt);
198+
if(result)
199+
return CheckPointsBreak;
200+
return CheckPointsContinue;
201+
}, true);
202+
return result;
224203
}
225204

226205
bool iwObservate::MoveToFollowedObj(const MapPoint ptToCheck)
227206
{
207+
const auto id = pickedObject.movable->GetObjId();
228208
if(view->GetViewer().GetVisibility(ptToCheck) != Visibility::Visible)
229209
return false;
230210
for(const noBase& obj : view->GetWorld().GetFigures(ptToCheck))
231211
{
232-
if(obj.GetObjId() == followMovableId)
212+
if(obj.GetObjId() == id)
233213
{
234214
const auto& followMovable = static_cast<const noMovable&>(obj);
235215
DrawPoint drawPt = view->GetWorld().GetNodePos(ptToCheck);
@@ -271,7 +251,7 @@ bool iwObservate::Msg_RightDown(const MouseCoords& mc)
271251
scrollOrigin = mc.GetPos();
272252

273253
isScrolling = true;
274-
followMovableId = 0;
254+
followingObject = false;
275255
WINDOWMANAGER.SetCursor(Cursor::Scroll);
276256
} else
277257
{

libs/s25main/ingameWindows/iwObservate.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class noMovable;
1313

1414
struct PickedMovableObject
1515
{
16-
static constexpr unsigned long EXPIRATION = 5000;
16+
static constexpr unsigned long EXPIRATION = 6000;
1717

1818
PickedMovableObject() = default;
1919

@@ -44,15 +44,15 @@ class iwObservate : public IngameWindow
4444

4545
unsigned zoomLvl;
4646

47-
/// id of object currently followed or INVALID_ID
48-
unsigned followMovableId;
47+
PickedMovableObject pickedObject;
48+
bool followingObject = false;
4949

5050
public:
5151
static bool PickMovableObject(const GameWorldView& gwv, PickedMovableObject& pmo, MapPoint mapPt, DrawPoint drawPt);
5252
static bool PickMovableObjectAtCursor(const GameWorldView& gwv, PickedMovableObject& pmo);
5353
static bool TrackPickedMovableObject(const GameWorldView& gwv, PickedMovableObject& pmo);
5454

55-
iwObservate(GameWorldView& gwv, MapPoint selectedPt);
55+
iwObservate(GameWorldView& gwv, MapPoint selectedPt, const PickedMovableObject& pmo);
5656

5757
private:
5858
void Draw_() override;

0 commit comments

Comments
 (0)