1400{
1402
1404
1406
1408
1414
1415
1416
1422
1428
1430
1434
1435
1437 {
1439
1440
1441 RegisterNetSyncVariableInt( "m_SyncParts01" );
1442 RegisterNetSyncVariableInt( "m_SyncParts02" );
1443 RegisterNetSyncVariableInt( "m_SyncParts03" );
1444 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1445 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1446 RegisterNetSyncVariableBool( "m_HasBase" );
1447
1448
1450
1451 if (ConfigIsExisting("hybridAttachments"))
1452 {
1455 }
1456 if (ConfigIsExisting("mountables"))
1457 {
1460 }
1461
1463 }
1464
1466 {
1467 super.EEDelete(parent);
1468
1470 {
1471 areaDamage.Destroy();
1472 }
1473
1474 }
1475
1477 {
1478 return "disableBaseDamage";
1479 }
1480
1482 {
1483 return true;
1484 }
1485
1487 {
1488 return EInventoryIconVisibility.HIDE_VICINITY;
1489 }
1490
1492 {
1493 super.InitItemSounds();
1494
1498
1503 }
1504
1506 {
1507 return "putDown_FenceKit_SoundSet";
1508 }
1509
1511 {
1512 return "Shelter_Site_Build_Loop_SoundSet";
1513 }
1514
1515
1517 {
1519 {
1520 SetSynchDirty();
1521 }
1522 }
1523
1525 {
1527 super.OnVariablesSynchronized();
1528
1530 }
1531
1533 {
1534
1536
1537
1539
1540
1542 }
1543
1544
1546 {
1547
1548 int offset;
1549 int mask;
1550
1551 if ( part_id >= 1 && part_id <= 31 )
1552 {
1553 offset = part_id - 1;
1554 mask = 1 << offset;
1555
1557 }
1558 else if ( part_id >= 32 && part_id <= 62 )
1559 {
1560 offset = ( part_id % 32 );
1561 mask = 1 << offset;
1562
1564 }
1565 else if ( part_id >= 63 && part_id <= 93 )
1566 {
1567 offset = ( part_id % 63 );
1568 mask = 1 << offset;
1569
1571 }
1572 }
1573
1575 {
1576
1577 int offset;
1578 int mask;
1579
1580 if ( part_id >= 1 && part_id <= 31 )
1581 {
1582 offset = part_id - 1;
1583 mask = 1 << offset;
1584
1586 }
1587 else if ( part_id >= 32 && part_id <= 62 )
1588 {
1589 offset = ( part_id % 32 );
1590 mask = 1 << offset;
1591
1593 }
1594 else if ( part_id >= 63 && part_id <= 93 )
1595 {
1596 offset = ( part_id % 63 );
1597 mask = 1 << offset;
1598
1600 }
1601 }
1602
1604 {
1605
1606 int offset;
1607 int mask;
1608
1609 if ( part_id >= 1 && part_id <= 31 )
1610 {
1611 offset = part_id - 1;
1612 mask = 1 << offset;
1613
1615 {
1616 return true;
1617 }
1618 }
1619 else if ( part_id >= 32 && part_id <= 62 )
1620 {
1621 offset = ( part_id % 32 );
1622 mask = 1 << offset;
1623
1625 {
1626 return true;
1627 }
1628 }
1629 else if ( part_id >= 63 && part_id <= 93 )
1630 {
1631 offset = ( part_id % 63 );
1632 mask = 1 << offset;
1633
1635 {
1636 return true;
1637 }
1638 }
1639
1640 return false;
1641 }
1642
1644 {
1647 }
1648
1650 {
1651
1654 }
1655
1657 {
1659 {
1662
1663 switch( build_action_id )
1664 {
1668 }
1669 }
1670 }
1671
1672
1674 {
1676 bool is_base = part.
IsBase();
1679 if ( is_part_built_sync )
1680 {
1682 {
1686
1687 if (is_base)
1688 {
1691 }
1692 }
1693 }
1694 else
1695 {
1697 {
1701
1702 if (is_base)
1703 {
1706 }
1707 }
1708 }
1709
1710
1712 }
1713
1714
1716 {
1719
1720 for ( int i = 0; i < construction_parts.Count(); ++i )
1721 {
1722 string key = construction_parts.GetKey( i );
1725 }
1726
1727
1729 }
1730
1732 {
1735
1736 for ( int i = 0; i < construction_parts.Count(); ++i )
1737 {
1738 string key = construction_parts.GetKey( i );
1740
1741 if ( value.
GetId() ==
id )
1742 {
1743 return value;
1744 }
1745 }
1746
1747 return NULL;
1748 }
1749
1750
1751
1753 {
1755 }
1756
1758 {
1760 }
1761
1763 {
1764 return true;
1765 }
1766
1768 {
1769 return false;
1770 }
1771
1772
1774 {
1777 {
1779 }
1780
1781 return construction_kit;
1782 }
1783
1785 {
1788 {
1790 }
1791 }
1792
1794 {
1796 }
1797
1799 {
1800 return "";
1801 }
1802
1804 {
1807 }
1808
1809
1811 {
1814 }
1815
1816
1818 {
1819 super.OnStoreSave( ctx );
1820
1821
1825
1827 }
1828
1830 {
1831 if ( !super.OnStoreLoad( ctx, version ) )
1832 return false;
1833
1834
1835
1837 {
1839 return false;
1840 }
1842 {
1844 return false;
1845 }
1847 {
1849 return false;
1850 }
1851
1852
1854 {
1856 return false;
1857 }
1858
1859
1860 return true;
1861 }
1862
1864 {
1865 super.AfterStoreLoad();
1866
1868 {
1870 }
1871 }
1872
1874 {
1875
1877
1878
1881
1882
1884 }
1885
1887 {
1888 super.OnCreatePhysics();
1891 }
1892
1894 {
1896 return;
1897
1898 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
1899
1901 return;
1902
1904 string part_name = zone;
1906
1908 {
1909 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
1910
1911 if ( construction_part && construction.IsPartConstructed( part_name ) )
1912 {
1914 construction.DestroyConnectedParts(part_name);
1915 }
1916
1917
1918 if ( part_name.
Contains(
"barbed") )
1919 {
1920 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
1921 if (barbed_wire)
1922 barbed_wire.SetMountedState( false );
1923 }
1924 }
1925 }
1926
1928 {
1930 {
1932 }
1933
1934 super.EEOnAfterLoad();
1935 }
1936
1938 {
1939 super.EEInit();
1940
1941
1943
1944
1945 #ifdef DEVELOPER
1947 #endif
1948 }
1949
1951 {
1952 super.EEItemAttached( item, slot_name );
1953
1957 }
1958
1960 {
1961 super.EEItemDetached( item, slot_name );
1962
1965 }
1966
1967 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
1968 {
1971
1974 }
1975
1976
1978 {
1979 return true;
1980 }
1981
1982
1983
1985 {
1987
1988
1989 if (construtionPart.
IsBase())
1990 {
1992
1993
1995 }
1996
1997
1999
2000
2002
2003
2005
2007
2009
2010
2012
2013
2015 }
2016
2018 {
2019
2021 }
2022
2023
2025 {
2028
2029
2031
2032
2034
2035
2037
2038
2040
2042
2043
2045
2046
2048
2049
2050 if (construtionPart.
IsBase())
2051 {
2052
2054 }
2055 }
2056
2058 {
2059
2061 }
2062
2063
2064 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2065 {
2068
2069
2071
2072
2074
2075
2077
2078
2080
2082
2083
2085
2086
2088
2089
2090 if (construtionPart.
IsBase())
2091 {
2092
2094 }
2095 }
2096
2098 {
2099
2101 }
2102
2105 {
2106 bool process = false;
2107
2108
2112
2113 if (process)
2114 {
2115 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2116 {
2118 return;
2119 }
2120
2122 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2123 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2124
2125
2127 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2128 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2129 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2130 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2131 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2132 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2133 mins = minTmp;
2134 maxs = maxTmp;
2135
2136 maxs[1] = maxs[1] + 0.35;
2137
2139 }
2140 }
2141
2144 {
2147
2148
2150 foreach (
EntityAI entity : foundEntities)
2151 {
2154 }
2155 }
2156
2157
2159 {
2161
2165 }
2166
2168 {
2170
2172 {
2174 }
2175 else
2176 {
2178 }
2179
2181 }
2182
2184 {
2186
2188 foreach (
string slotName : attachmentSlots)
2189 {
2191 }
2192
2193
2196 else
2198
2200 }
2201
2203 {
2204 string slotNameMounted = slot_name + "_Mounted";
2205 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2206
2207 if (attachment)
2208 {
2209 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2210 if (barbedWire && barbedWire.IsMounted())
2212 else
2214
2215 if (is_locked)
2216 {
2217 SetAnimationPhase(slotNameMounted, 0);
2218 SetAnimationPhase(slot_name, 1);
2219 }
2220 else
2221 {
2222 SetAnimationPhase(slotNameMounted, 1);
2223 SetAnimationPhase(slot_name, 0);
2224 }
2225 }
2226 else
2227 {
2228 SetAnimationPhase(slotNameMounted, 1);
2229 SetAnimationPhase(slot_name, 1);
2230
2232 }
2233 }
2234
2235
2237 {
2240
2243
2246
2247 foreach (
string slotName : attachmentSlots)
2248 {
2250 }
2251
2252
2254 {
2257
2259 }
2260 else
2261 {
2264
2266 }
2267
2270 }
2271
2273 {
2274
2276 return;
2277
2278 string slot_name_mounted = slot_name + "_Mounted";
2279 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2280
2281
2283 RemoveProxyPhysics( slot_name_mounted );
2284 RemoveProxyPhysics( slot_name );
2285
2286 if ( attachment )
2287 {
2289 if ( is_locked )
2290 {
2292 AddProxyPhysics( slot_name_mounted );
2293 }
2294 else
2295 {
2297 AddProxyPhysics( slot_name );
2298 }
2299 }
2300 }
2301
2303 {
2304 SetAffectPathgraph( true, false );
2306 }
2307
2309 {
2310 return true;
2311 }
2312
2314 {
2315 return true;
2316 }
2317
2319 {
2320 if ( attachment )
2321 {
2323 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2324
2325 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2326 }
2327
2328 return false;
2329 }
2330
2332 {
2334 }
2335
2336
2338 {
2339 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2340 if (
GetGame().ConfigIsExisting( config_path ) )
2341 {
2343 }
2344 }
2345
2347 {
2348 return true;
2349 }
2350
2352 {
2353 return true;
2354 }
2355
2357 {
2358 return true;
2359 }
2360
2361
2363 {
2365 {
2367 }
2368
2370 }
2371
2373 {
2375 }
2376
2377
2378
2380 {
2381 return super.CanReceiveAttachment(attachment, slotId);
2382 }
2383
2385 {
2386 int attachment_count = GetInventory().AttachmentCount();
2387 if ( attachment_count > 0 )
2388 {
2389 if (
HasBase() && attachment_count == 1 )
2390 {
2391 return false;
2392 }
2393
2394 return true;
2395 }
2396
2397 return false;
2398 }
2399
2401 {
2402 return true;
2403 }
2404
2406 {
2407 return false;
2408 }
2409
2410
2412 {
2413 return false;
2414 }
2415
2417 {
2418 return false;
2419 }
2420
2421
2423 {
2424 return false;
2425 }
2426
2427
2428
2430 {
2431 return true;
2432 }
2433
2435 {
2436 return true;
2437 }
2438
2441 {
2442 return false;
2443 }
2444
2445
2447 {
2448 return true;
2449 }
2450
2451
2453 {
2454 return false;
2455 }
2456
2457
2459 {
2460 return true;
2461 }
2462
2463
2465 {
2466 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2467 {
2468 return false;
2469 }
2470
2471 return true;
2472 }
2473
2475 {
2478
2479 return item;
2480 }
2481
2482
2484 {
2486 {
2487
2489
2490
2493
2495 if ( MemoryPointExists( slot_name + "_min" ) )
2496 {
2497 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2498 }
2499 if ( MemoryPointExists( slot_name + "_max" ) )
2500 {
2501 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2502 }
2503
2504
2507
2508
2511 center = ModelToWorld( center );
2512
2513
2516
2517 areaDamage.SetExtents( extents[0], extents[1] );
2518 areaDamage.SetAreaPosition( center );
2519 areaDamage.SetAreaOrientation( orientation );
2522 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2523 areaDamage.SetAmmoName( "BarbedWireHit" );
2524 areaDamage.Spawn();
2525
2527 }
2528 }
2529
2531 {
2532 if ( angle_deg != 0 )
2533 {
2534
2535 orientation[0] = orientation[0] - angle_deg;
2536
2537
2539 if ( MemoryPointExists( "rotate_axis" ) )
2540 {
2541 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2542 }
2543 float r_center_x = (
Math.
Cos( angle_deg *
Math.
DEG2RAD ) * ( center[0] - rotate_axis[0] ) ) - (
Math.
Sin( angle_deg *
Math.
DEG2RAD ) * ( center[2] - rotate_axis[2] ) ) + rotate_axis[0];
2544 float r_center_z = (
Math.
Sin( angle_deg *
Math.
DEG2RAD ) * ( center[0] - rotate_axis[0] ) ) + (
Math.
Cos( angle_deg *
Math.
DEG2RAD ) * ( center[2] - rotate_axis[2] ) ) + rotate_axis[2];
2545 center[0] = r_center_x;
2546 center[2] = r_center_z;
2547 }
2548 }
2549
2551 {
2553 {
2556 {
2557 if (areaDamage)
2558 {
2559 areaDamage.Destroy();
2560 }
2561
2563 }
2564 }
2565 }
2566
2568 {
2569 return true;
2570 }
2571
2572
2573
2574
2576 {
2578 }
2579
2581 {
2583 }
2584
2586 {
2588 }
2589
2591 {
2593
2594 switch ( material_type )
2595 {
2601 }
2602
2603 return "";
2604 }
2605
2607 {
2609
2610 switch ( material_type )
2611 {
2617 }
2618
2619 return "";
2620 }
2621
2622
2624 {
2626 {
2627
2629 {
2630 SetHealth(slot_name,"Health",item.GetHealth());
2631 }
2632 }
2633 }
2634
2636 {
2637 return 111;
2638 }
2639
2641 {
2642 super.SetActions();
2643
2647 }
2648
2649
2650
2651
2653 {
2654 }
2655
2658 {
2659 return null;
2660 }
2661
2663 {
2665 }
2666
2668 {
2671
2672 Man p;
2673
2674 #ifdef SERVER
2677 if (players.Count())
2678 p = players[0];
2679 #else
2681 #endif
2682
2684 {
2685 bool excluded = false;
2687 if (excludes)
2688 {
2689 foreach (string exclude : excludes)
2690 {
2692 {
2693 excluded = true;
2694 break;
2695 }
2696 }
2697 }
2698
2699 if (!excluded)
2700 {
2702 }
2703 }
2704
2706 }
2707}
2708
2710{
2711#ifdef BSB_DEBUG
2713#else
2714
2715#endif
2716}
2718{
2719#ifdef BSB_DEBUG_SPAM
2721#else
2722
2723#endif
2724}
const int AT_DISMANTLE_PART
const int AT_DESTROY_PART
void AddAction(typename actionName)
void RemoveAction(typename actionName)
void AreaDamageManager(EntityAI parent)
void OnPartDismantledClient(string part_name, int action_id)
const string ANIMATION_DEPLOYED
override int GetHideIconMask()
override void OnStoreSave(ParamsWriteContext ctx)
void SetActionFromSyncData()
bool CheckMemoryPointVerticalDistance(float max_dist, string selection, PlayerBase player)
override void OnDebugSpawn()
array< string > OnDebugSpawnBuildExcludes()
Excludes certain parts from being built by OnDebugSpawn, uses Contains to compare.
void SoundDestroyStart(string part_name)
const string SOUND_BUILD_WOOD_LOG
void SoundBuildStart(string part_name)
void UpdateAttachmentVisuals(string slot_name, bool is_locked)
void CalcDamageAreaRotation(float angle_deg, out vector center, out vector orientation)
override bool CanObstruct()
bool HasAttachmentsBesidesBase()
override void InitItemSounds()
void RegisterPartForSync(int part_id)
const string SOUND_DISMANTLE_METAL
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
void SetPartsAfterStoreLoad()
void DestroyConstruction()
ref array< string > m_HybridAttachments
override string GetFoldSoundset()
string GetDismantleSoundByMaterial(string part_name)
bool IsAttachmentSlotLocked(EntityAI attachment)
override bool IsFacingPlayer(PlayerBase player, string selection)
void OnPartBuiltClient(string part_name, int action_id)
bool HasProperDistance(string selection, PlayerBase player)
override void OnCreatePhysics()
void OnPartBuiltServer(notnull Man player, string part_name, int action_id)
void RegisterActionForSync(int part_id, int action_id)
const string SOUND_BUILD_WOOD_PLANK
void SetPartsFromSyncData()
ref array< string > m_Mountables
const string SOUND_BUILD_WIRE
void ResetActionSyncData()
override string GetInvulnerabilityTypeString()
void OnPartDismantledServer(notnull Man player, string part_name, int action_id)
void CheckForHybridAttachments(EntityAI item, string slot_name)
override void EEOnAfterLoad()
override void EEItemDetached(EntityAI item, string slot_name)
vector GetKitSpawnPosition()
ref Construction m_Construction
bool IsFacingCamera(string selection)
bool CheckSlotVerticalDistance(int slot_id, PlayerBase player)
void GetAttachmentSlots(EntityAI entity, out array< string > attachment_slots)
override bool IsDeployable()
void OnPartDestroyedClient(string part_name, int action_id)
void UnregisterPartForSync(int part_id)
void bsbDebugSpam(string s)
override void OnVariablesSynchronized()
bool PerformRoofCheckForBase(string partName, PlayerBase player, out bool result)
Construction GetConstruction()
void SoundDismantleStart(string part_name)
ConstructionPart GetConstructionPartById(int id)
string GetConstructionKitType()
bool CheckLevelVerticalDistance(float max_dist, string selection, PlayerBase player)
void OnPartDestroyedServer(Man player, string part_name, int action_id, bool destroyed_by_connected_part=false)
bool CanFoldBaseBuildingObject()
override int GetDamageSystemVersionChange()
const string SOUND_DISMANTLE_WOOD_PLANK
override void EEItemAttached(EntityAI item, string slot_name)
const string SOUND_DISMANTLE_WOOD_LOG
class BaseBuildingBase extends ItemBase bsbDebugPrint(string s)
const string SOUND_BUILD_WOOD_STAIRS
ItemBase FoldBaseBuildingObject()
override bool CanPutInCargo(EntityAI parent)
override bool CanUseConstruction()
override void AfterStoreLoad()
void SetPartFromSyncData(ConstructionPart part)
override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
override bool IgnoreOutOfReachCondition()
override bool OnStoreLoad(ParamsReadContext ctx, int version)
override bool ShowZonesHealth()
void UpdateAttachmentPhysics(string slot_name, bool is_locked)
override bool IsPlayerInside(PlayerBase player, string selection)
string GetBuildSoundByMaterial(string part_name)
ItemBase CreateConstructionKit()
const string SOUND_DISMANTLE_WIRE
bool MustBeBuiltFromOutside()
Some buildings can only be built from outside.
override bool IsTakeable()
float m_ConstructionKitHealth
override void EEDelete(EntityAI parent)
override void SetActions()
void HandleItemFalling(ConstructionPart part)
Disconnected temporarily.
void DestroyConstructionKit(ItemBase construction_kit)
void CreateConstructionKitInHands(notnull PlayerBase player)
void ItemFall(vector min, vector max)
Disconnected temporarily.
override bool CanUseConstructionBuild()
void OnSynchronizedClient()
void SynchronizeBaseState()
override bool IsIgnoredByConstruction()
ref map< string, ref AreaDamageManager > m_DamageTriggers
void SetBaseState(bool has_base)
const string SOUND_BUILD_METAL
override string GetLoopFoldSoundset()
void OnSetSlotLock(int slotId, bool locked, bool was_locked)
override bool CanPutIntoHands(EntityAI parent)
bool IsPartBuildInSyncData(int part_id)
override bool CanRemoveFromCargo(EntityAI parent)
const string SOUND_DISMANTLE_WOOD_STAIRS
const int ECE_PLACE_ON_SURFACE
PlayerSpawnPreset slotName
void Construction(BaseBuildingBase parent)
void DayZPlayerUtils()
cannot be instantiated
string GetLoopFoldSoundset()
ItemSoundHandler GetItemSoundHandler()
bool m_FixDamageSystemInit
void ItemSoundHandler(ItemBase parent)
override void SetLoopInterval(float time)
A particular version of the deferred loop used to not damage players inside vehicles.
override void SetDeferDuration(float time)
proto native World GetWorld()
override ScriptCallQueue GetCallQueue(int call_category)
proto native void ConfigGetTextArray(string path, out TStringArray values)
Get array of strings from config on path.
proto native DayZPlayer GetPlayer()
proto native void ObjectDelete(Object obj)
Super root of all classes in Enforce script.
static void Log(string message=LOG_DEFAULT, string plugin=LOG_DEFAULT, string author=LOG_DEFAULT, string label=LOG_DEFAULT, string entity=LOG_DEFAULT)
Prints debug message with normal prio.
Wrapper class for managing sound through SEffectManager.
proto native int GetSlot()
returns slot id if current type is Attachment
static proto native int GetSlotIdFromString(string slot_name)
converts string to slot_id
static proto native owned string GetSlotName(int id)
converts slot_id to string
provides access to slot configuration
override bool CanUseConstruction()
static bool IsBaseBuildingLogEnable()
proto void CallLater(func fn, int delay=0, bool repeat=false, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
adds call into the queue with given parameters and arguments (arguments are held in memory until the ...
proto bool Write(void value_out)
proto bool Read(void value_in)
proto native void GetPlayerList(out array< Man > players)
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
override string GetDebugName()
Serializer ParamsReadContext
proto native CGame GetGame()
Serializer ParamsWriteContext
proto void PrintToRPT(void var)
Prints content of variable to RPT file (performance warning - each write means fflush!...
static proto bool CastTo(out Class to, Class from)
Try to safely down-cast base class to child class.
static proto float Max(float x, float y)
Returns bigger of two given values.
static proto float Min(float x, float y)
Returns smaller of two given values.
static proto float Cos(float angle)
Returns cosinus of angle in radians.
static proto float Sin(float angle)
Returns sinus of angle in radians.
static const float DEG2RAD
class JsonUndergroundAreaTriggerData GetPosition
bool Contains(string sample)
Returns true if sample is substring of string.
proto int ToLower()
Changes string to lowercase. Returns length.