123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- class CfgPlayerRestrictedAreaHandler
- {
- private static bool m_Initialized;
-
- static ref TStringArray m_PRAFiles = new TStringArray();
- static ref CfgPlayerRestrictedAreaJsonData m_Data = new CfgPlayerRestrictedAreaJsonData();
-
- //----------------------------------------------------------
- //load, inits, validation
-
- static bool LoadData()
- {
- if (m_Initialized)
- return true;
-
- m_Initialized = false;
-
- if (GetGame().ServerConfigGetInt( "enableCfgGameplayFile" )) //only reach into the CfgGameplayHandler if properly loaded!
- m_PRAFiles = CfgGameplayHandler.GetPlayerRestrictedAreaFiles();
- else
- m_PRAFiles = g_Game.GetMission().GetWorldData().GetDefaultPRAPaths();
-
- if (!m_PRAFiles)
- return true;
- string worldName;
- GetGame().GetWorldName(worldName);
-
- foreach (string filename : m_PRAFiles)
- {
- PlayerRestrictedAreaInstance area = new PlayerRestrictedAreaInstance();
-
- string errorMessage, path;
- path = string.Format("$mission:%1", filename);
- if (!JsonFileLoader<PlayerRestrictedAreaInstance>.LoadFile(path, area, errorMessage))
- {
- if (!FileExist(filename))
- path = string.Format("dz/worlds/%1/ce/%2", worldName, filename);
-
- if (!JsonFileLoader<PlayerRestrictedAreaInstance>.LoadFile(path, area, errorMessage))
- {
- ErrorEx(errorMessage);
- continue;
- }
- }
-
- if (area != null)
- m_Data.m_Areas.Insert(area);
- }
-
- m_Initialized = m_Data.InitializeAreas();
-
- return true;
- }
-
- static bool IsInitialized()
- {
- return m_Initialized;
- }
-
- //----------------------------------------------------------
- //synchronization
-
- static void SyncDataSend(notnull PlayerIdentity identity)
- {
- GetGame().RPCSingleParam(null, ERPCs.RPC_PLAYERRESTRICTEDAREAS_SYNC, new Param1<CfgPlayerRestrictedAreaJsonData>(m_Data), true, identity);
- }
-
- static void OnRPC(ParamsReadContext ctx)
- {
- Param1<CfgPlayerRestrictedAreaJsonData> data = new Param1<CfgPlayerRestrictedAreaJsonData>(null);
-
- if (ctx.Read(data))
- {
- m_Data = data.param1;
- m_Initialized = m_Data.m_ValidatedAreas.Count() > 0;
- }
- else
- {
- ErrorEx("CfgPlayerRestrictedAreaHandler - client failed to read incoming data");
- }
- }
-
- //----------------------------------------------------------
- //main area checking methods
-
- static bool IsPointInPlayerRestrictedAreaClosest(vector point, out PlayerRestrictedAreaInstance hitArea)
- {
- if (!IsInitialized())
- return false;
-
- PlayerRestrictedAreaInstance area = GetClosestArea(point);
- if (area && IsCylinderInAreaBox(area,point) || IsPointInAreaPolygon(area,point))
- {
- hitArea = area;
- return true;
- }
- return false;
- }
-
- static bool IsPointInPlayerRestrictedArea(vector point, out PlayerRestrictedAreaInstance hitArea)
- {
- if (!IsInitialized())
- return false;
-
- foreach (PlayerRestrictedAreaInstance area : m_Data.m_ValidatedAreas)
- {
- if (IsCylinderInAreaBox(area,point) || IsPointInAreaPolygon(area,point))
- {
- hitArea = area;
- return true;
- }
- }
-
- return false;
- }
-
- //----------------------------------------------------------
- //support methods
-
- private static PlayerRestrictedAreaInstance GetClosestArea(vector point)
- {
- PlayerRestrictedAreaInstance ret;
- float closestDist = float.MAX;
- float currentDist;
-
- foreach (PlayerRestrictedAreaInstance area : m_Data.m_ValidatedAreas)
- {
- currentDist = vector.DistanceSq(point,area.GetCenterPos2D());
- if (currentDist < closestDist)
- {
- ret = area;
- closestDist = currentDist;
- }
- }
-
- return ret;
- }
-
- //! default cylinder values sufficient for player detection
- private static bool IsCylinderInAreaBox(notnull PlayerRestrictedAreaInstance area, vector point, float cylinderRadius = 0.25, float cylinderHeight = 1)
- {
- foreach (PRAShapeBoxData boxData : area.m_PRABoxDataTranslated)
- {
- vector matPlayer4[4];
- Math3D.MatrixIdentity4(matPlayer4);
- matPlayer4[3] = point;
- if (Math3D.IntersectCylinderOBB(boxData.m_Mins,boxData.m_Maxs,boxData.m_Mat4,matPlayer4,cylinderRadius,cylinderHeight))
- return true;
- }
-
- return false;
- }
-
- private static bool IsPointInAreaPolygon(notnull PlayerRestrictedAreaInstance area, vector point)
- {
- array<float> translatedDta = new array<float>;
- foreach (array<ref array<float>> polygonData : area.PRAPolygons)
- {
- translatedDta.Clear();
-
- foreach (array<float> vertexPos : polygonData)
- {
- translatedDta.Insert(vertexPos[0]);
- translatedDta.Insert(vertexPos[1]);
- }
-
- if (Math2D.IsPointInPolygon(translatedDta,point[0],point[2]))
- return true;
- }
-
- return false;
- }
-
- //----------------------------------------------------------
- //debugs
-
- static private ref array<Shape> m_DbgShapesBoxes;
- static private ref array<Shape> m_DbgShapesPolygonLines;
-
- static void DrawBoxesDebug(bool draw)
- {
- if (!IsInitialized())
- return;
-
- if (!m_DbgShapesBoxes)
- m_DbgShapesBoxes = {};
-
- if (draw && m_DbgShapesBoxes.Count() == 0)
- {
- foreach (PlayerRestrictedAreaInstance area : m_Data.m_ValidatedAreas)
- {
- foreach (PRAShapeBoxData boxData : area.m_PRABoxDataTranslated)
- {
- Shape shp = Debug.DrawBox(boxData.m_Mins,boxData.m_Maxs);
- shp.SetMatrix(boxData.m_Mat4);
- m_DbgShapesBoxes.Insert(shp);
- }
- }
- }
- else if (!draw && m_DbgShapesBoxes.Count() > 0)
- {
- foreach (Shape box : m_DbgShapesBoxes)
- {
- box.Destroy();
- }
-
- m_DbgShapesBoxes.Clear();
- }
- }
-
- static void DrawPolygonLinesDebug(bool draw)
- {
- if (!IsInitialized())
- return;
-
- if (!m_DbgShapesPolygonLines)
- m_DbgShapesPolygonLines = {};
-
- if (draw && m_DbgShapesPolygonLines.Count() == 0)
- {
- array<vector> polygonVectors = {};
- foreach (PlayerRestrictedAreaInstance area : m_Data.m_ValidatedAreas)
- {
- foreach (array<ref array<float>> polygonData : area.PRAPolygons)
- {
- vector first;
- vector current;
- vector last;
-
- foreach (array<float> vertexPos : polygonData)
- {
- polygonVectors.Insert(Vector(vertexPos[0],GetGame().SurfaceY(vertexPos[0],vertexPos[1]) + 2,vertexPos[1]));
- }
-
- int count = polygonVectors.Count();
- for (int i = 0; i < count; ++i)
- {
- current = polygonVectors[i];
-
- if (i == 0)
- first = polygonVectors[i];
- else
- Debug.DrawLine(last,current,COLOR_WHITE,ShapeFlags.TRANSP|ShapeFlags.NOZWRITE);
-
- last = current;
- }
-
- m_DbgShapesPolygonLines.Insert(Debug.DrawLine(current,first,COLOR_RED,ShapeFlags.TRANSP|ShapeFlags.NOZWRITE));
-
- polygonVectors.Clear();
- }
- }
- }
- else if (!draw && m_DbgShapesPolygonLines.Count() > 0)
- {
- foreach (Shape item : m_DbgShapesPolygonLines)
- {
- item.Destroy();
- }
-
- m_DbgShapesPolygonLines.Clear();
- }
- }
- }
|