Skip to content

Commit

Permalink
Pick object to follow early
Browse files Browse the repository at this point in the history
Pick the object to follow when the activity window is shown.
  • Loading branch information
falbrechtskirchinger committed Jul 19, 2023
1 parent 4ad9671 commit cc1a1a4
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 73 deletions.
16 changes: 14 additions & 2 deletions libs/s25main/ingameWindows/iwAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ iwAction::iwAction(GameInterface& gi, GameWorldView& gwv, const Tabs& tabs, MapP
curPos.x += btSize.x;
group->AddImageButton(4, curPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 107),
_("Notify allies of this location"));

// try to pick a movable object at the cursor now, in case the user activates the observation window later
if(iwObservate::PickMovableObjectAtCursor(gwv, pickedObject_))
pickedObject_.ExpireIn(PickedMovableObject::EXPIRATION);
}

main_tab->SetSelection(0, true);
Expand Down Expand Up @@ -706,8 +710,7 @@ void iwAction::Msg_ButtonClick_TabWatch(const unsigned ctrl_id)
switch(ctrl_id)
{
case 1:
// TODO: bestimen, was an der position selected ist
WINDOWMANAGER.Show(std::make_unique<iwObservate>(gwv, selectedPt));
WINDOWMANAGER.Show(std::make_unique<iwObservate>(gwv, selectedPt, pickedObject_));
DisableMousePosResetOnClose();
Close();
break;
Expand All @@ -731,3 +734,12 @@ void iwAction::DisableMousePosResetOnClose()
{
mousePosAtOpen_ = DrawPoint::Invalid();
}

void iwAction::Draw_()
{
IngameWindow::Draw_();

// track picked object for a while
if(pickedObject_.IsValid() && !pickedObject_.HasExpired())
iwObservate::TrackPickedMovableObject(gwv, pickedObject_);
}
5 changes: 5 additions & 0 deletions libs/s25main/ingameWindows/iwAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

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

PickedMovableObject pickedObject_;

public:
iwAction(GameInterface& gi, GameWorldView& gwv, const Tabs& tabs, MapPoint selectedPt, const DrawPoint& mousePos,
Params params, bool military_buildings);
Expand Down Expand Up @@ -98,4 +101,6 @@ class iwAction : public IngameWindow
void AddAttackControls(ctrlGroup* group, unsigned attackers_count);
void AddUpgradeRoad(ctrlGroup* group, unsigned& x, unsigned& width);
bool DoUpgradeRoad();

void Draw_() override;
};
114 changes: 47 additions & 67 deletions libs/s25main/ingameWindows/iwObservate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
#include "Loader.h"
#include "Settings.h"
#include "WindowManager.h"
#include "controls/ctrlButton.h"
#include "controls/ctrlImageButton.h"
#include "desktops/dskGameInterface.h"
#include "driver/MouseCoords.h"
#include "drivers/VideoDriverWrapper.h"
#include "ogl/glArchivItem_Bitmap.h"
Expand Down Expand Up @@ -43,13 +45,13 @@ void PickedMovableObject::ExpireIn(unsigned long ticks)
expiration = VIDEODRIVER.GetTickCount() + ticks;
}

iwObservate::iwObservate(GameWorldView& gwv, const MapPoint selectedPt)
iwObservate::iwObservate(GameWorldView& gwv, const MapPoint selectedPt, const PickedMovableObject& pmo)
: IngameWindow(CGI_OBSERVATION, IngameWindow::posAtMouse, SmallWndSize, _("Observation window"), nullptr, false,
CloseBehavior::NoRightClick),
parentView(gwv),
view(new GameWorldView(gwv.GetViewer(), Position(GetDrawPos() * DrawPoint(10, 15)), GetSize() - Extent::all(20))),
selectedPt(selectedPt), lastWindowPos(Point<unsigned short>::Invalid()), isScrolling(false), zoomLvl(0),
followMovableId(0)
pickedObject(pmo)
{
view->MoveToMapPt(selectedPt);
view->SetZoomFactor(1.9f, false);
Expand All @@ -61,7 +63,9 @@ iwObservate::iwObservate(GameWorldView& gwv, const MapPoint selectedPt)
AddImageButton(1, btPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 36), _("Zoom"));
// Kamera (Folgen): 43
btPos.x += btSize.x;
AddImageButton(2, btPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 43), _("Follow object"));
auto* button = AddImageButton(2, btPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 43), _("Follow object"));
if(pickedObject.IsValid() && !pickedObject.HasExpired())
button->SetTooltip((boost::format(_("Follow %s")) % typeid(*pickedObject.movable).name()).str());
// Zum Ort
btPos.x += btSize.x;
AddImageButton(3, btPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 107), _("Go to place"));
Expand Down Expand Up @@ -90,50 +94,29 @@ void iwObservate::Msg_ButtonClick(const unsigned ctrl_id)
break;
case 2:
{
if(followMovableId)
followMovableId = 0;
if(followingObject)
followingObject = false;
else
{
const DrawPoint centerDrawPt = DrawPoint(view->GetSize() / 2u);

double minDistance = std::numeric_limits<double>::max();

for(int y = view->GetFirstPt().y; y <= view->GetLastPt().y; ++y)
if(pickedObject.IsValid() && !pickedObject.HasExpired())
// start following currently picked object
followingObject = true;
else
{
for(int x = view->GetFirstPt().x; x <= view->GetLastPt().x; ++x)
{
Position curOffset;
const MapPoint curPt =
view->GetViewer().GetTerrainRenderer().ConvertCoords(Position(x, y), &curOffset);
DrawPoint curDrawPt = view->GetWorld().GetNodePos(curPt) - view->GetOffset() + curOffset;

if(view->GetViewer().GetVisibility(curPt) != Visibility::Visible)
continue;

for(const noBase& obj : view->GetWorld().GetFigures(curPt))
{
const auto* movable = dynamic_cast<const noMovable*>(&obj);
if(!movable)
continue;

DrawPoint objDrawPt = curDrawPt;

if(movable->IsMoving())
objDrawPt += movable->CalcWalkingRelative();

DrawPoint diffToCenter = objDrawPt - centerDrawPt;
double distance = sqrt(pow(diffToCenter.x, 2) + pow(diffToCenter.y, 2));

if(distance < minDistance)
{
followMovableId = movable->GetObjId();
minDistance = distance;
}
}
}
// pick new object at center of view
const auto& world = view->GetWorld();
const auto centerMapPt = world.MakeMapPoint((view->GetFirstPt() + view->GetLastPt()) / 2);
const auto centerDrawPt = DrawPoint(view->GetSize() / 2u);
followingObject = PickMovableObject(*view, pickedObject, centerMapPt, centerDrawPt);
}
}

auto* button = GetCtrl<ctrlImageButton>(2);
if(followingObject)
button->SetTooltip(
(boost::format(_("Stop following %s")) % typeid(*pickedObject.movable).name()).str());
else
button->SetTooltip(_("Follow object"));
break;
}
case 3:
Expand Down Expand Up @@ -179,10 +162,17 @@ void iwObservate::Draw_()
lastWindowPos = GetPos();
}

