Skip to content

Commit cc1a1a4

Browse files
Pick object to follow early
Pick the object to follow when the activity window is shown.
1 parent 4ad9671 commit cc1a1a4

File tree

4 files changed

+70
-73
lines changed

4 files changed

+70
-73
lines changed

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"
@@ -43,13 +45,13 @@ void PickedMovableObject::ExpireIn(unsigned long ticks)
4345
expiration = VIDEODRIVER.GetTickCount() + ticks;
4446
}
4547

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

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

182-
if(followMovableId)
165+
if(followingObject)
183166
{
184167
if(!MoveToFollowedObj())
185-
followMovableId = 0;
168+
followingObject = false;
169+
} else if(pickedObject.IsValid())
170+
{
171+
if(!TrackPickedMovableObject(*view, pickedObject) || pickedObject.HasExpired())
172+
{
173+
auto* button = GetCtrl<ctrlImageButton>(2);
174+
button->SetTooltip(_("Follow object"));
175+
}
186176
}
187177

188178
if(!IsMinimized())
@@ -192,7 +182,7 @@ void iwObservate::Draw_()
192182

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

@@ -201,36 +191,26 @@ void iwObservate::Draw_()
201191

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

227206
bool iwObservate::MoveToFollowedObj(const MapPoint ptToCheck)
228207
{
208+
const auto id = pickedObject.movable->GetObjId();
229209
if(view->GetViewer().GetVisibility(ptToCheck) != Visibility::Visible)
230210
return false;
231211
for(const noBase& obj : view->GetWorld().GetFigures(ptToCheck))
232212
{
233-
if(obj.GetObjId() == followMovableId)
213+
if(obj.GetObjId() == id)
234214
{
235215
const auto& followMovable = static_cast<const noMovable&>(obj);
236216
DrawPoint drawPt = view->GetWorld().GetNodePos(ptToCheck);
@@ -272,7 +252,7 @@ bool iwObservate::Msg_RightDown(const MouseCoords& mc)
272252
scrollOrigin = mc.GetPos();
273253

274254
isScrolling = true;
275-
followMovableId = 0;
255+
followingObject = false;
276256
WINDOWMANAGER.SetCursor(Cursor::Scroll);
277257
} else
278258
{

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)