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
202192bool 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
227206bool 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 {
0 commit comments