if(followMovableId)
if(followingObject)
{
if(!MoveToFollowedObj())
followMovableId = 0;
followingObject = false;
} else if(pickedObject.IsValid())
{
if(!TrackPickedMovableObject(*view, pickedObject) || pickedObject.HasExpired())
{
auto* button = GetCtrl<ctrlImageButton>(2);
button->SetTooltip(_("Follow object"));
}
}

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

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

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

bool iwObservate::MoveToFollowedObj()
{
// First look around the center (figure is normally still there)
const GameWorldBase& world = view->GetWorld();
const MapPoint centerPt = world.MakeMapPoint((view->GetFirstPt() + view->GetLastPt()) / 2);
const std::vector<MapPoint> centerPts = world.GetPointsInRadiusWithCenter(centerPt, 2);
for(const MapPoint& curPt : centerPts)
{
if(MoveToFollowedObj(curPt))
return true;
}

// Not at the center (normally due to lags) -> Check full area
for(int y = view->GetFirstPt().y; y <= view->GetLastPt().y; ++y)
{
for(int x = view->GetFirstPt().x; x <= view->GetLastPt().x; ++x)
{
const MapPoint curPt = world.MakeMapPoint(Position(x, y));
if(MoveToFollowedObj(curPt))
return true;
}
}
return false;
const auto& world = view->GetWorld();
const auto centerPt = world.MakeMapPoint((view->GetFirstPt() + view->GetLastPt()) / 2);
bool result = false;
world.CheckPointsInRadius(centerPt, 3, [&, this](MapPoint curPt, unsigned) {
result = MoveToFollowedObj(curPt);
if(result)
return CheckPointsBreak;
return CheckPointsContinue;
}, true);
return result;
}

bool iwObservate::MoveToFollowedObj(const MapPoint ptToCheck)
{
const auto id = pickedObject.movable->GetObjId();
if(view->GetViewer().GetVisibility(ptToCheck) != Visibility::Visible)
return false;
for(const noBase& obj : view->GetWorld().GetFigures(ptToCheck))
{
if(obj.GetObjId() == followMovableId)
if(obj.GetObjId() == id)
{
const auto& followMovable = static_cast<const noMovable&>(obj);
DrawPoint drawPt = view->GetWorld().GetNodePos(ptToCheck);
Expand Down Expand Up @@ -272,7 +252,7 @@ bool iwObservate::Msg_RightDown(const MouseCoords& mc)
scrollOrigin = mc.GetPos();

isScrolling = true;
followMovableId = 0;
followingObject = false;
WINDOWMANAGER.SetCursor(Cursor::Scroll);
} else
{
Expand Down
8 changes: 4 additions & 4 deletions libs/s25main/ingameWindows/iwObservate.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class noMovable;

struct PickedMovableObject
{
static constexpr unsigned long EXPIRATION = 5000;
static constexpr unsigned long EXPIRATION = 6000;

PickedMovableObject() = default;

Expand Down Expand Up @@ -44,15 +44,15 @@ class iwObservate : public IngameWindow

unsigned zoomLvl;

/// id of object currently followed or INVALID_ID
unsigned followMovableId;
PickedMovableObject pickedObject;
bool followingObject = false;

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

iwObservate(GameWorldView& gwv, MapPoint selectedPt);
iwObservate(GameWorldView& gwv, MapPoint selectedPt, const PickedMovableObject& pmo);

private:
void Draw_() override;
Expand Down

0 comments on commit cc1a1a4

Please sign in to comment.