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