1419{
1421
1423
1425
1427
1433
1434
1435
1441
1447
1449
1453
1454
1456 {
1458
1459
1460 RegisterNetSyncVariableInt( "m_SyncParts01" );
1461 RegisterNetSyncVariableInt( "m_SyncParts02" );
1462 RegisterNetSyncVariableInt( "m_SyncParts03" );
1463 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1464 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1465 RegisterNetSyncVariableBool( "m_HasBase" );
1466
1467
1469
1470 if (ConfigIsExisting("hybridAttachments"))
1471 {
1474 }
1475 if (ConfigIsExisting("mountables"))
1476 {
1479 }
1480
1482 }
1483
1485 {
1486 super.EEDelete(parent);
1487
1489 {
1490 areaDamage.Destroy();
1491 }
1492
1493 }
1494
1496 {
1497 return "disableBaseDamage";
1498 }
1499
1501 {
1502 return true;
1503 }
1504
1506 {
1507 return EInventoryIconVisibility.HIDE_VICINITY;
1508 }
1509
1511 {
1512 super.InitItemSounds();
1513
1517
1522 }
1523
1525 {
1526 return "putDown_FenceKit_SoundSet";
1527 }
1528
1530 {
1531 return "Shelter_Site_Build_Loop_SoundSet";
1532 }
1533
1534
1536 {
1538 {
1539 SetSynchDirty();
1540 }
1541 }
1542
1544 {
1546 super.OnVariablesSynchronized();
1547
1549 }
1550
1552 {
1553
1555
1556
1558
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 else if ( part_id >= 32 && part_id <= 62 )
1607 {
1608 offset = ( part_id % 32 );
1609 mask = 1 << offset;
1610
1612 }
1613 else if ( part_id >= 63 && part_id <= 93 )
1614 {
1615 offset = ( part_id % 63 );
1616 mask = 1 << offset;
1617
1619 }
1620 }
1621
1623 {
1624
1625 int offset;
1626 int mask;
1627
1628 if ( part_id >= 1 && part_id <= 31 )
1629 {
1630 offset = part_id - 1;
1631 mask = 1 << offset;
1632
1634 {
1635 return true;
1636 }
1637 }
1638 else if ( part_id >= 32 && part_id <= 62 )
1639 {
1640 offset = ( part_id % 32 );
1641 mask = 1 << offset;
1642
1644 {
1645 return true;
1646 }
1647 }
1648 else if ( part_id >= 63 && part_id <= 93 )
1649 {
1650 offset = ( part_id % 63 );
1651 mask = 1 << offset;
1652
1654 {
1655 return true;
1656 }
1657 }
1658
1659 return false;
1660 }
1661
1663 {
1666 }
1667
1669 {
1670
1673 }
1674
1676 {
1678 {
1681
1682 switch( build_action_id )
1683 {
1687 }
1688 }
1689 }
1690
1691
1693 {
1695 bool is_base = part.
IsBase();
1698 if ( is_part_built_sync )
1699 {
1701 {
1705
1706 if (is_base)
1707 {
1710 }
1711 }
1712 }
1713 else
1714 {
1716 {
1720
1721 if (is_base)
1722 {
1725 }
1726 }
1727 }
1728
1729
1731 }
1732
1733
1735 {
1738
1739 for ( int i = 0; i < construction_parts.Count(); ++i )
1740 {
1741 string key = construction_parts.GetKey( i );
1744 }
1745
1746
1748 }
1749
1751 {
1754
1755 for ( int i = 0; i < construction_parts.Count(); ++i )
1756 {
1757 string key = construction_parts.GetKey( i );
1759
1760 if ( value.
GetId() ==
id )
1761 {
1762 return value;
1763 }
1764 }
1765
1766 return NULL;
1767 }
1768
1769
1770
1772 {
1774 }
1775
1777 {
1779 }
1780
1782 {
1783 return true;
1784 }
1785
1787 {
1788 return false;
1789 }
1790
1791
1793 {
1796 {
1798 }
1799
1800 return construction_kit;
1801 }
1802
1804 {
1807 {
1809 }
1810 }
1811
1813 {
1815 }
1816
1818 {
1819 return "";
1820 }
1821
1823 {
1826 }
1827
1828
1830 {
1833 }
1834
1835
1837 {
1838 super.OnStoreSave( ctx );
1839
1840
1844
1846 }
1847
1849 {
1850 if ( !super.OnStoreLoad( ctx, version ) )
1851 return false;
1852
1853
1854
1856 {
1858 return false;
1859 }
1861 {
1863 return false;
1864 }
1866 {
1868 return false;
1869 }
1870
1871
1873 {
1875 return false;
1876 }
1877
1878
1879 return true;
1880 }
1881
1883 {
1884 super.AfterStoreLoad();
1885
1887 {
1889 }
1890 }
1891
1893 {
1894
1896
1897
1900
1901
1903 }
1904
1906 {
1907 super.OnCreatePhysics();
1910 }
1911
1913 {
1915 return;
1916
1917 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
1918
1920 return;
1921
1923 string part_name = zone;
1925
1927 {
1928 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
1929
1930 if ( construction_part && construction.IsPartConstructed( part_name ) )
1931 {
1933 construction.DestroyConnectedParts(part_name);
1934 }
1935
1936
1937 if ( part_name.
Contains(
"barbed") )
1938 {
1939 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
1940 if (barbed_wire)
1941 barbed_wire.SetMountedState( false );
1942 }
1943 }
1944 }
1945
1947 {
1949 {
1951 }
1952
1953 super.EEOnAfterLoad();
1954 }
1955
1957 {
1958 super.EEInit();
1959
1960
1962
1963
1964 #ifdef DEVELOPER
1966 #endif
1967 }
1968
1970 {
1971 super.EEItemAttached( item, slot_name );
1972
1976 }
1977
1979 {
1980 super.EEItemDetached( item, slot_name );
1981
1984 }
1985
1986 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
1987 {
1990
1993 }
1994
1995
1997 {
1998 return true;
1999 }
2000
2001
2002
2004 {
2006
2007
2008 if (construtionPart.
IsBase())
2009 {
2011
2012
2014 }
2015
2016
2018
2019
2021
2022
2024
2026
2028
2029
2031
2032
2034 }
2035
2037 {
2038
2040 }
2041
2042
2044 {
2047
2048
2050
2051
2053
2054
2056
2057
2059
2061
2062
2064
2065
2067
2068
2069 if (construtionPart.
IsBase())
2070 {
2071
2073 }
2074 }
2075
2077 {
2078
2080 }
2081
2082
2083 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2084 {
2087
2088
2090
2091
2093
2094
2096
2097
2099
2101
2102
2104
2105
2107
2108
2109 if (construtionPart.
IsBase())
2110 {
2111
2113 }
2114 }
2115
2117 {
2118
2120 }
2121
2124 {
2125 bool process = false;
2126
2127
2131
2132 if (process)
2133 {
2134 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2135 {
2137 return;
2138 }
2139
2141 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2142 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2143
2144
2146 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2147 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2148 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2149 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2150 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2151 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2152 mins = minTmp;
2153 maxs = maxTmp;
2154
2155 maxs[1] = maxs[1] + 0.35;
2156
2158 }
2159 }
2160
2163 {
2166
2167
2169 foreach (
EntityAI entity : foundEntities)
2170 {
2173 }
2174 }
2175
2176
2178 {
2180
2184 }
2185
2187 {
2189
2191 {
2193 }
2194 else
2195 {
2197 }
2198
2200 }
2201
2203 {
2205
2207 foreach (
string slotName : attachmentSlots)
2208 {
2210 }
2211
2212
2215 else
2217
2219 }
2220
2222 {
2223 string slotNameMounted = slot_name + "_Mounted";
2224 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2225
2226 if (attachment)
2227 {
2228 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2229 if (barbedWire && barbedWire.IsMounted())
2231 else
2233
2234 if (is_locked)
2235 {
2236 SetAnimationPhase(slotNameMounted, 0);
2237 SetAnimationPhase(slot_name, 1);
2238 }
2239 else
2240 {
2241 SetAnimationPhase(slotNameMounted, 1);
2242 SetAnimationPhase(slot_name, 0);
2243 }
2244 }
2245 else
2246 {
2247 SetAnimationPhase(slotNameMounted, 1);
2248 SetAnimationPhase(slot_name, 1);
2249
2251 }
2252 }
2253
2254
2256 {
2259
2262
2265
2266 foreach (
string slotName : attachmentSlots)
2267 {
2269 }
2270
2271
2273 {
2276
2278 }
2279 else
2280 {
2283
2285 }
2286
2289 }
2290
2292 {
2293
2295 return;
2296
2297 string slot_name_mounted = slot_name + "_Mounted";
2298 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2299
2300
2302 RemoveProxyPhysics( slot_name_mounted );
2303 RemoveProxyPhysics( slot_name );
2304
2305 if ( attachment )
2306 {
2308 if ( is_locked )
2309 {
2311 AddProxyPhysics( slot_name_mounted );
2312 }
2313 else
2314 {
2316 AddProxyPhysics( slot_name );
2317 }
2318 }
2319 }
2320
2322 {
2323 SetAffectPathgraph( true, false );
2325 }
2326
2328 {
2329 return true;
2330 }
2331
2333 {
2334 return true;
2335 }
2336
2338 {
2339 if ( attachment )
2340 {
2342 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2343
2344 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2345 }
2346
2347 return false;
2348 }
2349
2351 {
2353 }
2354
2355
2357 {
2358 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2359 if (
GetGame().ConfigIsExisting( config_path ) )
2360 {
2362 }
2363 }
2364
2366 {
2367 return true;
2368 }
2369
2371 {
2372 return true;
2373 }
2374
2376 {
2377 return true;
2378 }
2379
2380
2382 {
2384 {
2386 }
2387
2389 }
2390
2392 {
2394 }
2395
2396
2397
2399 {
2400 return super.CanReceiveAttachment(attachment, slotId);
2401 }
2402
2404 {
2405 int attachment_count = GetInventory().AttachmentCount();
2406 if ( attachment_count > 0 )
2407 {
2408 if (
HasBase() && attachment_count == 1 )
2409 {
2410 return false;
2411 }
2412
2413 return true;
2414 }
2415
2416 return false;
2417 }
2418
2420 {
2421 return true;
2422 }
2423
2425 {
2426 return false;
2427 }
2428
2429
2431 {
2432 return false;
2433 }
2434
2436 {
2437 return false;
2438 }
2439
2440
2442 {
2443 return false;
2444 }
2445
2446
2447
2449 {
2450 return true;
2451 }
2452
2454 {
2455 return true;
2456 }
2457
2460 {
2461 return false;
2462 }
2463
2464
2466 {
2467 return true;
2468 }
2469
2470
2472 {
2473 return false;
2474 }
2475
2476
2478 {
2479 return true;
2480 }
2481
2482
2484 {
2485 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2486 {
2487 return false;
2488 }
2489
2490 return true;
2491 }
2492
2494 {
2497
2498 return item;
2499 }
2500
2501
2503 {
2505 {
2506
2508
2509
2512
2514 if ( MemoryPointExists( slot_name + "_min" ) )
2515 {
2516 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2517 }
2518 if ( MemoryPointExists( slot_name + "_max" ) )
2519 {
2520 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2521 }
2522
2523
2526
2527
2530 center = ModelToWorld( center );
2531
2532
2535
2536 areaDamage.SetExtents( extents[0], extents[1] );
2537 areaDamage.SetAreaPosition( center );
2538 areaDamage.SetAreaOrientation( orientation );
2541 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2542 areaDamage.SetAmmoName( "BarbedWireHit" );
2543 areaDamage.Spawn();
2544
2546 }
2547 }
2548
2550 {
2551 if ( angle_deg != 0 )
2552 {
2553
2554 orientation[0] = orientation[0] - angle_deg;
2555
2556
2558 if ( MemoryPointExists( "rotate_axis" ) )
2559 {
2560 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2561 }
2562 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];
2563 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];
2564 center[0] = r_center_x;
2565 center[2] = r_center_z;
2566 }
2567 }
2568
2570 {
2572 {
2575 {
2576 if (areaDamage)
2577 {
2578 areaDamage.Destroy();
2579 }
2580
2582 }
2583 }
2584 }
2585
2587 {
2588 return true;
2589 }
2590
2591
2592
2593
2595 {
2597 }
2598
2600 {
2602 }
2603
2605 {
2607 }
2608
2610 {
2612
2613 switch ( material_type )
2614 {
2620 }
2621
2622 return "";
2623 }
2624
2626 {
2628
2629 switch ( material_type )
2630 {
2636 }
2637
2638 return "";
2639 }
2640
2641
2643 {
2645 {
2646
2648 {
2649 SetHealth(slot_name,"Health",item.GetHealth());
2650 }
2651 }
2652 }
2653
2655 {
2656 return 111;
2657 }
2658
2660 {
2661 super.SetActions();
2662
2666 }
2667
2668
2669
2670
2672 {
2673 }
2674
2677 {
2678 return null;
2679 }
2680
2682 {
2684 }
2685
2687 {
2690
2691 Man p;
2692
2693 #ifdef SERVER
2696 if (players.Count())
2697 p = players[0];
2698 #else
2700 #endif
2701
2703 {
2704 bool excluded = false;
2706 if (excludes)
2707 {
2708 foreach (string exclude : excludes)
2709 {
2711 {
2712 excluded = true;
2713 break;
2714 }
2715 }
2716 }
2717
2718 if (!excluded)
2719 {
2721 }
2722 }
2723
2725 }
2726}
2727
2729{
2730#ifdef BSB_DEBUG
2732#else
2733
2734#endif
2735}
2737{
2738#ifdef BSB_DEBUG_SPAM
2740#else
2741
2742#endif
2743}
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.