|
19 | 19 | #include "gameData/const_gui_ids.h" |
20 | 20 | #include <cmath> |
21 | 21 |
|
| 22 | +#include "PointOutput.h" |
| 23 | +#include <iostream> |
| 24 | + |
| 25 | +namespace { |
22 | 26 | const Extent SmallWndSize(260, 190); |
23 | 27 | const Extent MediumWndSize(300, 250); |
24 | 28 | const Extent BigWndSize(340, 310); |
25 | 29 |
|
| 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 | + |
26 | 45 | iwObservate::iwObservate(GameWorldView& gwv, const MapPoint selectedPt) |
27 | 46 | : IngameWindow(CGI_OBSERVATION, IngameWindow::posAtMouse, SmallWndSize, _("Observation window"), nullptr, false, |
28 | 47 | CloseBehavior::NoRightClick), |
@@ -270,3 +289,92 @@ bool iwObservate::Msg_RightUp(const MouseCoords& /*mc*/) |
270 | 289 |
|
271 | 290 | return true; |
272 | 291 | } |
| 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 | +} |
0 commit comments