Browse Source

Highlight stack on queue icon hovered

Dydzio 2 years ago
parent
commit
92754e22f0

+ 21 - 1
client/battle/BattleInterfaceClasses.cpp

@@ -807,8 +807,21 @@ int32_t StackQueue::getSiegeShooterIconID()
 	return owner.siegeController->getSiegedTown()->town->faction->getIndex();
 }
 
+boost::optional<uint32_t> StackQueue::getHoveredUnitIdIfAny() const
+{
+	for(const auto & stackBox : stackBoxes)
+	{
+		if(stackBox->hovered)
+		{
+			return stackBox->getBoundUnitID();
+		}
+	}
+
+	return boost::none;
+}
+
 StackQueue::StackBox::StackBox(StackQueue * owner):
-	owner(owner)
+	CIntObject(HOVER), owner(owner)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 	background = std::make_shared<CPicture>(owner->embedded ? "StackQueueSmall" : "StackQueueLarge");
@@ -838,6 +851,7 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
 {
 	if(unit)
 	{
+		boundUnitID = unit->unitId();
 		background->colorize(unit->unitOwner());
 		icon->visible = true;
 
@@ -872,6 +886,7 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
 	}
 	else
 	{
+		boundUnitID = boost::none;
 		background->colorize(PlayerColor::NEUTRAL);
 		icon->visible = false;
 		icon->setFrame(0);
@@ -881,3 +896,8 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
 			stateIcon->visible = false;
 	}
 }
+
+boost::optional<uint32_t> StackQueue::StackBox::getBoundUnitID() const
+{
+	return boundUnitID;
+}

+ 3 - 0
client/battle/BattleInterfaceClasses.h

@@ -196,6 +196,7 @@ class StackQueue : public CIntObject
 	class StackBox : public CIntObject
 	{
 		StackQueue * owner;
+		boost::optional<uint32_t> boundUnitID;
 	public:
 		std::shared_ptr<CPicture> background;
 		std::shared_ptr<CAnimImage> icon;
@@ -204,6 +205,7 @@ class StackQueue : public CIntObject
 
 		void setUnit(const battle::Unit * unit, size_t turn = 0);
 		StackBox(StackQueue * owner);
+		boost::optional<uint32_t> getBoundUnitID() const;
 	};
 
 	static const int QUEUE_SIZE = 10;
@@ -220,6 +222,7 @@ public:
 
 	StackQueue(bool Embedded, BattleInterface & owner);
 	void update();
+	boost::optional<uint32_t> getHoveredUnitIdIfAny() const;
 
 	void show(SDL_Surface * to) override;
 };

+ 6 - 0
client/battle/BattleStacksController.cpp

@@ -897,6 +897,12 @@ std::vector<const CStack *> BattleStacksController::selectHoveredStacks()
 	if(owner.getAnimationCondition(EAnimationEvents::ACTION) == true)
 		return {};
 
+	auto hoveredQueueUnitId = owner.windowObject->getQueueHoveredUnitId();
+	if(hoveredQueueUnitId.has_value())
+	{
+		return { owner.curInt->cb->battleGetStackByUnitId(hoveredQueueUnitId.value(), true) };
+	}
+
 	auto hoveredHex = owner.fieldController->getHoveredHex();
 
 	if (!hoveredHex.isValid())

+ 1 - 1
client/battle/BattleStacksController.h

@@ -70,7 +70,7 @@ class BattleStacksController
 	/// currently active stack; nullptr - no one
 	const CStack *activeStack;
 
-	/// stacks below mouse pointer (multiple stacks possible while spellcasting), used for border animation
+	/// stacks or their battle queue images below mouse pointer (multiple stacks possible while spellcasting), used for border animation
 	std::vector<const CStack *> mouseHoveredStacks;
 
 	///when animation is playing, we should wait till the end to make the next stack active; nullptr of none

+ 5 - 0
client/battle/BattleWindow.cpp

@@ -550,6 +550,11 @@ void BattleWindow::blockUI(bool on)
 	}
 }
 
+boost::optional<uint32_t> BattleWindow::getQueueHoveredUnitId()
+{
+	return queue->getHoveredUnitIdIfAny();
+}
+
 void BattleWindow::showAll(SDL_Surface *to)
 {
 	CIntObject::showAll(to);

+ 3 - 0
client/battle/BattleWindow.h

@@ -74,6 +74,9 @@ public:
 	/// Refresh queue after turn order changes
 	void updateQueue();
 
+	/// Get mouse-hovered battle queue unit ID if any found
+	boost::optional<uint32_t> getQueueHoveredUnitId();
+
 	void activate() override;
 	void deactivate() override;
 	void keyPressed(const SDL_KeyboardEvent & key) override;

+ 15 - 0
lib/battle/CBattleInfoEssentials.cpp

@@ -185,6 +185,21 @@ const CStack* CBattleInfoEssentials::battleGetStackByID(int ID, bool onlyAlive)
 		return stacks[0];
 }
 
+const CStack* CBattleInfoEssentials::battleGetStackByUnitId(int unitId, bool onlyAlive) const
+{
+	RETURN_IF_NOT_BATTLE(nullptr);
+
+	auto stacks = battleGetStacksIf([=](const CStack * s)
+	{
+		return s->unitId() == unitId && (!onlyAlive || s->alive());
+	});
+
+	if(stacks.empty())
+		return nullptr;
+	else
+		return stacks[0];
+}
+
 bool CBattleInfoEssentials::battleDoWeKnowAbout(ui8 side) const
 {
 	RETURN_IF_NOT_BATTLE(false);

+ 1 - 0
lib/battle/CBattleInfoEssentials.h

@@ -102,6 +102,7 @@ public:
 	TStacks battleGetAllStacks(bool includeTurrets = false) const;
 
 	const CStack * battleGetStackByID(int ID, bool onlyAlive = true) const; //returns stack info by given ID
+	const CStack * battleGetStackByUnitId(int unitId, bool onlyAlive = true) const; //returns stack info by given ID
 	bool battleIsObstacleVisibleForSide(const CObstacleInstance & coi, BattlePerspective::BattlePerspective side) const;
 
 	///returns player that controls given stack; mind control included