1557{
1559
1561
1563
1565
1571
1572
1573
1579
1585
1587
1591
1592
1594 {
1596
1597
1598 RegisterNetSyncVariableInt( "m_SyncParts01" );
1599 RegisterNetSyncVariableInt( "m_SyncParts02" );
1600 RegisterNetSyncVariableInt( "m_SyncParts03" );
1601 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1602 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1603 RegisterNetSyncVariableBool( "m_HasBase" );
1604
1605
1607
1608 if (ConfigIsExisting("hybridAttachments"))
1609 {
1612 }
1613 if (ConfigIsExisting("mountables"))
1614 {
1617 }
1618
1620 }
1621
1623 {
1624 super.EEDelete(parent);
1625
1627 {
1628 areaDamage.Destroy();
1629 }
1630
1631 }
1632
1634 {
1635 return "disableBaseDamage";
1636 }
1637
1639 {
1640 return true;
1641 }
1642
1644 {
1645 return EInventoryIconVisibility.HIDE_VICINITY;
1646 }
1647
1649 {
1650 super.InitItemSounds();
1651
1655
1660 }
1661
1663 {
1664 return "putDown_FenceKit_SoundSet";
1665 }
1666
1668 {
1669 return "Shelter_Site_Build_Loop_SoundSet";
1670 }
1671
1672
1674 {
1676 {
1677 SetSynchDirty();
1678 }
1679 }
1680
1682 {
1684 super.OnVariablesSynchronized();
1685
1687 }
1688
1690 {
1691
1693
1694
1696
1697
1699 }
1700
1701
1703 {
1704
1705 int offset;
1706 int mask;
1707
1708 if ( part_id >= 1 && part_id <= 31 )
1709 {
1710 offset = part_id - 1;
1711 mask = 1 << offset;
1712
1714 }
1715 else if ( part_id >= 32 && part_id <= 62 )
1716 {
1717 offset = ( part_id % 32 );
1718 mask = 1 << offset;
1719
1721 }
1722 else if ( part_id >= 63 && part_id <= 93 )
1723 {
1724 offset = ( part_id % 63 );
1725 mask = 1 << offset;
1726
1728 }
1729 }
1730
1732 {
1733
1734 int offset;
1735 int mask;
1736
1737 if ( part_id >= 1 && part_id <= 31 )
1738 {
1739 offset = part_id - 1;
1740 mask = 1 << offset;
1741
1743 }
1744 else if ( part_id >= 32 && part_id <= 62 )
1745 {
1746 offset = ( part_id % 32 );
1747 mask = 1 << offset;
1748
1750 }
1751 else if ( part_id >= 63 && part_id <= 93 )
1752 {
1753 offset = ( part_id % 63 );
1754 mask = 1 << offset;
1755
1757 }
1758 }
1759
1761 {
1762
1763 int offset;
1764 int mask;
1765
1766 if ( part_id >= 1 && part_id <= 31 )
1767 {
1768 offset = part_id - 1;
1769 mask = 1 << offset;
1770
1772 {
1773 return true;
1774 }
1775 }
1776 else if ( part_id >= 32 && part_id <= 62 )
1777 {
1778 offset = ( part_id % 32 );
1779 mask = 1 << offset;
1780
1782 {
1783 return true;
1784 }
1785 }
1786 else if ( part_id >= 63 && part_id <= 93 )
1787 {
1788 offset = ( part_id % 63 );
1789 mask = 1 << offset;
1790
1792 {
1793 return true;
1794 }
1795 }
1796
1797 return false;
1798 }
1799
1801 {
1804 }
1805
1807 {
1808
1811 }
1812
1814 {
1816 {
1819
1820 switch( build_action_id )
1821 {
1825 }
1826 }
1827 }
1828
1829
1831 {
1833 bool is_base = part.
IsBase();
1836 if ( is_part_built_sync )
1837 {
1839 {
1843
1844 if (is_base)
1845 {
1848 }
1849 }
1850 }
1851 else
1852 {
1854 {
1858
1859 if (is_base)
1860 {
1863 }
1864 }
1865 }
1866
1867
1869 }
1870
1871
1873 {
1876
1877 for ( int i = 0; i < construction_parts.Count(); ++i )
1878 {
1879 string key = construction_parts.GetKey( i );
1882 }
1883
1884
1886 }
1887
1889 {
1892
1893 for ( int i = 0; i < construction_parts.Count(); ++i )
1894 {
1895 string key = construction_parts.GetKey( i );
1897
1898 if ( value.
GetId() ==
id )
1899 {
1900 return value;
1901 }
1902 }
1903
1904 return NULL;
1905 }
1906
1907
1908
1910 {
1912 }
1913
1915 {
1917 }
1918
1920 {
1921 return true;
1922 }
1923
1925 {
1926 return false;
1927 }
1928
1929
1931 {
1934 {
1936 }
1937
1938 return construction_kit;
1939 }
1940
1942 {
1945 {
1947 }
1948 }
1949
1951 {
1953 }
1954
1956 {
1957 return "";
1958 }
1959
1961 {
1964 }
1965
1966
1968 {
1971 }
1972
1973
1975 {
1976 super.OnStoreSave( ctx );
1977
1978
1982
1984 }
1985
1987 {
1988 if ( !super.OnStoreLoad( ctx, version ) )
1989 return false;
1990
1991
1992
1994 {
1996 return false;
1997 }
1999 {
2001 return false;
2002 }
2004 {
2006 return false;
2007 }
2008
2009
2011 {
2013 return false;
2014 }
2015
2016
2017 return true;
2018 }
2019
2021 {
2022 super.AfterStoreLoad();
2023
2025 {
2027 }
2028 }
2029
2031 {
2032
2034
2035
2038
2039
2041 }
2042
2044 {
2045 super.OnCreatePhysics();
2048 }
2049
2051 {
2053 return;
2054
2055 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2056
2058 return;
2059
2061 string part_name = zone;
2063
2065 {
2066 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2067
2068 if ( construction_part && construction.IsPartConstructed( part_name ) )
2069 {
2071 construction.DestroyConnectedParts(part_name);
2072 }
2073
2074
2075 if ( part_name.
Contains(
"barbed") )
2076 {
2077 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2078 if (barbed_wire)
2079 barbed_wire.SetMountedState( false );
2080 }
2081 }
2082 }
2083
2085 {
2087 {
2089 }
2090
2091 super.EEOnAfterLoad();
2092 }
2093
2095 {
2096 super.EEInit();
2097
2098
2100
2101
2102 #ifdef DEVELOPER
2104 #endif
2105 }
2106
2108 {
2109 super.EEItemAttached( item, slot_name );
2110
2114 }
2115
2117 {
2118 super.EEItemDetached( item, slot_name );
2119
2122 }
2123
2124 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2125 {
2128
2131 }
2132
2133
2135 {
2136 return true;
2137 }
2138
2139
2140
2142 {
2144
2145
2146 if (construtionPart.
IsBase())
2147 {
2149
2150
2152 }
2153
2154
2156
2157
2159
2160
2162
2164
2166
2167
2169
2170
2172 }
2173
2175 {
2176
2178 }
2179
2180
2182 {
2185
2186
2188
2189
2191
2192
2194
2195
2197
2199
2200
2202
2203
2205
2206
2207 if (construtionPart.
IsBase())
2208 {
2209
2211 }
2212 }
2213
2215 {
2216
2218 }
2219
2220
2221 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2222 {
2225
2226
2228
2229
2231
2232
2234
2235
2237
2239
2240
2242
2243
2245
2246
2247 if (construtionPart.
IsBase())
2248 {
2249
2251 }
2252 }
2253
2255 {
2256
2258 }
2259
2262 {
2263 bool process = false;
2264
2265
2269
2270 if (process)
2271 {
2272 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2273 {
2275 return;
2276 }
2277
2279 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2280 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2281
2282
2284 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2285 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2286 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2287 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2288 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2289 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2290 mins = minTmp;
2291 maxs = maxTmp;
2292
2293 maxs[1] = maxs[1] + 0.35;
2294
2296 }
2297 }
2298
2301 {
2304
2305
2307 foreach (
EntityAI entity : foundEntities)
2308 {
2311 }
2312 }
2313
2314
2316 {
2318
2322 }
2323
2325 {
2327
2329 {
2331 }
2332 else
2333 {
2335 }
2336
2338 }
2339
2341 {
2343
2345 foreach (
string slotName : attachmentSlots)
2346 {
2348 }
2349
2350
2353 else
2355
2357 }
2358
2360 {
2361 string slotNameMounted = slot_name + "_Mounted";
2362 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2363
2364 if (attachment)
2365 {
2366 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2367 if (barbedWire && barbedWire.IsMounted())
2369 else
2371
2372 if (is_locked)
2373 {
2374 SetAnimationPhase(slotNameMounted, 0);
2375 SetAnimationPhase(slot_name, 1);
2376 }
2377 else
2378 {
2379 SetAnimationPhase(slotNameMounted, 1);
2380 SetAnimationPhase(slot_name, 0);
2381 }
2382 }
2383 else
2384 {
2385 SetAnimationPhase(slotNameMounted, 1);
2386 SetAnimationPhase(slot_name, 1);
2387
2389 }
2390 }
2391
2392
2394 {
2397
2400
2403
2404 foreach (
string slotName : attachmentSlots)
2405 {
2407 }
2408
2409
2411 {
2414
2416 }
2417 else
2418 {
2421
2423 }
2424
2427 }
2428
2430 {
2431
2433 return;
2434
2435 string slot_name_mounted = slot_name + "_Mounted";
2436 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2437
2438
2440 RemoveProxyPhysics( slot_name_mounted );
2441 RemoveProxyPhysics( slot_name );
2442
2443 if ( attachment )
2444 {
2446 if ( is_locked )
2447 {
2449 AddProxyPhysics( slot_name_mounted );
2450 }
2451 else
2452 {
2454 AddProxyPhysics( slot_name );
2455 }
2456 }
2457 }
2458
2460 {
2461 SetAffectPathgraph( true, false );
2463 }
2464
2466 {
2467 return true;
2468 }
2469
2471 {
2472 return true;
2473 }
2474
2476 {
2477 if ( attachment )
2478 {
2480 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2481
2482 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2483 }
2484
2485 return false;
2486 }
2487
2489 {
2491 }
2492
2493
2495 {
2496 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2497 if (
GetGame().ConfigIsExisting( config_path ) )
2498 {
2500 }
2501 }
2502
2504 {
2505 return true;
2506 }
2507
2509 {
2510 return true;
2511 }
2512
2514 {
2515 return true;
2516 }
2517
2518
2520 {
2522 {
2524 }
2525
2527 }
2528
2530 {
2532 }
2533
2534
2535
2537 {
2538 return super.CanReceiveAttachment(attachment, slotId);
2539 }
2540
2542 {
2543 int attachment_count = GetInventory().AttachmentCount();
2544 if ( attachment_count > 0 )
2545 {
2546 if (
HasBase() && attachment_count == 1 )
2547 {
2548 return false;
2549 }
2550
2551 return true;
2552 }
2553
2554 return false;
2555 }
2556
2558 {
2559 return true;
2560 }
2561
2563 {
2564 return false;
2565 }
2566
2567
2569 {
2570 return false;
2571 }
2572
2574 {
2575 return false;
2576 }
2577
2578
2580 {
2581 return false;
2582 }
2583
2584
2585
2587 {
2588 return true;
2589 }
2590
2592 {
2593 return true;
2594 }
2595
2598 {
2599 return false;
2600 }
2601
2602
2604 {
2605 return true;
2606 }
2607
2608
2610 {
2611 return false;
2612 }
2613
2614
2616 {
2617 return true;
2618 }
2619
2620
2622 {
2623 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2624 {
2625 return false;
2626 }
2627
2628 return true;
2629 }
2630
2632 {
2635
2636 return item;
2637 }
2638
2639
2641 {
2643 {
2644
2646
2647
2650
2652 if ( MemoryPointExists( slot_name + "_min" ) )
2653 {
2654 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2655 }
2656 if ( MemoryPointExists( slot_name + "_max" ) )
2657 {
2658 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2659 }
2660
2661
2664
2665
2668 center = ModelToWorld( center );
2669
2670
2673
2674 areaDamage.SetExtents( extents[0], extents[1] );
2675 areaDamage.SetAreaPosition( center );
2676 areaDamage.SetAreaOrientation( orientation );
2679 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2680 areaDamage.SetAmmoName( "BarbedWireHit" );
2681 areaDamage.Spawn();
2682
2684 }
2685 }
2686
2688 {
2689 if ( angle_deg != 0 )
2690 {
2691
2692 orientation[0] = orientation[0] - angle_deg;
2693
2694
2696 if ( MemoryPointExists( "rotate_axis" ) )
2697 {
2698 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2699 }
2700 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];
2701 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];
2702 center[0] = r_center_x;
2703 center[2] = r_center_z;
2704 }
2705 }
2706
2708 {
2710 {
2713 {
2714 if (areaDamage)
2715 {
2716 areaDamage.Destroy();
2717 }
2718
2720 }
2721 }
2722 }
2723
2725 {
2726 return true;
2727 }
2728
2729
2730
2731
2733 {
2735 }
2736
2738 {
2740 }
2741
2743 {
2745 }
2746
2748 {
2750
2751 switch ( material_type )
2752 {
2758 }
2759
2760 return "";
2761 }
2762
2764 {
2766
2767 switch ( material_type )
2768 {
2774 }
2775
2776 return "";
2777 }
2778
2779
2781 {
2783 {
2784
2786 {
2787 SetHealth(slot_name,"Health",item.GetHealth());
2788 }
2789 }
2790 }
2791
2793 {
2794 return 111;
2795 }
2796
2798 {
2799 super.SetActions();
2800
2804 }
2805
2806
2807
2808
2810 {
2811 }
2812
2815 {
2816 return null;
2817 }
2818
2820 {
2822 }
2823
2825 {
2828
2829 Man p;
2830
2831 #ifdef SERVER
2834 if (players.Count())
2835 p = players[0];
2836 #else
2838 #endif
2839
2841 {
2842 bool excluded = false;
2844 if (excludes)
2845 {
2846 foreach (string exclude : excludes)
2847 {
2849 {
2850 excluded = true;
2851 break;
2852 }
2853 }
2854 }
2855
2856 if (!excluded)
2857 {
2859 }
2860 }
2861
2863 }
2864}
2865
2867{
2868#ifdef BSB_DEBUG
2870#else
2871
2872#endif
2873}
2875{
2876#ifdef BSB_DEBUG_SPAM
2878#else
2879
2880#endif
2881}
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.