Skip to content

Commit 556c1d2

Browse files
Add functions for picking and tracking objects
1 parent 3ea34ac commit 556c1d2

2 files changed

Lines changed: 129 additions & 0 deletions

File tree

libs/s25main/ingameWindows/iwObservate.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,29 @@
1919
#include "gameData/const_gui_ids.h"
2020
#include <cmath>
2121

22+
#include "PointOutput.h"
23+
#include <iostream>
24+
25+
namespace {
2226
const Extent SmallWndSize(260, 190);
2327
const Extent MediumWndSize(300, 250);
2428
const Extent BigWndSize(340, 310);
2529

30+
// Make (ab-)use of CheckPointsInRadius() easier
31+
constexpr bool CheckPointsBreak = false;
32+
constexpr bool CheckPointsContinue = true;
33+
}
34+
35+
bool PickedMovableObject::HasExpired() const
36+
{
37+
return VIDEODRIVER.GetTickCount() > expiration;
38+
}
39+
40+
void PickedMovableObject::ExpireIn(unsigned long ticks)
41+
{
42+
expiration = VIDEODRIVER.GetTickCount() + ticks;
43+
}
44+
2645
iwObservate::iwObservate(GameWorldView& gwv, const MapPoint selectedPt)
2746
: IngameWindow(CGI_OBSERVATION, IngameWindow::posAtMouse, SmallWndSize, _("Observation window"), nullptr, false,
2847
CloseBehavior::NoRightClick),
@@ -270,3 +289,92 @@ bool iwObservate::Msg_RightUp(const MouseCoords& /*mc*/)
270289

271290
return true;
272291
}
292+
293+
bool iwObservate::PickMovableObject(const GameWorldView& gwv, PickedMovableObject& pmo, MapPoint mapPt,
294+
DrawPoint drawPt)
295+
{
296+
unsigned i = 1;
297+
298+
const auto offset = gwv.GetOffset();
299+
const auto center = gwv.GetSize() / 2.f;
300+
const auto zoomFactor = gwv.GetZoomFactor();
301+
const auto& world = gwv.GetWorld();
302+
const auto worldSize = world.GetSize() * DrawPoint(TR_W, TR_H);
303+
auto minDistance = std::numeric_limits<float>::max();
304+
305+
pmo.movable = nullptr;
306+
307+
world.CheckPointsInRadius(mapPt, 2, [&](MapPoint curPt, unsigned) {
308+
if(gwv.GetViewer().GetVisibility(curPt) != Visibility::Visible)
309+
return CheckPointsContinue;
310+
311+
DrawPoint curDrawPt = world.GetNodePos(curPt);
312+
if(curDrawPt.x < offset.x)
313+
curDrawPt.x += worldSize.x;
314+
if(curDrawPt.y < offset.y)
315+
curDrawPt.y += worldSize.y;
316+
curDrawPt -= offset;
317+
for(const noBase& obj : world.GetFigures(curPt))
318+
{
319+
const auto* movable = dynamic_cast<const noMovable*>(&obj);
320+
if(!movable)
321+
continue;
322+
323+
DrawPoint objDrawPt = curDrawPt;
324+
if(movable->IsMoving())
325+
objDrawPt += movable->CalcWalkingRelative();
326+
objDrawPt = DrawPoint((objDrawPt - center) * zoomFactor + center);
327+
328+
// DEBUG REMOVE BEFORE MERGE
329+
dskGameInterface::SetDebugPoint(i++, objDrawPt, 8, 4, MakeColor(255, 255, 0, 255));
330+
331+
auto diff = Point<float>(objDrawPt - drawPt);
332+
float distance = std::sqrt(diff.x * diff.x + diff.y * diff.y);
333+
if(distance < minDistance)
334+
{
335+
pmo.movable = movable;
336+
pmo.pt = curPt;
337+
minDistance = distance;
338+
}
339+
}
340+
341+
return CheckPointsContinue;
342+
}, true);
343+
344+
return pmo.IsValid();
345+
}
346+
347+
bool iwObservate::PickMovableObjectAtCursor(const GameWorldView& gwv, PickedMovableObject& pmo)
348+
{
349+
return PickMovableObject(gwv, pmo, gwv.GetSelectedPt(), DrawPoint(VIDEODRIVER.GetMousePos()));
350+
}
351+
352+
bool iwObservate::TrackPickedMovableObject(const GameWorldView& gwv, PickedMovableObject& pmo)
353+
{
354+
const auto& world = gwv.GetWorld();
355+
bool result = false;
356+
world.CheckPointsInRadius(pmo.pt, 2, [&](MapPoint curPt, unsigned) {
357+
if(gwv.GetViewer().GetVisibility(curPt) != Visibility::Visible)
358+
return CheckPointsContinue;
359+
360+
for(const noBase& obj : world.GetFigures(curPt))
361+
{
362+
const auto* movable = dynamic_cast<const noMovable*>(&obj);
363+
if(pmo.movable == movable)
364+
{
365+
pmo.pt = curPt;
366+
result = true;
367+
return CheckPointsBreak;
368+
}
369+
}
370+
return CheckPointsContinue;
371+
}, true);
372+
373+
if(!result)
374+
{
375+
pmo.movable = nullptr;
376+
pmo.expiration = 0;
377+
}
378+
379+
return result;
380+
}

libs/s25main/ingameWindows/iwObservate.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@
99

1010
class GameWorldView;
1111
class MouseCoords;
12+
class noMovable;
13+
14+
struct PickedMovableObject
15+
{
16+
static constexpr unsigned long EXPIRATION = 5000;
17+
18+
PickedMovableObject() = default;
19+
20+
bool IsValid() const { return movable != nullptr; }
21+
bool HasExpired() const;
22+
23+
void ExpireIn(unsigned long ticks);
24+
25+
const noMovable* movable = nullptr;
26+
MapPoint pt{};
27+
unsigned long expiration = 0;
28+
};
1229

1330
/// Observing window (shows a part of the world in an extra window)
1431
class iwObservate : public IngameWindow
@@ -31,6 +48,10 @@ class iwObservate : public IngameWindow
3148
unsigned followMovableId;
3249

3350
public:
51+
static bool PickMovableObject(const GameWorldView& gwv, PickedMovableObject& pmo, MapPoint mapPt, DrawPoint drawPt);
52+
static bool PickMovableObjectAtCursor(const GameWorldView& gwv, PickedMovableObject& pmo);
53+
static bool TrackPickedMovableObject(const GameWorldView& gwv, PickedMovableObject& pmo);
54+
3455
iwObservate(GameWorldView& gwv, MapPoint selectedPt);
3556

3657
private:

0 commit comments

Comments
 (0)