diff --git a/game/ui/base/vequipscreen.cpp b/game/ui/base/vequipscreen.cpp
index 66e5ee5db..e4ce39bda 100644
--- a/game/ui/base/vequipscreen.cpp
+++ b/game/ui/base/vequipscreen.cpp
@@ -18,10 +18,12 @@
#include "game/state/city/vehicle.h"
#include "game/state/city/vequipment.h"
#include "game/state/gamestate.h"
+#include "game/state/rules/city/ufopaedia.h"
#include "game/state/rules/city/vehicletype.h"
#include "game/ui/components/equipscreen.h"
#include "game/ui/general/messagebox.h"
#include "game/ui/general/vehiclesheet.h"
+#include "game/ui/ufopaedia/ufopaediacategoryview.h"
#include "library/strings_format.h"
namespace OpenApoc
@@ -281,8 +283,68 @@ void VEquipScreen::eventOccurred(Event *e)
// Find the base this vehicle is landed in
StateRef base = selected->currentBuilding ? selected->currentBuilding->base : nullptr;
+ // Right-click: open UFOpaedia entry for the item under cursor
+ if (e->type() == EVENT_MOUSE_DOWN &&
+ Event::isPressed(e->mouse().Button, Event::MouseButton::Right) && !this->draggedEquipment)
+ {
+ Vec2 mousePos{e->mouse().X, e->mouse().Y};
+ StateRef clickedType;
+
+ // Check if we're over any equipment in the paper doll
+ auto mouseSlotPos = this->paperDoll->getSlotPositionFromScreenPosition(mousePos);
+ auto equipment =
+ std::dynamic_pointer_cast(this->selected->getEquipmentAt(mouseSlotPos));
+ if (equipment)
+ {
+ clickedType = equipment->type;
+ }
+ else
+ {
+ // Check if we're over any equipment in the inventory bar
+ for (auto &pair : this->inventoryItems)
+ {
+ if (pair.first.within(mousePos))
+ {
+ clickedType = pair.second;
+ break;
+ }
+ }
+ }
+
+ if (clickedType)
+ {
+ sp ufopaediaCategory;
+ sp ufopaediaEntry;
+ for (auto &cat : state->ufopaedia)
+ {
+ for (auto &entry : cat.second->entries)
+ {
+ if (entry.second->data_type == UfopaediaEntry::Data::VehicleEquipment &&
+ entry.second->data_id == clickedType.id)
+ {
+ ufopaediaEntry = entry.second;
+ ufopaediaCategory = cat.second;
+ break;
+ }
+ }
+ if (ufopaediaCategory)
+ {
+ break;
+ }
+ }
+ if (ufopaediaEntry && ufopaediaEntry->dependency.satisfied())
+ {
+ fw().stageQueueCommand(
+ {StageCmd::Command::PUSH,
+ mksp(state, ufopaediaCategory, ufopaediaEntry)});
+ }
+ }
+ return;
+ }
+
// Only allow removing equipment if we're in a base, otherwise it'll disappear
- if (e->type() == EVENT_MOUSE_DOWN && base)
+ if (e->type() == EVENT_MOUSE_DOWN &&
+ Event::isPressed(e->mouse().Button, Event::MouseButton::Left) && base)
{
Vec2 mousePos{e->mouse().X, e->mouse().Y};
diff --git a/game/ui/general/aequipscreen.cpp b/game/ui/general/aequipscreen.cpp
index dba972a65..84d982e2c 100644
--- a/game/ui/general/aequipscreen.cpp
+++ b/game/ui/general/aequipscreen.cpp
@@ -21,6 +21,7 @@
#include "game/state/city/city.h"
#include "game/state/city/vehicle.h"
#include "game/state/gamestate.h"
+#include "game/state/rules/city/ufopaedia.h"
#include "game/state/shared/aequipment.h"
#include "game/state/shared/agent.h"
#include "game/state/tilemap/tileobject_battleunit.h"
@@ -30,6 +31,7 @@
#include "game/ui/general/aequipmentsheet.h"
#include "game/ui/general/agentsheet.h"
#include "game/ui/general/messagebox.h"
+#include "game/ui/ufopaedia/ufopaediacategoryview.h"
#include
namespace OpenApoc
@@ -443,17 +445,87 @@ void AEquipScreen::eventOccurred(Event *e)
// Item manipulation
if (currentAgent->type->inventory && getMode() != Mode::Enemy)
{
- // Picking up items
- if (e->type() == EVENT_MOUSE_DOWN && !this->draggedEquipment)
+ // Picking up items (left-click)
+ if (e->type() == EVENT_MOUSE_DOWN && !this->draggedEquipment &&
+ Event::isPressed(e->mouse().Button, Event::MouseButton::Left))
{
handleItemPickup({e->mouse().X, e->mouse().Y});
}
- // Placing items
- if (e->type() == EVENT_MOUSE_UP && draggedEquipment)
+ // Placing items (left-click)
+ if (e->type() == EVENT_MOUSE_UP && draggedEquipment &&
+ Event::isPressed(e->mouse().Button, Event::MouseButton::Left))
{
handleItemPlacement({e->mouse().X, e->mouse().Y});
}
+
+ // Right-click: open UFOpaedia entry for the item under cursor
+ if (e->type() == EVENT_MOUSE_DOWN && !this->draggedEquipment &&
+ Event::isPressed(e->mouse().Button, Event::MouseButton::Right))
+ {
+ Vec2 mousePos{e->mouse().X, e->mouse().Y};
+ sp clickedItem;
+
+ // Check if we're over any equipment in the paper doll
+ auto mouseSlotPos = this->paperDoll->getSlotPositionFromScreenPosition(mousePos);
+ auto equipment =
+ std::dynamic_pointer_cast(currentAgent->getEquipmentAt(mouseSlotPos));
+ if (equipment)
+ {
+ clickedItem = equipment;
+ }
+ else
+ {
+ // Check if we're over any equipment in the inventory bar
+ auto posWithinInventory = mousePos;
+ posWithinInventory.x += inventoryPage * inventoryControl->Size.x;
+ for (auto &tuple : this->inventoryItems)
+ {
+ if (std::get<0>(tuple).within(posWithinInventory))
+ {
+ auto pos = std::get<0>(tuple).p0;
+ pos.x -= inventoryPage * inventoryControl->Size.x;
+ if (pos.x >= inventoryControl->Location.x + formMain->Location.x &&
+ pos.x < inventoryControl->Location.x + inventoryControl->Size.x +
+ formMain->Location.x)
+ {
+ clickedItem = std::get<2>(tuple);
+ }
+ break;
+ }
+ }
+ }
+
+ if (clickedItem)
+ {
+ const auto &itemTypeId = clickedItem->type.id;
+ sp ufopaediaCategory;
+ sp ufopaediaEntry;
+ for (auto &cat : state->ufopaedia)
+ {
+ for (auto &entry : cat.second->entries)
+ {
+ if (entry.second->data_type == UfopaediaEntry::Data::Equipment &&
+ entry.second->data_id == itemTypeId)
+ {
+ ufopaediaEntry = entry.second;
+ ufopaediaCategory = cat.second;
+ break;
+ }
+ }
+ if (ufopaediaCategory)
+ {
+ break;
+ }
+ }
+ if (ufopaediaEntry && ufopaediaEntry->dependency.satisfied())
+ {
+ fw().stageQueueCommand(
+ {StageCmd::Command::PUSH,
+ mksp(state, ufopaediaCategory, ufopaediaEntry)});
+ }
+ }
+ }
}
}