1390{
1392
1394
1396
1398
1404
1405
1406
1412
1418
1420
1424
1425
1427 {
1429
1430
1431 RegisterNetSyncVariableInt( "m_SyncParts01" );
1432 RegisterNetSyncVariableInt( "m_SyncParts02" );
1433 RegisterNetSyncVariableInt( "m_SyncParts03" );
1434 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1435 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1436 RegisterNetSyncVariableBool( "m_HasBase" );
1437
1438
1440
1441 if (ConfigIsExisting("hybridAttachments"))
1442 {
1445 }
1446 if (ConfigIsExisting("mountables"))
1447 {
1450 }
1451
1453 }
1454
1456 {
1457 super.EEDelete(parent);
1458
1460 {
1461 areaDamage.Destroy();
1462 }
1463
1464 }
1465
1467 {
1468 return "disableBaseDamage";
1469 }
1470
1472 {
1473 return true;
1474 }
1475
1477 {
1478 return EInventoryIconVisibility.HIDE_VICINITY;
1479 }
1480
1482 {
1483 super.InitItemSounds();
1484
1488
1493 }
1494
1496 {
1497 return "putDown_FenceKit_SoundSet";
1498 }
1499
1501 {
1502 return "Shelter_Site_Build_Loop_SoundSet";
1503 }
1504
1505
1507 {
1509 {
1510 SetSynchDirty();
1511 }
1512 }
1513
1515 {
1517 super.OnVariablesSynchronized();
1518
1520 }
1521
1523 {
1524
1526
1527
1529
1530
1532 }
1533
1534
1536 {
1537
1538 int offset;
1539 int mask;
1540
1541 if ( part_id >= 1 && part_id <= 31 )
1542 {
1543 offset = part_id - 1;
1544 mask = 1 << offset;
1545
1547 }
1548 else if ( part_id >= 32 && part_id <= 62 )
1549 {
1550 offset = ( part_id % 32 );
1551 mask = 1 << offset;
1552
1554 }
1555 else if ( part_id >= 63 && part_id <= 93 )
1556 {
1557 offset = ( part_id % 63 );
1558 mask = 1 << offset;
1559
1561 }
1562 }
1563
1565 {
1566
1567 int offset;
1568 int mask;
1569
1570 if ( part_id >= 1 && part_id <= 31 )
1571 {
1572 offset = part_id - 1;
1573 mask = 1 << offset;
1574
1576 }
1577 else if ( part_id >= 32 && part_id <= 62 )
1578 {
1579 offset = ( part_id % 32 );
1580 mask = 1 << offset;
1581
1583 }
1584 else if ( part_id >= 63 && part_id <= 93 )
1585 {
1586 offset = ( part_id % 63 );
1587 mask = 1 << offset;
1588
1590 }
1591 }
1592
1594 {
1595
1596 int offset;
1597 int mask;
1598
1599 if ( part_id >= 1 && part_id <= 31 )
1600 {
1601 offset = part_id - 1;
1602 mask = 1 << offset;
1603
1605 {
1606 return true;
1607 }
1608 }
1609 else if ( part_id >= 32 && part_id <= 62 )
1610 {
1611 offset = ( part_id % 32 );
1612 mask = 1 << offset;
1613
1615 {
1616 return true;
1617 }
1618 }
1619 else if ( part_id >= 63 && part_id <= 93 )
1620 {
1621 offset = ( part_id % 63 );
1622 mask = 1 << offset;
1623
1625 {
1626 return true;
1627 }
1628 }
1629
1630 return false;
1631 }
1632
1634 {
1637 }
1638
1640 {
1641
1644 }
1645
1647 {
1649 {
1652
1653 switch( build_action_id )
1654 {
1658 }
1659 }
1660 }
1661
1662
1664 {
1666 bool is_base = part.
IsBase();
1669 if ( is_part_built_sync )
1670 {
1672 {
1676
1677 if (is_base)
1678 {
1681 }
1682 }
1683 }
1684 else
1685 {
1687 {
1691
1692 if (is_base)
1693 {
1696 }
1697 }
1698 }
1699
1700
1702 }
1703
1704
1706 {
1709
1710 for ( int i = 0; i < construction_parts.Count(); ++i )
1711 {
1712 string key = construction_parts.GetKey( i );
1715 }
1716
1717
1719 }
1720
1722 {
1725
1726 for ( int i = 0; i < construction_parts.Count(); ++i )
1727 {
1728 string key = construction_parts.GetKey( i );
1730
1731 if ( value.
GetId() ==
id )
1732 {
1733 return value;
1734 }
1735 }
1736
1737 return NULL;
1738 }
1739
1740
1741
1743 {
1745 }
1746
1748 {
1750 }
1751
1753 {
1754 return true;
1755 }
1756
1758 {
1759 return false;
1760 }
1761
1762
1764 {
1767 {
1769 }
1770
1771 return construction_kit;
1772 }
1773
1775 {
1778 {
1780 }
1781 }
1782
1784 {
1786 }
1787
1789 {
1790 return "";
1791 }
1792
1794 {
1797 }
1798
1799
1801 {
1804 }
1805
1806
1808 {
1809 super.OnStoreSave( ctx );
1810
1811
1815
1817 }
1818
1820 {
1821 if ( !super.OnStoreLoad( ctx, version ) )
1822 return false;
1823
1824
1825
1827 {
1829 return false;
1830 }
1832 {
1834 return false;
1835 }
1837 {
1839 return false;
1840 }
1841
1842
1844 {
1846 return false;
1847 }
1848
1849
1850 return true;
1851 }
1852
1854 {
1855 super.AfterStoreLoad();
1856
1858 {
1860 }
1861 }
1862
1864 {
1865
1867
1868
1871
1872
1874 }
1875
1877 {
1878 super.OnCreatePhysics();
1881 }
1882
1884 {
1886 return;
1887
1888 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
1889
1891 return;
1892
1894 string part_name = zone;
1896
1898 {
1899 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
1900
1901 if ( construction_part && construction.IsPartConstructed( part_name ) )
1902 {
1904 construction.DestroyConnectedParts(part_name);
1905 }
1906
1907
1908 if ( part_name.
Contains(
"barbed") )
1909 {
1910 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
1911 if (barbed_wire)
1912 barbed_wire.SetMountedState( false );
1913 }
1914 }
1915 }
1916
1918 {
1920 {
1922 }
1923
1924 super.EEOnAfterLoad();
1925 }
1926
1928 {
1929 super.EEInit();
1930
1931
1933
1934
1935 #ifdef DEVELOPER
1937 #endif
1938 }
1939
1941 {
1942 super.EEItemAttached( item, slot_name );
1943
1947 }
1948
1950 {
1951 super.EEItemDetached( item, slot_name );
1952
1955 }
1956
1957 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
1958 {
1961
1964 }
1965
1966
1968 {
1969 return true;
1970 }
1971
1972
1973
1975 {
1977
1978
1979 if (construtionPart.
IsBase())
1980 {
1982
1983
1985 }
1986
1987
1989
1990
1992
1993
1995
1997
1999
2000
2002
2003
2005 }
2006
2008 {
2009
2011 }
2012
2013
2015 {
2018
2019
2021
2022
2024
2025
2027
2028
2030
2032
2033
2035
2036
2038
2039
2040 if (construtionPart.
IsBase())
2041 {
2042
2044 }
2045 }
2046
2048 {
2049
2051 }
2052
2053
2054 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2055 {
2058
2059
2061
2062
2064
2065
2067
2068
2070
2072
2073
2075
2076
2078
2079
2080 if (construtionPart.
IsBase())
2081 {
2082
2084 }
2085 }
2086
2088 {
2089
2091 }
2092
2095 {
2096 bool process = false;
2097
2098
2102
2103 if (process)
2104 {
2105 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2106 {
2108 return;
2109 }
2110
2112 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2113 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2114
2115
2117 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2118 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2119 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2120 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2121 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2122 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2123 mins = minTmp;
2124 maxs = maxTmp;
2125
2126 maxs[1] = maxs[1] + 0.35;
2127
2129 }
2130 }
2131
2134 {
2137
2138
2140 foreach (
EntityAI entity : foundEntities)
2141 {
2144 }
2145 }
2146
2147
2149 {
2151
2155 }
2156
2158 {
2160
2162 {
2164 }
2165 else
2166 {
2168 }
2169
2171 }
2172
2174 {
2176
2178 foreach (
string slotName : attachmentSlots)
2179 {
2181 }
2182
2183
2186 else
2188
2190 }
2191
2193 {
2194 string slotNameMounted = slot_name + "_Mounted";
2195 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2196
2197 if (attachment)
2198 {
2199 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2200 if (barbedWire && barbedWire.IsMounted())
2202 else
2204
2205 if (is_locked)
2206 {
2207 SetAnimationPhase(slotNameMounted, 0);
2208 SetAnimationPhase(slot_name, 1);
2209 }
2210 else
2211 {
2212 SetAnimationPhase(slotNameMounted, 1);
2213 SetAnimationPhase(slot_name, 0);
2214 }
2215 }
2216 else
2217 {
2218 SetAnimationPhase(slotNameMounted, 1);
2219 SetAnimationPhase(slot_name, 1);
2220
2222 }
2223 }
2224
2225
2227 {
2230
2233
2236
2237 foreach (
string slotName : attachmentSlots)
2238 {
2240 }
2241
2242
2244 {
2247
2249 }
2250 else
2251 {
2254
2256 }
2257
2260 }
2261
2263 {
2264
2266 return;
2267
2268 string slot_name_mounted = slot_name + "_Mounted";
2269 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2270
2271
2273 RemoveProxyPhysics( slot_name_mounted );
2274 RemoveProxyPhysics( slot_name );
2275
2276 if ( attachment )
2277 {
2279 if ( is_locked )
2280 {
2282 AddProxyPhysics( slot_name_mounted );
2283 }
2284 else
2285 {
2287 AddProxyPhysics( slot_name );
2288 }
2289 }
2290 }
2291
2293 {
2294 SetAffectPathgraph( true, false );
2296 }
2297
2299 {
2300 return true;
2301 }
2302
2304 {
2305 return true;
2306 }
2307
2309 {
2310 if ( attachment )
2311 {
2313 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2314
2315 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2316 }
2317
2318 return false;
2319 }
2320
2322 {
2324 }
2325
2326
2328 {
2329 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2330 if (
GetGame().ConfigIsExisting( config_path ) )
2331 {
2333 }
2334 }
2335
2337 {
2338 return true;
2339 }
2340
2342 {
2343 return true;
2344 }
2345
2347 {
2348 return true;
2349 }
2350
2351
2353 {
2355 {
2357 }
2358
2360 }
2361
2363 {
2365 }
2366
2367
2368
2370 {
2371 return super.CanReceiveAttachment(attachment, slotId);
2372 }
2373
2375 {
2376 int attachment_count = GetInventory().AttachmentCount();
2377 if ( attachment_count > 0 )
2378 {
2379 if (
HasBase() && attachment_count == 1 )
2380 {
2381 return false;
2382 }
2383
2384 return true;
2385 }
2386
2387 return false;
2388 }
2389
2391 {
2392 return true;
2393 }
2394
2396 {
2397 return false;
2398 }
2399
2400
2402 {
2403 return false;
2404 }
2405
2407 {
2408 return false;
2409 }
2410
2411
2413 {
2414 return false;
2415 }
2416
2417
2418
2420 {
2421 return true;
2422 }
2423
2425 {
2426 return true;
2427 }
2428
2431 {
2432 return false;
2433 }
2434
2435
2437 {
2438 return true;
2439 }
2440
2441
2443 {
2444 return false;
2445 }
2446
2447
2449 {
2450 return true;
2451 }
2452
2453
2455 {
2456 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2457 {
2458 return false;
2459 }
2460
2461 return true;
2462 }
2463
2465 {
2468
2469 return item;
2470 }
2471
2472
2474 {
2476 {
2477
2479
2480
2483
2485 if ( MemoryPointExists( slot_name + "_min" ) )
2486 {
2487 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2488 }
2489 if ( MemoryPointExists( slot_name + "_max" ) )
2490 {
2491 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2492 }
2493
2494
2497
2498
2501 center = ModelToWorld( center );
2502
2503
2506
2507 areaDamage.SetExtents( extents[0], extents[1] );
2508 areaDamage.SetAreaPosition( center );
2509 areaDamage.SetAreaOrientation( orientation );
2512 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2513 areaDamage.SetAmmoName( "BarbedWireHit" );
2514 areaDamage.Spawn();
2515
2517 }
2518 }
2519
2521 {
2522 if ( angle_deg != 0 )
2523 {
2524
2525 orientation[0] = orientation[0] - angle_deg;
2526
2527
2529 if ( MemoryPointExists( "rotate_axis" ) )
2530 {
2531 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2532 }
2533 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];
2534 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];
2535 center[0] = r_center_x;
2536 center[2] = r_center_z;
2537 }
2538 }
2539
2541 {
2543 {
2546 {
2547 if (areaDamage)
2548 {
2549 areaDamage.Destroy();
2550 }
2551
2553 }
2554 }
2555 }
2556
2558 {
2559 return true;
2560 }
2561
2562
2563
2564
2566 {
2568 }
2569
2571 {
2573 }
2574
2576 {
2578 }
2579
2581 {
2583
2584 switch ( material_type )
2585 {
2591 }
2592
2593 return "";
2594 }
2595
2597 {
2599
2600 switch ( material_type )
2601 {
2607 }
2608
2609 return "";
2610 }
2611
2612
2614 {
2616 {
2617
2619 {
2620 SetHealth(slot_name,"Health",item.GetHealth());
2621 }
2622 }
2623 }
2624
2626 {
2627 return 111;
2628 }
2629
2631 {
2632 super.SetActions();
2633
2637 }
2638
2639
2640
2641
2643 {
2644 }
2645
2648 {
2649 return null;
2650 }
2651
2653 {
2655 }
2656
2658 {
2661
2662 Man p;
2663
2664 #ifdef SERVER
2667 if (players.Count())
2668 p = players[0];
2669 #else
2671 #endif
2672
2674 {
2675 bool excluded = false;
2677 if (excludes)
2678 {
2679 foreach (string exclude : excludes)
2680 {
2682 {
2683 excluded = true;
2684 break;
2685 }
2686 }
2687 }
2688
2689 if (!excluded)
2690 {
2692 }
2693 }
2694
2696 }
2697}
2698
2700{
2701#ifdef BSB_DEBUG
2703#else
2704
2705#endif
2706}
2708{
2709#ifdef BSB_DEBUG_SPAM
2711#else
2712
2713#endif
2714}
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.