diff --git a/gamedata/configs/ui/pda_spot.xml b/gamedata/configs/ui/pda_spot.xml
new file mode 100644
index 0000000000..6634b63e29
--- /dev/null
+++ b/gamedata/configs/ui/pda_spot.xml
@@ -0,0 +1,22 @@
+
+
+
+ ui_inGame2_message_box
+
+
+
+
+
+ ui_inGame2_edit_box_2
+
+
+
+ ui_inv_ok
+ ui_inGame2_Mp_bigbuttone
+
+
+
+ ui_inv_cancel
+ ui_inGame2_Mp_bigbuttone
+
+
\ No newline at end of file
diff --git a/gamedata/configs/ui/pda_spot_16.xml b/gamedata/configs/ui/pda_spot_16.xml
new file mode 100644
index 0000000000..dc6f3583a7
--- /dev/null
+++ b/gamedata/configs/ui/pda_spot_16.xml
@@ -0,0 +1,22 @@
+
+
+
+ ui_inGame2_message_box
+
+
+
+
+
+ ui_inGame2_edit_box_2
+
+
+
+ ui_inv_ok
+ ui_inGame2_Mp_bigbuttone
+
+
+
+ ui_inv_cancel
+ ui_inGame2_Mp_bigbuttone
+
+
\ No newline at end of file
diff --git a/src/xrGame/map_location.cpp b/src/xrGame/map_location.cpp
index 1dcb6fbf87..86d2701b56 100644
--- a/src/xrGame/map_location.cpp
+++ b/src/xrGame/map_location.cpp
@@ -30,7 +30,7 @@
#include "Inventory.h"
//#include "CustomMonster.h"
-CMapLocation::CMapLocation(LPCSTR type, u16 object_id)
+CMapLocation::CMapLocation(LPCSTR type, u16 object_id, bool is_user_loc)
{
m_flags.zero ();
@@ -49,9 +49,14 @@ CMapLocation::CMapLocation(LPCSTR type, u16 object_id)
m_mini_map_spot_border_na = nullptr;
m_complex_spot_border_na = nullptr;
+ if (is_user_loc)
+ {
+ m_flags.set(eUserDefined, TRUE);
+ }
+
m_objectID = object_id;
m_actual_time = 0;
- m_owner_se_object = (ai().get_alife()) ? ai().alife().objects().object(m_objectID,true) : nullptr;
+ m_owner_se_object = (ai().get_alife() && !IsUserDefined()) ? ai().alife().objects().object(m_objectID, true) : nullptr;
m_flags.set (eHintEnabled, TRUE);
LoadSpot (type, false);
@@ -87,6 +92,41 @@ void CMapLocation::destroy()
delete_data(m_complex_spot_border_na);
}
+void CMapLocation::InitUserSpot(const shared_str& level_name, const Fvector& pos)
+{
+ m_cached.m_LevelName = level_name;
+ m_position_global = pos;
+ m_position_on_map.set(pos.x, pos.z);
+ m_cached.m_graphID = GameGraph::_GRAPH_ID(-1);
+ m_cached.m_Position.set(pos.x, pos.z);
+ m_cached.m_Direction.set(0.f, 0.f);
+
+ if (ai().get_alife())
+ {
+ const CGameGraph::SLevel& level = ai().game_graph().header().level(*level_name);
+ float min_dist = 128; // flt_max;
+
+ GameGraph::_GRAPH_ID n = ai().game_graph().header().vertex_count();
+
+ for (GameGraph::_GRAPH_ID i = 0; i < n; ++i)
+ {
+ if (ai().game_graph().vertex(i)->level_id() == level.id())
+ {
+ float distance = ai().game_graph().vertex(i)->game_point().distance_to_sqr(m_position_global);
+ if (distance < min_dist)
+ {
+ min_dist = distance;
+ m_cached.m_graphID = i;
+ }
+ }
+ }
+ if (!ai().game_graph().vertex(m_cached.m_graphID))
+ {
+ R_ASSERT(ai().game_graph().vertex(m_cached.m_graphID));
+ }
+ }
+}
+
CUIXml* g_uiSpotXml=nullptr;
void CMapLocation::LoadSpot(LPCSTR type, bool bReload)
{
@@ -228,33 +268,47 @@ void CMapLocation::LoadSpot(LPCSTR type, bool bReload)
}
}
-void CMapLocation::CalcPosition()
+Fvector2 CMapLocation::CalcPosition()
{
- if(m_flags.test( ePosToActor) && Level().CurrentEntity())
+ if (IsUserDefined())
+ return m_cached.m_Position;
+
+ Fvector2 pos;
+ pos.set(0.0f, 0.0f);
+
+ if (m_flags.test(ePosToActor) && Level().CurrentEntity())
{
- m_position_global = Level().CurrentEntity()->Position();
- m_cached.m_Position.set (m_position_global.x, m_position_global.z);
- return;
+ m_position_global = Level().CurrentEntity()->Position();
+ pos.set(m_position_global.x, m_position_global.z);
+ m_cached.m_Position = pos;
+ return pos;
}
- CObject* pObject = Level().Objects.net_Find(m_objectID);
- if(!pObject)
+ CObject* pObject = Level().Objects.net_Find(m_objectID);
+ if (!pObject)
{
- if(m_owner_se_object)
+ if (m_owner_se_object)
{
- m_position_global = m_owner_se_object->draw_level_position();
- m_cached.m_Position.set (m_position_global.x, m_position_global.z);
+ m_position_global = m_owner_se_object->draw_level_position();
+ pos.set(m_position_global.x, m_position_global.z);
}
-
- }else
+
+ }
+ else
{
- m_position_global = pObject->Position();
- m_cached.m_Position.set (m_position_global.x, m_position_global.z);
+ m_position_global = pObject->Position();
+ pos.set(m_position_global.x, m_position_global.z);
}
+
+ m_cached.m_Position = pos;
+ return m_cached.m_Position;
}
const Fvector2& CMapLocation::CalcDirection()
{
+ if (IsUserDefined())
+ return m_cached.m_Direction;
+
if(Level().CurrentViewEntity()&&Level().CurrentViewEntity()->ID()==m_objectID )
{
m_cached.m_Direction.set(Device.vCameraDirection.x,Device.vCameraDirection.z);
@@ -284,6 +338,9 @@ const Fvector2& CMapLocation::CalcDirection()
void CMapLocation::CalcLevelName()
{
+ if (IsUserDefined())
+ return;
+
if(m_owner_se_object && ai().get_game_graph())
{
if(m_cached.m_graphID != m_owner_se_object->m_tGraphID)
@@ -321,8 +378,11 @@ bool CMapLocation::Update() //returns actual
CalcLevelName ();
CalcPosition ();
- }else
- m_cached.m_Actuality = false;
+ }
+ else if (IsUserDefined())
+ m_cached.m_Actuality = true;
+ else
+ m_cached.m_Actuality = false;
m_cached.m_updatedFrame = Device.dwFrame;
return m_cached.m_Actuality;
@@ -335,16 +395,18 @@ void CMapLocation::UpdateSpot(CUICustomMap* map, CMapSpot* sp )
{
if( map->MapName() == GetLevelName() )
{
- bool b_alife = !!ai().get_alife();
-
- if ( b_alife && m_flags.test(eHideInOffline) && !m_owner_se_object->m_bOnline )
+ if (!IsUserDefined())
{
- return;
- }
+ bool b_alife = !!ai().get_alife();
+ if (b_alife && m_flags.test(eHideInOffline) && !m_owner_se_object->m_bOnline)
+ {
+ return;
+ }
- if (b_alife && m_owner_se_object->m_flags.test(CSE_ALifeObject::flVisibleForMap) == FALSE)
- {
- return;
+ if (b_alife && m_owner_se_object->m_flags.test(CSE_ALifeObject::flVisibleForMap) == FALSE)
+ {
+ return;
+ }
}
CGameTask* ml_task = Level().GameTaskManager().HasGameTask( this, true );
@@ -375,17 +437,20 @@ void CMapLocation::UpdateSpot(CUICustomMap* map, CMapSpot* sp )
Frect wnd_rect = sp->GetWndRect();
- if ( map->IsRectVisible(wnd_rect) )
+ if (map->IsRectVisible(wnd_rect))
{
- //update heading if needed
- if( sp->Heading() && !sp->GetConstHeading() )
+ if (!IsUserDefined())
{
- Fvector2 dir_global = CalcDirection();
- float h = dir_global.getH();
- float h_ = map->GetHeading()+h;
- sp->SetHeading( h_ );
+ //update heading if needed
+ if (sp->Heading() && !sp->GetConstHeading())
+ {
+ Fvector2 dir_global = CalcDirection();
+ float h = dir_global.getH();
+ float h_ = map->GetHeading() + h;
+ sp->SetHeading(h_);
+ }
}
- map->AttachChild (sp);
+ map->AttachChild(sp);
}
CMapSpot* s = GetSpotBorder(sp);
@@ -410,7 +475,10 @@ void CMapLocation::UpdateSpot(CUICustomMap* map, CMapSpot* sp )
{
GameGraph::_GRAPH_ID dest_graph_id;
- dest_graph_id = m_owner_se_object->m_tGraphID;
+ if (!IsUserDefined())
+ dest_graph_id = m_owner_se_object->m_tGraphID;
+ else
+ dest_graph_id = m_cached.m_graphID;
map_point_path.clear();
@@ -574,6 +642,13 @@ void CMapLocation::save(IWriter &stream)
stream.w_stringZ(m_hint);
stream.w_u32 (m_flags.flags);
stream.w_stringZ(m_owner_task_id);
+
+ if (IsUserDefined())
+ {
+ save_data(m_cached.m_LevelName, stream);
+ save_data(m_cached.m_Position, stream);
+ save_data(m_cached.m_graphID, stream);
+ }
}
void CMapLocation::load(IReader &stream)
@@ -585,6 +660,16 @@ void CMapLocation::load(IReader &stream)
stream.r_stringZ(str);
m_owner_task_id = str.c_str();
+
+ if (IsUserDefined())
+ {
+ load_data(m_cached.m_LevelName, stream);
+ load_data(m_cached.m_Position, stream);
+ load_data(m_cached.m_graphID, stream);
+
+ m_position_on_map = m_cached.m_Position;
+ m_position_global.set(m_position_on_map.x, 0.f, m_position_on_map.y);
+ }
}
void CMapLocation::SetHint(const shared_str& hint)
@@ -596,7 +681,12 @@ void CMapLocation::SetHint(const shared_str& hint)
return;
}
m_hint = hint;
-};
+}
+
+Fvector2 CMapLocation::SpotSize()
+{
+ return m_level_spot->GetWndSize();
+}
LPCSTR CMapLocation::GetHint()
{
@@ -855,4 +945,19 @@ void CRelationMapLocation::Dump ()
inherited::Dump();
Msg("--CRelationMapLocation m_curr_spot_name=[%s]",*m_curr_spot_name);
}
-#endif
\ No newline at end of file
+#endif
+
+void CMapLocation::HighlightSpot(bool state, const Fcolor& color)
+{
+ CUIStatic* st = smart_cast(m_level_spot);
+ if (state)
+ {
+ u32 clr = color_rgba((u32)color.r, (u32)color.g, (u32)color.b, (u32)color.a);
+ st->SetTextureColor(clr);
+ }
+ else
+ {
+ if (st->GetTextureColor() != 0xffffffff)
+ st->SetTextureColor(0xffffffff);
+ }
+}
\ No newline at end of file
diff --git a/src/xrGame/map_location.h b/src/xrGame/map_location.h
index 8bb3f8ae88..656e7b1960 100644
--- a/src/xrGame/map_location.h
+++ b/src/xrGame/map_location.h
@@ -24,9 +24,11 @@ enum ELocationFlags
eSpotEnabled = (1<<5),
eCollidable = (1<<6),
eHintEnabled = (1<<7),
+ eUserDefined = (1 << 8),
};
protected:
+ LPCSTR m_type;
flags32 m_flags;
shared_str m_hint;
CMapSpot* m_level_spot;
@@ -71,10 +73,17 @@ protected :
CMapSpotPointer* GetSpotPointer (CMapSpot* sp);
CMapSpot* GetSpotBorder (CMapSpot* sp);
public:
- CMapLocation (LPCSTR type, u16 object_id);
+ CMapLocation (LPCSTR type, u16 object_id, bool is_user_loc = false);
virtual ~CMapLocation ();
virtual void destroy ();
+ IC LPCSTR GetType () const { return m_type; };
+ Fvector2 SpotSize ();
+ IC bool IsUserDefined () const { return !!m_flags.test(eUserDefined); }
+ IC void SetUserDefinedFlag (BOOL state) { m_flags.set(eUserDefined, state); }
+ void InitUserSpot (const shared_str& level_name, const Fvector& pos);
+ void HighlightSpot (bool state, const Fcolor& color);
+
IC bool HintEnabled () {return !!m_flags.test(eHintEnabled);}
LPCSTR GetHint ();
void SetHint (const shared_str& hint);
@@ -93,7 +102,7 @@ protected :
virtual void UpdateMiniMap (CUICustomMap* map);
virtual void UpdateLevelMap (CUICustomMap* map);
- void CalcPosition ();
+ Fvector2 CalcPosition ();
const Fvector2& CalcDirection ();
IC const shared_str& GetLevelName () {return m_cached.m_LevelName;}
const Fvector2& GetPosition () {return m_cached.m_Position;}
diff --git a/src/xrGame/map_manager.cpp b/src/xrGame/map_manager.cpp
index 8c97cc7cdb..354ca6668b 100644
--- a/src/xrGame/map_manager.cpp
+++ b/src/xrGame/map_manager.cpp
@@ -41,6 +41,7 @@ void SLocationKey::save(IWriter &stream)
stream.w (&object_id,sizeof(object_id));
stream.w_stringZ(spot_type);
+ stream.w_u8(location->IsUserDefined() ? 1 : 0);
stream.w_u8 (0);
location->save (stream);
}
@@ -50,8 +51,19 @@ void SLocationKey::load(IReader &stream)
stream.r (&object_id,sizeof(object_id));
stream.r_stringZ(spot_type);
+ u8 bUserDefined = stream.r_u8();
stream.r_u8 ();
+ if (bUserDefined)
+ {
+ Level().Server->PerformIDgen(object_id);
+ location = xr_new(*spot_type, object_id, true);
+ }
+ else
+ {
+ location = xr_new(*spot_type, object_id);
+ }
+
location = new CMapLocation(*spot_type, object_id);
location->load (stream);
@@ -59,6 +71,9 @@ void SLocationKey::load(IReader &stream)
void SLocationKey::destroy()
{
+ if (location && location->IsUserDefined())
+ Level().Server->FreeID(object_id, 0);
+
delete_data(location);
}
@@ -130,6 +145,19 @@ CMapLocation* CMapManager::AddRelationLocation(CInventoryOwner* pInvOwner)
return l;
}
+CMapLocation* CMapManager::AddUserLocation(const shared_str& spot_type, const shared_str& level_name, Fvector position)
+{
+ u16 _id = Level().Server->PerformIDgen(0xffff);
+
+ CMapLocation* l = xr_new(spot_type.c_str(), _id, true);
+ l->InitUserSpot(level_name, position);
+
+ Locations().push_back(SLocationKey(spot_type, _id));
+ Locations().back().location = l;
+
+ return l;
+}
+
void CMapManager::Destroy(CMapLocation* ml)
{
m_deffered_destroy_queue.push_back(ml);
@@ -287,4 +315,77 @@ void CMapManager::Dump ()
Msg("end of map_locations dump");
}
-#endif
\ No newline at end of file
+#endif
+
+using namespace luabind;
+void CMapManager::MapLocationsForEach(LPCSTR spot_type, u16 id, const luabind::functor& functor)
+{
+ xr_vector res;
+ Level().MapManager().GetMapLocations(spot_type, id, res);
+ xr_vector::iterator it = res.begin();
+ xr_vector::iterator it_e = res.end();
+ for (; it != it_e; ++it)
+ {
+ CMapLocation* ml = *it;
+ if (functor(ml) == true)
+ return;
+ }
+}
+
+void CMapManager::AllLocationsForEach(const luabind::functor& functor)
+{
+ Locations_it it = Locations().begin();
+ Locations_it it_e = Locations().end();
+
+ for (; it != it_e; ++it)
+ {
+ if (functor((*it).location) == true)
+ return;
+ }
+}
+
+#include "map_location.h"
+
+#pragma optimize("s",on)
+void CMapManager::script_register(lua_State* L)
+{
+ module(L)
+ [
+ class_("CMapManager")
+ .def(constructor<>())
+ //.def("AddMapLocation", &CMapManager::AddMapLocation_script)
+ //.def("AddUserLocation", &CMapManager::AddUserLocation_script)
+ //.def("RemoveMapLocation", &CMapManager::RemoveMapLocation_script)
+ //.def("HasMapLocation", &CMapManager::HasMapLocation_script)
+ //.def("GetMapLocation", &CMapManager::GetMapLocation_script)
+ .def("RemoveMapLocationByObjectID", &CMapManager::RemoveMapLocationByObjectID)
+ .def("RemoveMapLocation", (void (CMapManager::*)(CMapLocation*)) & CMapManager::RemoveMapLocation)
+ //.def("RemoveMapLocation", &CMapManager::RemoveMapLocation_script)
+ .def("DisableAllPointers", &CMapManager::DisableAllPointers)
+ .def("MapLocationsForEach", &CMapManager::MapLocationsForEach)
+ .def("AllLocationsForEach", &CMapManager::AllLocationsForEach),
+
+ class_("CMapLocation")
+ //.def(constructor<>())
+ .def("HintEnabled", &CMapLocation::HintEnabled)
+ .def("GetHint", &CMapLocation::GetHint)
+ .def("SetHint", &CMapLocation::SetHint)
+ .def("PointerEnabled", &CMapLocation::PointerEnabled)
+ .def("EnablePointer", &CMapLocation::EnablePointer)
+ .def("DisablePointer", &CMapLocation::DisablePointer)
+ .def("GetType", &CMapLocation::GetType)
+ .def("SpotSize", &CMapLocation::SpotSize)
+ .def("IsUserDefined", &CMapLocation::IsUserDefined)
+ .def("SetUserDefinedFlag", &CMapLocation::SetUserDefinedFlag)
+ .def("HighlightSpot", &CMapLocation::HighlightSpot)
+ .def("Collidable", &CMapLocation::Collidable)
+ .def("SpotEnabled", &CMapLocation::SpotEnabled)
+ .def("EnableSpot", &CMapLocation::EnableSpot)
+ .def("DisableSpot", &CMapLocation::DisableSpot)
+ .def("GetLevelName", &CMapLocation::GetLevelName)
+ .def("GetPosition", &CMapLocation::GetPosition)
+ .def("ObjectID", &CMapLocation::ObjectID)
+ .def("GetLastPosition", &CMapLocation::GetLastPosition)
+ //.def("GetOwnerTaskID", &CMapLocation::GetOwnerTaskID)
+ ];
+}
\ No newline at end of file
diff --git a/src/xrGame/map_manager.h b/src/xrGame/map_manager.h
index e18ef4c189..94d1e6dde0 100644
--- a/src/xrGame/map_manager.h
+++ b/src/xrGame/map_manager.h
@@ -19,6 +19,7 @@ class CMapManager
/*ICF */Locations& Locations ();//{return *m_locations;}
CMapLocation* AddMapLocation (const shared_str& spot_type, u16 id);
CMapLocation* AddRelationLocation (CInventoryOwner* pInvOwner);
+ CMapLocation* AddUserLocation (const shared_str& spot_type, const shared_str& level_name, Fvector position);
void RemoveMapLocation (const shared_str& spot_type, u16 id);
bool HasMapLocation (const shared_str& spot_type, u16 id);
void RemoveMapLocationByObjectID (u16 id); //call on destroy object
@@ -33,4 +34,9 @@ class CMapManager
void Dump ();
#endif
void Destroy (CMapLocation*);
+
+
+ void MapLocationsForEach(LPCSTR spot_type, u16 id, const luabind::functor& functor);
+ void AllLocationsForEach(const luabind::functor& functor);
+ void script_register(lua_State* L);
};
diff --git a/src/xrGame/ui/UIDialogWnd.cpp b/src/xrGame/ui/UIDialogWnd.cpp
index de29c16f25..4dcdb2813c 100644
--- a/src/xrGame/ui/UIDialogWnd.cpp
+++ b/src/xrGame/ui/UIDialogWnd.cpp
@@ -37,7 +37,8 @@ bool CUIDialogWnd::IR_process()
{
if(!IsEnabled()) return false;
- if(GetHolder()->IgnorePause()) return true;
+ if(GetHolder() && GetHolder()->IgnorePause())
+ return true;
if(Device.Paused()&&!WorkInPause()) return false;
diff --git a/src/xrGame/ui/UIMap.cpp b/src/xrGame/ui/UIMap.cpp
index 525f6d4083..803e85090f 100644
--- a/src/xrGame/ui/UIMap.cpp
+++ b/src/xrGame/ui/UIMap.cpp
@@ -516,6 +516,23 @@ bool CUILevelMap::OnMouseAction(float x, float y, EUIMessages mouse_action)
if (inherited::OnMouseAction(x,y,mouse_action)) return true;
if (MapWnd()->GlobalMap()->Locked()) return true;
+ if (mouse_action == WINDOW_LBUTTON_DB_CLICK)
+ {
+ Fvector RealPosition;
+
+ if (MapWnd()->ConvertCursorPosToMap(&RealPosition, this))
+ {
+ CMapLocation* _mapLoc = MapWnd()->UnderSpot(RealPosition, this);
+
+ if (_mapLoc == nullptr)
+ {
+ MapWnd()->CreateSpotWindow(RealPosition, MapName());
+ return true;
+ }
+ }
+
+ }
+
if(mouse_action==WINDOW_MOUSE_MOVE && (FALSE==pInput->iGetAsyncBtnState(0)) )
{
if( MapWnd() )
diff --git a/src/xrGame/ui/UIMapWnd.cpp b/src/xrGame/ui/UIMapWnd.cpp
index 8028e78284..296afa8355 100644
--- a/src/xrGame/ui/UIMapWnd.cpp
+++ b/src/xrGame/ui/UIMapWnd.cpp
@@ -1,4 +1,4 @@
-#include "stdafx.h"
+#include "stdafx.h"
#include "UIMapWnd.h"
#include "UIMap.h"
#include "UIXmlInit.h"
@@ -9,6 +9,9 @@
#include "../map_spot.h"
#include "../map_location.h"
+#include "../xrEngine/string_table.h"
+#include "../xrEngine/xr_input.h"
+
#include "UIFixedScrollBar.h"
#include "UIFrameWindow.h"
#include "UIFrameLineWnd.h"
@@ -19,8 +22,10 @@
#include "UIHint.h"
#include "map_hint.h"
#include "uicursor.h"
+#include "UIPdaSpot.h"
-#include "../../xrEngine/xr_input.h" //remove me !!!
+#include "UIPropertiesBox.h"
+#include "UIListBoxItem.h"
CUIMapWnd* g_map_wnd = nullptr; // quick temporary solution -(
CUIMapWnd* GetMapWnd()
@@ -37,13 +42,9 @@ CUIMapWnd::CUIMapWnd()
m_currentZoom = 1.0f;
m_map_location_hint = nullptr;
m_map_move_step = 10.0f;
-/*
-#ifdef DEBUG
-// m_dbg_text_hint = nullptr;
-// m_dbg_info = nullptr;
-#endif // DEBUG /**/
+ m_UserSpotWnd = nullptr;
+ m_cur_location = nullptr;
-// UIMainMapHeader = nullptr;
m_scroll_mode = false;
m_nav_timing = Device.dwTimeGlobal;
hint_wnd = nullptr;
@@ -185,6 +186,18 @@ void CUIMapWnd::Init(LPCSTR xml_name, LPCSTR start_from)
m_ActionPlanner = new CMapActionPlanner();
m_ActionPlanner->setup (this);
m_view_actor = true;
+
+ m_UIPropertiesBox = xr_new();
+ m_UIPropertiesBox->SetAutoDelete(true);
+ m_UIPropertiesBox->InitPropertiesBox(Fvector2().set(0, 0), Fvector2().set(300, 300));
+
+ AttachChild(m_UIPropertiesBox);
+ m_UIPropertiesBox->Hide();
+ m_UIPropertiesBox->SetWindowName("property_box");
+
+ m_UserSpotWnd = new CUIPdaSpot();
+ m_UserSpotWnd->SetAutoDelete(true);
+ AttachChild(m_UserSpotWnd);
}
void CUIMapWnd::Show(bool status)
@@ -224,6 +237,8 @@ void CUIMapWnd::Show(bool status)
InventoryUtilities::SendInfoToActor("ui_pda_map_local");
}
HideCurHint();
+
+ m_UserSpotWnd->Exit();
}
void CUIMapWnd::Activated()
@@ -414,6 +429,9 @@ bool CUIMapWnd::OnMouseAction(float x, float y, EUIMessages mouse_action)
{
switch ( mouse_action )
{
+ case WINDOW_RBUTTON_UP:
+ ActivatePropertiesBox(nullptr);
+ break;
case WINDOW_MOUSE_MOVE:
if( pInput->iGetAsyncBtnState(0) )
{
@@ -478,6 +496,66 @@ void CUIMapWnd::SendMessage(CUIWindow* pWnd, s16 msg, void* pData)
{
// inherited::SendMessage( pWnd, msg, pData);
CUIWndCallback::OnEvent(pWnd, msg, pData);
+
+ if (pWnd == m_UIPropertiesBox && msg == PROPERTY_CLICKED && m_UIPropertiesBox->GetClickedItem())
+ {
+ luabind::functor funct;
+ if (ai().script_engine().functor("pda.property_box_clicked", funct))
+ funct(m_UIPropertiesBox);
+ //-----------------------
+ switch (m_UIPropertiesBox->GetClickedItem()->GetTAG())
+ {
+ case MAP_CHANGE_SPOT_HINT_ACT:
+ {
+ ShowSettingsWindow(m_cur_location->ObjectID(), m_cur_location->GetLastPosition(), m_cur_location->GetLevelName());
+ break;
+ }
+ case MAP_REMOVE_SPOT_ACT:
+ {
+ Level().MapManager().RemoveMapLocation(m_cur_location);
+ m_cur_location = nullptr;
+ break;
+ }
+ }
+ }
+}
+
+void CUIMapWnd::ActivatePropertiesBox(CUIWindow* w)
+{
+ m_UIPropertiesBox->RemoveAll();
+
+ CMapSpot* sp = smart_cast(w);
+ if (!sp)
+ {
+ return;
+ }
+
+ m_cur_location = sp->MapLocation();
+
+ luabind::functor funct;
+ if (ai().script_engine().functor("pda.property_box_add_properties", funct))
+ {
+ funct(m_UIPropertiesBox, m_cur_location->ObjectID(), (LPCSTR)m_cur_location->GetLevelName().c_str());
+ }
+
+ if (m_cur_location->IsUserDefined())
+ {
+ m_UIPropertiesBox->AddItem("st_pda_change_spot_hint", NULL, MAP_CHANGE_SPOT_HINT_ACT);
+ m_UIPropertiesBox->AddItem("st_pda_delete_spot", NULL, MAP_REMOVE_SPOT_ACT);
+ }
+
+ if (m_UIPropertiesBox->GetItemsCount() > 0)
+ {
+ m_UIPropertiesBox->AutoUpdateSize();
+
+ Fvector2 cursor_pos;
+ Frect vis_rect;
+
+ GetAbsoluteRect(vis_rect);
+ cursor_pos = GetUICursor().GetCursorPosition();
+ cursor_pos.sub(vis_rect.lt);
+ m_UIPropertiesBox->Show(vis_rect, cursor_pos);
+ }
}
CUICustomMap* CUIMapWnd::GetMapByIdx(u16 idx)
@@ -709,3 +787,77 @@ void CUIMapWnd::SpotSelected( CUIWindow* w )
Level().GameTaskManager().SetActiveTask( t );
}
}
+
+// -------------------------------------------------------------
+// qweasdd: Following functions from Lost Alpha
+//Alun: Correct now. All you need is relative mouse position to absolute pos of uilevelmap, then remove widescreen scale on X before local-to-world convert
+bool CUIMapWnd::ConvertCursorPosToMap(Fvector* return_position, CUILevelMap* curr_map)
+{
+ Fvector2 cursor_pos = GetUICursor().GetCursorPosition();
+ Frect box_rect;
+ curr_map->GetAbsoluteRect(box_rect);
+ if (!box_rect.in(cursor_pos))
+ return false;
+
+ cursor_pos.sub(box_rect.lt);
+
+ Frect bound_rect = curr_map->BoundRect();
+ bound_rect.lt.x /= UI().get_current_kx();
+ bound_rect.rb.x /= UI().get_current_kx();
+ return_position->x = bound_rect.lt.x + cursor_pos.x / (box_rect.width() / bound_rect.width());
+ return_position->y = 0.f;
+ return_position->z = bound_rect.height() + bound_rect.lt.y - cursor_pos.y / (box_rect.height() / bound_rect.height());
+
+ return true;
+}
+
+// -------------------------------------------------------------
+void CUIMapWnd::ShowSettingsWindow(u16 id, Fvector pos, shared_str levelName)
+{
+ m_UserSpotWnd->Init(id, levelName.c_str(), pos, false);
+ m_UserSpotWnd->ShowDialog(true);
+}
+
+// -------------------------------------------------------------
+CMapLocation* CUIMapWnd::UnderSpot(Fvector RealPosition, CUILevelMap* curr_map)
+{
+ Fvector2 RealPositionXZ;
+ RealPositionXZ.set(RealPosition.x, RealPosition.z);
+
+ Locations Spots = Level().MapManager().Locations();
+ Locations_it it;
+ Fvector2 m_position_on_map;
+ Fvector2 m_position_mouse = curr_map->ConvertRealToLocal(RealPositionXZ, false);
+ float TargetLocationDistance = 100.0f;
+ CMapLocation* ml = NULL;
+
+ for (it = Spots.begin(); it != Spots.end(); ++it)
+ {
+ if ((*it).location->IsUserDefined())
+ {
+ Msg("qweasdd: CUIMapWnd::UnderSpot map loc is user defined!");
+ m_position_on_map = curr_map->ConvertRealToLocal((*it).location->CalcPosition(), false);
+
+ float distance = m_position_on_map.distance_to(m_position_mouse);
+
+ Fvector2 FvectorSize = (*it).location->SpotSize();
+ float size = (FvectorSize.x + FvectorSize.y) / 2;
+
+ if ((distance < size) && (distance < TargetLocationDistance))
+ {
+ TargetLocationDistance = distance;
+ ml = (*it).location;
+
+ }
+ }
+ }
+
+ return ml;
+}
+
+// -------------------------------------------------------------
+void CUIMapWnd::CreateSpotWindow(Fvector RealPosition, shared_str map_name)
+{
+ m_UserSpotWnd->Init(u16(-1), map_name.c_str(), RealPosition, true);
+ m_UserSpotWnd->ShowDialog(true);
+}
\ No newline at end of file
diff --git a/src/xrGame/ui/UIMapWnd.h b/src/xrGame/ui/UIMapWnd.h
index d21b1a2bff..7bc3597e2a 100644
--- a/src/xrGame/ui/UIMapWnd.h
+++ b/src/xrGame/ui/UIMapWnd.h
@@ -20,6 +20,8 @@ class CMapSpot;
class CGameTask;
class CUIXml;
class UIHint;
+class CUIPdaSpot;
+class CUIPropertiesBox;
using GameMaps = xr_map;
using GameMapsPairIt = GameMaps::iterator;
@@ -44,13 +46,9 @@ class CUIMapWnd: public CUIWindow, public CUIWndCallback
CUIFixedScrollBar* m_UIMainScrollH;
CUIWindow* m_UILevelFrame;
CMapActionPlanner* m_ActionPlanner;
-// CUIFrameLineWnd* UIMainMapHeader;
- CUIMapLocationHint* m_map_location_hint;
-#ifdef DEBUG
-// CUIStatic* m_dbg_text_hint;
-// CUIStatic* m_dbg_info;
-#endif // DEBUG
+ CUIMapLocationHint* m_map_location_hint;
+ CUIPdaSpot* m_UserSpotWnd;
enum EBtnPos
{
@@ -92,7 +90,18 @@ class CUIMapWnd: public CUIWindow, public CUIWndCallback
void ResetActionPlanner ();
+ CMapLocation* m_cur_location;
+ CUIPropertiesBox* m_UIPropertiesBox;
+
public:
+
+ // qweasdd: from lost alpha
+ bool ConvertCursorPosToMap(Fvector*, CUILevelMap*);
+ void CreateSpotWindow(Fvector, shared_str);
+ void ShowSettingsWindow(u16 id, Fvector position, shared_str levelName);
+ CMapLocation* UnderSpot(Fvector RealPosition, CUILevelMap*);
+ //-qweasdd
+
void ViewGlobalMap ();
void ViewActor ();
void ViewZoomIn ();
@@ -100,6 +109,7 @@ class CUIMapWnd: public CUIWindow, public CUIWndCallback
void MoveScrollV ( float dy );
void MoveScrollH ( float dx );
+ void ActivatePropertiesBox(CUIWindow* w);
public:
CUICustomMap* m_tgtMap;
diff --git a/src/xrGame/ui/UIMessages.h b/src/xrGame/ui/UIMessages.h
index fe2eec8e67..4976c44e44 100644
--- a/src/xrGame/ui/UIMessages.h
+++ b/src/xrGame/ui/UIMessages.h
@@ -102,7 +102,7 @@ enum EUIMessages
INVENTORY_ATTACH_SCOPE_ADDON,
INVENTORY_DETACH_SCOPE_ADDON,
- INVENTORY_ATTACH_SILENCER_ADDON,
+ INVENTORY_ATTACH_SILENCER_ADDON,
INVENTORY_DETACH_SILENCER_ADDON,
INVENTORY_ATTACH_GRENADE_LAUNCHER_ADDON,
@@ -118,6 +118,10 @@ enum EUIMessages
MAP_SHOW_HINT,
MAP_HIDE_HINT,
MAP_SELECT_SPOT,
+
+ //CUIMapWnd
+ MAP_CHANGE_SPOT_HINT_ACT,
+ MAP_REMOVE_SPOT_ACT,
MAIN_MENU_RELOADED,
};
diff --git a/src/xrGame/ui/UIPdaSpot.cpp b/src/xrGame/ui/UIPdaSpot.cpp
new file mode 100644
index 0000000000..5e4975fab9
--- /dev/null
+++ b/src/xrGame/ui/UIPdaSpot.cpp
@@ -0,0 +1,137 @@
+#include "stdafx.h"
+#include "UIPdaSpot.h"
+#include
+#include "Level.h"
+#include "map_manager.h"
+#include "map_location.h"
+#include "UIEditBox.h"
+#include "UIStatic.h"
+#include "UIXmlInit.h"
+#include "UIHelper.h"
+#include "UI3tButton.h"
+#include "../xrEngine/string_table.h"
+
+CUIPdaSpot::CUIPdaSpot()
+{
+ m_mainWnd = false;
+ m_levelName = nullptr;
+ m_position = Fvector();
+
+ m_spotID = u16(-1);
+ m_spotType = READ_IF_EXISTS(pSettings, r_string, "user_spots", "spot_type", "treasure");
+
+ InitControls();
+}
+
+CUIPdaSpot::~CUIPdaSpot()
+{
+}
+
+void CUIPdaSpot::Init(u16 spot_id, LPCSTR level_name, Fvector pos, bool main_wnd)
+{
+ m_mainWnd = main_wnd;
+ m_levelName = level_name;
+ m_position = pos;
+
+ m_spotID = !m_mainWnd ? spot_id : u16(-1);
+
+ if (!m_mainWnd)
+ {
+ CMapLocation* ml = Level().MapManager().GetMapLocation(m_spotType, m_spotID);
+ if (!ml) return;
+ m_editBox->SetText(ml->GetHint());
+ ml->HighlightSpot(true, Fcolor().set(255.f, 36.f, 0.f, 255.f));
+ }
+}
+
+void CUIPdaSpot::InitControls()
+{
+ this->SetWndRect(Frect().set(0.0f, 0.0f, 1024.f, 768.f));
+
+ CUIXml uiXml;
+ uiXml.Load(CONFIG_PATH, UI_PATH, "pda_spot.xml");
+
+ m_background = UIHelper::CreateStatic(uiXml, "background", this);
+ m_editBox = UIHelper::CreateEditBox(uiXml, "spot_name_edit", this);
+
+ m_btn_ok = UIHelper::Create3tButton(uiXml, "btn_apply", this);
+ Register(m_btn_ok);
+ AddCallback(m_btn_ok, BUTTON_CLICKED, CUIWndCallback::void_function(this, &CUIPdaSpot::OnApply));
+
+ m_btn_cancel = UIHelper::Create3tButton(uiXml, "btn_cancel", this);
+ Register(m_btn_cancel);
+ AddCallback(m_btn_cancel, BUTTON_CLICKED, CUIWndCallback::void_function(this, &CUIPdaSpot::OnExit));
+}
+
+void CUIPdaSpot::OnAdd(CUIWindow* ui, void* d)
+{
+ CMapLocation* ml = Level().MapManager().AddUserLocation(m_spotType, m_levelName, m_position);
+ ml->SetHint(m_editBox->GetText());
+ ml->SetSerializable(true);
+
+ OnExit(ui, d);
+}
+
+void CUIPdaSpot::OnApply(CUIWindow* ui, void* d)
+{
+ if (m_mainWnd)
+ {
+ OnAdd(ui, d);
+ return;
+ }
+
+ CMapLocation* ml = Level().MapManager().GetMapLocation(m_spotType, m_spotID);
+ if (!ml)
+ return;
+
+ if (m_editBox->GetText() != ml->GetHint())
+ ml->SetHint(m_editBox->GetText());
+
+ OnExit(ui, d);
+}
+
+void CUIPdaSpot::OnExit(CUIWindow* w, void* d)
+{
+ Exit();
+}
+
+void CUIPdaSpot::Exit()
+{
+ if (!m_mainWnd)
+ {
+ CMapLocation* ml = Level().MapManager().GetMapLocation(m_spotType, m_spotID);
+ if (!ml) return;
+ ml->HighlightSpot(false, Fcolor().set(0.f, 0.f, 0.f, 0.f));
+ }
+
+ m_mainWnd = false;
+ m_levelName = nullptr;
+ m_position = Fvector();
+ m_spotID = u16(-1);
+
+ m_editBox->ClearText();
+
+ HideDialog();
+}
+
+bool CUIPdaSpot::OnKeyboardAction(int dik, EUIMessages keyboard_action)
+{
+ switch (dik)
+ {
+ case DIK_ESCAPE:
+ {
+ if (IsShown())
+ {
+ Exit();
+ return true;
+ }
+ }break;
+ }
+
+ return base_class::OnKeyboardAction(dik, keyboard_action);
+}
+
+void CUIPdaSpot::SendMessage(CUIWindow* pWnd, s16 msg, void* pData)
+{
+ CUIWndCallback::OnEvent(pWnd, msg, pData);
+}
\ No newline at end of file
diff --git a/src/xrGame/ui/UIPdaSpot.h b/src/xrGame/ui/UIPdaSpot.h
new file mode 100644
index 0000000000..824309571a
--- /dev/null
+++ b/src/xrGame/ui/UIPdaSpot.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "UIDialogWnd.h"
+#include "UIWndCallback.h"
+
+class CUIXml;
+class CUI3tButton;
+class CUIStatic;
+class CUIEditBox;
+class UIHint;
+
+class CUIPdaSpot :
+ public CUIDialogWnd,
+ public CUIWndCallback
+{
+ typedef CUIDialogWnd base_class;
+
+ CUIStatic* m_background;
+ CUIEditBox* m_editBox;
+ CUI3tButton* m_btn_ok;
+ CUI3tButton* m_btn_cancel;
+
+ bool m_mainWnd;
+ LPCSTR m_levelName;
+ Fvector m_position;
+ u16 m_spotID;
+ shared_str m_spotType;
+
+public:
+ CUIPdaSpot();
+ ~CUIPdaSpot();
+
+ void Init(u16 spot_id, LPCSTR level_name, Fvector pos, bool main_wnd);
+ void InitControls();
+
+ void OnAdd(CUIWindow* w, void* d);
+ void OnApply(CUIWindow* w, void* d);
+ void OnExit(CUIWindow* w, void* d);
+ void Exit();
+
+ virtual bool OnKeyboardAction(int dik, EUIMessages keyboard_action);
+ virtual void SendMessage(CUIWindow* pWnd, s16 msg, void* pData = NULL);
+};
\ No newline at end of file