1405{
1407
1409
1411
1413
1419
1420
1421
1427
1433
1435
1439
1440
1442 {
1444
1445
1446 RegisterNetSyncVariableInt( "m_SyncParts01" );
1447 RegisterNetSyncVariableInt( "m_SyncParts02" );
1448 RegisterNetSyncVariableInt( "m_SyncParts03" );
1449 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1450 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1451 RegisterNetSyncVariableBool( "m_HasBase" );
1452
1453
1455
1456 if (ConfigIsExisting("hybridAttachments"))
1457 {
1460 }
1461 if (ConfigIsExisting("mountables"))
1462 {
1465 }
1466
1468 }
1469
1471 {
1472 super.EEDelete(parent);
1473
1475 {
1476 areaDamage.Destroy();
1477 }
1478
1479 }
1480
1482 {
1483 return "disableBaseDamage";
1484 }
1485
1487 {
1488 return true;
1489 }
1490
1492 {
1493 return EInventoryIconVisibility.HIDE_VICINITY;
1494 }
1495
1497 {
1498 super.InitItemSounds();
1499
1503
1508 }
1509
1511 {
1512 return "putDown_FenceKit_SoundSet";
1513 }
1514
1516 {
1517 return "Shelter_Site_Build_Loop_SoundSet";
1518 }
1519
1520
1522 {
1524 {
1525 SetSynchDirty();
1526 }
1527 }
1528
1530 {
1532 super.OnVariablesSynchronized();
1533
1535 }
1536
1538 {
1539
1541
1542
1544
1545
1547 }
1548
1549
1551 {
1552
1553 int offset;
1554 int mask;
1555
1556 if ( part_id >= 1 && part_id <= 31 )
1557 {
1558 offset = part_id - 1;
1559 mask = 1 << offset;
1560
1562 }
1563 else if ( part_id >= 32 && part_id <= 62 )
1564 {
1565 offset = ( part_id % 32 );
1566 mask = 1 << offset;
1567
1569 }
1570 else if ( part_id >= 63 && part_id <= 93 )
1571 {
1572 offset = ( part_id % 63 );
1573 mask = 1 << offset;
1574
1576 }
1577 }
1578
1580 {
1581
1582 int offset;
1583 int mask;
1584
1585 if ( part_id >= 1 && part_id <= 31 )
1586 {
1587 offset = part_id - 1;
1588 mask = 1 << offset;
1589
1591 }
1592 else if ( part_id >= 32 && part_id <= 62 )
1593 {
1594 offset = ( part_id % 32 );
1595 mask = 1 << offset;
1596
1598 }
1599 else if ( part_id >= 63 && part_id <= 93 )
1600 {
1601 offset = ( part_id % 63 );
1602 mask = 1 << offset;
1603
1605 }
1606 }
1607
1609 {
1610
1611 int offset;
1612 int mask;
1613
1614 if ( part_id >= 1 && part_id <= 31 )
1615 {
1616 offset = part_id - 1;
1617 mask = 1 << offset;
1618
1620 {
1621 return true;
1622 }
1623 }
1624 else if ( part_id >= 32 && part_id <= 62 )
1625 {
1626 offset = ( part_id % 32 );
1627 mask = 1 << offset;
1628
1630 {
1631 return true;
1632 }
1633 }
1634 else if ( part_id >= 63 && part_id <= 93 )
1635 {
1636 offset = ( part_id % 63 );
1637 mask = 1 << offset;
1638
1640 {
1641 return true;
1642 }
1643 }
1644
1645 return false;
1646 }
1647
1649 {
1652 }
1653
1655 {
1656
1659 }
1660
1662 {
1664 {
1667
1668 switch( build_action_id )
1669 {
1673 }
1674 }
1675 }
1676
1677
1679 {
1681 bool is_base = part.
IsBase();
1684 if ( is_part_built_sync )
1685 {
1687 {
1691
1692 if (is_base)
1693 {
1696 }
1697 }
1698 }
1699 else
1700 {
1702 {
1706
1707 if (is_base)
1708 {
1711 }
1712 }
1713 }
1714
1715
1717 }
1718
1719
1721 {
1724
1725 for ( int i = 0; i < construction_parts.Count(); ++i )
1726 {
1727 string key = construction_parts.GetKey( i );
1730 }
1731
1732
1734 }
1735
1737 {
1740
1741 for ( int i = 0; i < construction_parts.Count(); ++i )
1742 {
1743 string key = construction_parts.GetKey( i );
1745
1746 if ( value.
GetId() ==
id )
1747 {
1748 return value;
1749 }
1750 }
1751
1752 return NULL;
1753 }
1754
1755
1756
1758 {
1760 }
1761
1763 {
1765 }
1766
1768 {
1769 return true;
1770 }
1771
1773 {
1774 return false;
1775 }
1776
1777
1779 {
1782 {
1784 }
1785
1786 return construction_kit;
1787 }
1788
1790 {
1793 {
1795 }
1796 }
1797
1799 {
1801 }
1802
1804 {
1805 return "";
1806 }
1807
1809 {
1812 }
1813
1814
1816 {
1819 }
1820
1821
1823 {
1824 super.OnStoreSave( ctx );
1825
1826
1830
1832 }
1833
1835 {
1836 if ( !super.OnStoreLoad( ctx, version ) )
1837 return false;
1838
1839
1840
1842 {
1844 return false;
1845 }
1847 {
1849 return false;
1850 }
1852 {
1854 return false;
1855 }
1856
1857
1859 {
1861 return false;
1862 }
1863
1864
1865 return true;
1866 }
1867
1869 {
1870 super.AfterStoreLoad();
1871
1873 {
1875 }
1876 }
1877
1879 {
1880
1882
1883
1886
1887
1889 }
1890
1892 {
1893 super.OnCreatePhysics();
1896 }
1897
1899 {
1901 return;
1902
1903 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
1904
1906 return;
1907
1909 string part_name = zone;
1911
1913 {
1914 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
1915
1916 if ( construction_part && construction.IsPartConstructed( part_name ) )
1917 {
1919 construction.DestroyConnectedParts(part_name);
1920 }
1921
1922
1923 if ( part_name.
Contains(
"barbed") )
1924 {
1925 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
1926 if (barbed_wire)
1927 barbed_wire.SetMountedState( false );
1928 }
1929 }
1930 }
1931
1933 {
1935 {
1937 }
1938
1939 super.EEOnAfterLoad();
1940 }
1941
1943 {
1944 super.EEInit();
1945
1946
1948
1949
1950 #ifdef DEVELOPER
1952 #endif
1953 }
1954
1956 {
1957 super.EEItemAttached( item, slot_name );
1958
1962 }
1963
1965 {
1966 super.EEItemDetached( item, slot_name );
1967
1970 }
1971
1972 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
1973 {
1976
1979 }
1980
1981
1983 {
1984 return true;
1985 }
1986
1987
1988
1990 {
1992
1993
1994 if (construtionPart.
IsBase())
1995 {
1997
1998
2000 }
2001
2002
2004
2005
2007
2008
2010
2012
2014
2015
2017
2018
2020 }
2021
2023 {
2024
2026 }
2027
2028
2030 {
2033
2034
2036
2037
2039
2040
2042
2043
2045
2047
2048
2050
2051
2053
2054
2055 if (construtionPart.
IsBase())
2056 {
2057
2059 }
2060 }
2061
2063 {
2064
2066 }
2067
2068
2069 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2070 {
2073
2074
2076
2077
2079
2080
2082
2083
2085
2087
2088
2090
2091
2093
2094
2095 if (construtionPart.
IsBase())
2096 {
2097
2099 }
2100 }
2101
2103 {
2104
2106 }
2107
2110 {
2111 bool process = false;
2112
2113
2117
2118 if (process)
2119 {
2120 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2121 {
2123 return;
2124 }
2125
2127 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2128 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2129
2130
2132 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2133 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2134 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2135 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2136 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2137 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2138 mins = minTmp;
2139 maxs = maxTmp;
2140
2141 maxs[1] = maxs[1] + 0.35;
2142
2144 }
2145 }
2146
2149 {
2152
2153
2155 foreach (
EntityAI entity : foundEntities)
2156 {
2159 }
2160 }
2161
2162
2164 {
2166
2170 }
2171
2173 {
2175
2177 {
2179 }
2180 else
2181 {
2183 }
2184
2186 }
2187
2189 {
2191
2193 foreach (
string slotName : attachmentSlots)
2194 {
2196 }
2197
2198
2201 else
2203
2205 }
2206
2208 {
2209 string slotNameMounted = slot_name + "_Mounted";
2210 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2211
2212 if (attachment)
2213 {
2214 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2215 if (barbedWire && barbedWire.IsMounted())
2217 else
2219
2220 if (is_locked)
2221 {
2222 SetAnimationPhase(slotNameMounted, 0);
2223 SetAnimationPhase(slot_name, 1);
2224 }
2225 else
2226 {
2227 SetAnimationPhase(slotNameMounted, 1);
2228 SetAnimationPhase(slot_name, 0);
2229 }
2230 }
2231 else
2232 {
2233 SetAnimationPhase(slotNameMounted, 1);
2234 SetAnimationPhase(slot_name, 1);
2235
2237 }
2238 }
2239
2240
2242 {
2245
2248
2251
2252 foreach (
string slotName : attachmentSlots)
2253 {
2255 }
2256
2257
2259 {
2262
2264 }
2265 else
2266 {
2269
2271 }
2272
2275 }
2276
2278 {
2279
2281 return;
2282
2283 string slot_name_mounted = slot_name + "_Mounted";
2284 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2285
2286
2288 RemoveProxyPhysics( slot_name_mounted );
2289 RemoveProxyPhysics( slot_name );
2290
2291 if ( attachment )
2292 {
2294 if ( is_locked )
2295 {
2297 AddProxyPhysics( slot_name_mounted );
2298 }
2299 else
2300 {
2302 AddProxyPhysics( slot_name );
2303 }
2304 }
2305 }
2306
2308 {
2309 SetAffectPathgraph( true, false );
2311 }
2312
2314 {
2315 return true;
2316 }
2317
2319 {
2320 return true;
2321 }
2322
2324 {
2325 if ( attachment )
2326 {
2328 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2329
2330 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2331 }
2332
2333 return false;
2334 }
2335
2337 {
2339 }
2340
2341
2343 {
2344 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2345 if (
GetGame().ConfigIsExisting( config_path ) )
2346 {
2348 }
2349 }
2350
2352 {
2353 return true;
2354 }
2355
2357 {
2358 return true;
2359 }
2360
2362 {
2363 return true;
2364 }
2365
2366
2368 {
2370 {
2372 }
2373
2375 }
2376
2378 {
2380 }
2381
2382
2383
2385 {
2386 return super.CanReceiveAttachment(attachment, slotId);
2387 }
2388
2390 {
2391 int attachment_count = GetInventory().AttachmentCount();
2392 if ( attachment_count > 0 )
2393 {
2394 if (
HasBase() && attachment_count == 1 )
2395 {
2396 return false;
2397 }
2398
2399 return true;
2400 }
2401
2402 return false;
2403 }
2404
2406 {
2407 return true;
2408 }
2409
2411 {
2412 return false;
2413 }
2414
2415
2417 {
2418 return false;
2419 }
2420
2422 {
2423 return false;
2424 }
2425
2426
2428 {
2429 return false;
2430 }
2431
2432
2433
2435 {
2436 return true;
2437 }
2438
2440 {
2441 return true;
2442 }
2443
2446 {
2447 return false;
2448 }
2449
2450
2452 {
2453 return true;
2454 }
2455
2456
2458 {
2459 return false;
2460 }
2461
2462
2464 {
2465 return true;
2466 }
2467
2468
2470 {
2471 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2472 {
2473 return false;
2474 }
2475
2476 return true;
2477 }
2478
2480 {
2483
2484 return item;
2485 }
2486
2487
2489 {
2491 {
2492
2494
2495
2498
2500 if ( MemoryPointExists( slot_name + "_min" ) )
2501 {
2502 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2503 }
2504 if ( MemoryPointExists( slot_name + "_max" ) )
2505 {
2506 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2507 }
2508
2509
2512
2513
2516 center = ModelToWorld( center );
2517
2518
2521
2522 areaDamage.SetExtents( extents[0], extents[1] );
2523 areaDamage.SetAreaPosition( center );
2524 areaDamage.SetAreaOrientation( orientation );
2527 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2528 areaDamage.SetAmmoName( "BarbedWireHit" );
2529 areaDamage.Spawn();
2530
2532 }
2533 }
2534
2536 {
2537 if ( angle_deg != 0 )
2538 {
2539
2540 orientation[0] = orientation[0] - angle_deg;
2541
2542
2544 if ( MemoryPointExists( "rotate_axis" ) )
2545 {
2546 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2547 }
2548 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];
2549 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];
2550 center[0] = r_center_x;
2551 center[2] = r_center_z;
2552 }
2553 }
2554
2556 {
2558 {
2561 {
2562 if (areaDamage)
2563 {
2564 areaDamage.Destroy();
2565 }
2566
2568 }
2569 }
2570 }
2571
2573 {
2574 return true;
2575 }
2576
2577
2578
2579
2581 {
2583 }
2584
2586 {
2588 }
2589
2591 {
2593 }
2594
2596 {
2598
2599 switch ( material_type )
2600 {
2606 }
2607
2608 return "";
2609 }
2610
2612 {
2614
2615 switch ( material_type )
2616 {
2622 }
2623
2624 return "";
2625 }
2626
2627
2629 {
2631 {
2632
2634 {
2635 SetHealth(slot_name,"Health",item.GetHealth());
2636 }
2637 }
2638 }
2639
2641 {
2642 return 111;
2643 }
2644
2646 {
2647 super.SetActions();
2648
2652 }
2653
2654
2655
2656
2658 {
2659 }
2660
2663 {
2664 return null;
2665 }
2666
2668 {
2670 }
2671
2673 {
2676
2677 Man p;
2678
2679 #ifdef SERVER
2682 if (players.Count())
2683 p = players[0];
2684 #else
2686 #endif
2687
2689 {
2690 bool excluded = false;
2692 if (excludes)
2693 {
2694 foreach (string exclude : excludes)
2695 {
2697 {
2698 excluded = true;
2699 break;
2700 }
2701 }
2702 }
2703
2704 if (!excluded)
2705 {
2707 }
2708 }
2709
2711 }
2712}
2713
2715{
2716#ifdef BSB_DEBUG
2718#else
2719
2720#endif
2721}
2723{
2724#ifdef BSB_DEBUG_SPAM
2726#else
2727
2728#endif
2729}
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.