1671{
1673
1675
1677
1679
1685
1686
1687
1693
1699
1701
1705
1706
1708 {
1710
1711
1712 RegisterNetSyncVariableInt( "m_SyncParts01" );
1713 RegisterNetSyncVariableInt( "m_SyncParts02" );
1714 RegisterNetSyncVariableInt( "m_SyncParts03" );
1715 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1716 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1717 RegisterNetSyncVariableBool( "m_HasBase" );
1718
1719
1721
1722 if (ConfigIsExisting("hybridAttachments"))
1723 {
1726 }
1727 if (ConfigIsExisting("mountables"))
1728 {
1731 }
1732
1734 }
1735
1737 {
1738 super.EEDelete(parent);
1739
1741 {
1742 areaDamage.Destroy();
1743 }
1744
1745 }
1746
1748 {
1749 return "disableBaseDamage";
1750 }
1751
1753 {
1754 return true;
1755 }
1756
1758 {
1759 return EInventoryIconVisibility.HIDE_VICINITY;
1760 }
1761
1763 {
1764 super.InitItemSounds();
1765
1769
1774 }
1775
1777 {
1778 return "putDown_FenceKit_SoundSet";
1779 }
1780
1782 {
1783 return "Shelter_Site_Build_Loop_SoundSet";
1784 }
1785
1786
1788 {
1790 {
1791 SetSynchDirty();
1792 }
1793 }
1794
1796 {
1798 super.OnVariablesSynchronized();
1799
1801 }
1802
1804 {
1805
1807
1808
1810
1811
1813 }
1814
1815
1817 {
1818
1819 int offset;
1820 int mask;
1821
1822 if ( part_id >= 1 && part_id <= 31 )
1823 {
1824 offset = part_id - 1;
1825 mask = 1 << offset;
1826
1828 }
1829 else if ( part_id >= 32 && part_id <= 62 )
1830 {
1831 offset = ( part_id % 32 );
1832 mask = 1 << offset;
1833
1835 }
1836 else if ( part_id >= 63 && part_id <= 93 )
1837 {
1838 offset = ( part_id % 63 );
1839 mask = 1 << offset;
1840
1842 }
1843 }
1844
1846 {
1847
1848 int offset;
1849 int mask;
1850
1851 if ( part_id >= 1 && part_id <= 31 )
1852 {
1853 offset = part_id - 1;
1854 mask = 1 << offset;
1855
1857 }
1858 else if ( part_id >= 32 && part_id <= 62 )
1859 {
1860 offset = ( part_id % 32 );
1861 mask = 1 << offset;
1862
1864 }
1865 else if ( part_id >= 63 && part_id <= 93 )
1866 {
1867 offset = ( part_id % 63 );
1868 mask = 1 << offset;
1869
1871 }
1872 }
1873
1875 {
1876
1877 int offset;
1878 int mask;
1879
1880 if ( part_id >= 1 && part_id <= 31 )
1881 {
1882 offset = part_id - 1;
1883 mask = 1 << offset;
1884
1886 {
1887 return true;
1888 }
1889 }
1890 else if ( part_id >= 32 && part_id <= 62 )
1891 {
1892 offset = ( part_id % 32 );
1893 mask = 1 << offset;
1894
1896 {
1897 return true;
1898 }
1899 }
1900 else if ( part_id >= 63 && part_id <= 93 )
1901 {
1902 offset = ( part_id % 63 );
1903 mask = 1 << offset;
1904
1906 {
1907 return true;
1908 }
1909 }
1910
1911 return false;
1912 }
1913
1915 {
1918 }
1919
1921 {
1922
1925 }
1926
1928 {
1930 {
1933
1934 switch( build_action_id )
1935 {
1939 }
1940 }
1941 }
1942
1943
1945 {
1947 bool is_base = part.
IsBase();
1950 if ( is_part_built_sync )
1951 {
1953 {
1957
1958 if (is_base)
1959 {
1962 }
1963 }
1964 }
1965 else
1966 {
1968 {
1972
1973 if (is_base)
1974 {
1977 }
1978 }
1979 }
1980
1981
1983 }
1984
1985
1987 {
1990
1991 for ( int i = 0; i < construction_parts.Count(); ++i )
1992 {
1993 string key = construction_parts.GetKey( i );
1996 }
1997
1998
2000 }
2001
2003 {
2006
2007 for ( int i = 0; i < construction_parts.Count(); ++i )
2008 {
2009 string key = construction_parts.GetKey( i );
2011
2012 if ( value.
GetId() ==
id )
2013 {
2014 return value;
2015 }
2016 }
2017
2018 return NULL;
2019 }
2020
2021
2022
2024 {
2026 }
2027
2029 {
2031 }
2032
2034 {
2035 return true;
2036 }
2037
2039 {
2040 return false;
2041 }
2042
2043
2045 {
2048 {
2050 }
2051
2052 return construction_kit;
2053 }
2054
2056 {
2059 {
2061 }
2062 }
2063
2065 {
2067 }
2068
2070 {
2071 return "";
2072 }
2073
2075 {
2078 }
2079
2080
2082 {
2085 }
2086
2087
2089 {
2090 super.OnStoreSave( ctx );
2091
2092
2096
2098 }
2099
2101 {
2102 if ( !super.OnStoreLoad( ctx, version ) )
2103 return false;
2104
2105
2106
2108 {
2110 return false;
2111 }
2113 {
2115 return false;
2116 }
2118 {
2120 return false;
2121 }
2122
2123
2125 {
2127 return false;
2128 }
2129
2130
2131 return true;
2132 }
2133
2135 {
2136 super.AfterStoreLoad();
2137
2139 {
2141 }
2142 }
2143
2145 {
2146
2148
2149
2152
2153
2155 }
2156
2158 {
2159 super.OnCreatePhysics();
2162 }
2163
2165 {
2167 return;
2168
2169 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2170
2172 return;
2173
2175 string part_name = zone;
2177
2179 {
2180 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2181
2182 if ( construction_part && construction.IsPartConstructed( part_name ) )
2183 {
2185 construction.DestroyConnectedParts(part_name);
2186 }
2187
2188
2189 if ( part_name.
Contains(
"barbed") )
2190 {
2191 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2192 if (barbed_wire)
2193 barbed_wire.SetMountedState( false );
2194 }
2195 }
2196 }
2197
2199 {
2201 {
2203 }
2204
2205 super.EEOnAfterLoad();
2206 }
2207
2209 {
2210 super.EEInit();
2211
2212
2214
2215
2216 #ifdef DEVELOPER
2218 #endif
2219 }
2220
2222 {
2223 super.EEItemAttached( item, slot_name );
2224
2228 }
2229
2231 {
2232 super.EEItemDetached( item, slot_name );
2233
2236 }
2237
2238 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2239 {
2242
2245 }
2246
2247
2249 {
2250 return true;
2251 }
2252
2253
2254
2256 {
2258
2259
2260 if (construtionPart.
IsBase())
2261 {
2263
2264
2266 }
2267
2268
2270
2271
2273
2274
2276
2278
2280
2281
2283
2284
2286 }
2287
2289 {
2290
2292 }
2293
2294
2296 {
2299
2300
2302
2303
2305
2306
2308
2309
2311
2313
2314
2316
2317
2319
2320
2321 if (construtionPart.
IsBase())
2322 {
2323
2325 }
2326 }
2327
2329 {
2330
2332 }
2333
2334
2335 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2336 {
2339
2340
2342
2343
2345
2346
2348
2349
2351
2353
2354
2356
2357
2359
2360
2361 if (construtionPart.
IsBase())
2362 {
2363
2365 }
2366 }
2367
2369 {
2370
2372 }
2373
2376 {
2377 bool process = false;
2378
2379
2383
2384 if (process)
2385 {
2386 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2387 {
2389 return;
2390 }
2391
2393 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2394 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2395
2396
2398 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2399 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2400 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2401 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2402 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2403 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2404 mins = minTmp;
2405 maxs = maxTmp;
2406
2407 maxs[1] = maxs[1] + 0.35;
2408
2410 }
2411 }
2412
2415 {
2418
2419
2421 foreach (
EntityAI entity : foundEntities)
2422 {
2425 }
2426 }
2427
2428
2430 {
2432
2436 }
2437
2439 {
2441
2443 {
2445 }
2446 else
2447 {
2449 }
2450
2452 }
2453
2455 {
2457
2459 foreach (
string slotName : attachmentSlots)
2460 {
2462 }
2463
2464
2467 else
2469
2471 }
2472
2474 {
2475 string slotNameMounted = slot_name + "_Mounted";
2476 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2477
2478 if (attachment)
2479 {
2480 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2481 if (barbedWire && barbedWire.IsMounted())
2483 else
2485
2486 if (is_locked)
2487 {
2488 SetAnimationPhase(slotNameMounted, 0);
2489 SetAnimationPhase(slot_name, 1);
2490 }
2491 else
2492 {
2493 SetAnimationPhase(slotNameMounted, 1);
2494 SetAnimationPhase(slot_name, 0);
2495 }
2496 }
2497 else
2498 {
2499 SetAnimationPhase(slotNameMounted, 1);
2500 SetAnimationPhase(slot_name, 1);
2501
2503 }
2504 }
2505
2506
2508 {
2511
2514
2517
2518 foreach (
string slotName : attachmentSlots)
2519 {
2521 }
2522
2523
2525 {
2528
2530 }
2531 else
2532 {
2535
2537 }
2538
2541 }
2542
2544 {
2545
2547 return;
2548
2549 string slot_name_mounted = slot_name + "_Mounted";
2550 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2551
2552
2554 RemoveProxyPhysics( slot_name_mounted );
2555 RemoveProxyPhysics( slot_name );
2556
2557 if ( attachment )
2558 {
2560 if ( is_locked )
2561 {
2563 AddProxyPhysics( slot_name_mounted );
2564 }
2565 else
2566 {
2568 AddProxyPhysics( slot_name );
2569 }
2570 }
2571 }
2572
2574 {
2575 SetAffectPathgraph( true, false );
2577 }
2578
2580 {
2581 return true;
2582 }
2583
2585 {
2586 return true;
2587 }
2588
2590 {
2591 if ( attachment )
2592 {
2594 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2595
2596 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2597 }
2598
2599 return false;
2600 }
2601
2603 {
2605 }
2606
2607
2609 {
2610 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2611 if (
GetGame().ConfigIsExisting( config_path ) )
2612 {
2614 }
2615 }
2616
2618 {
2619 return true;
2620 }
2621
2623 {
2624 return true;
2625 }
2626
2628 {
2629 return true;
2630 }
2631
2632
2634 {
2636 {
2638 }
2639
2641 }
2642
2644 {
2646 }
2647
2648
2649
2651 {
2652 return super.CanReceiveAttachment(attachment, slotId);
2653 }
2654
2656 {
2657 int attachment_count = GetInventory().AttachmentCount();
2658 if ( attachment_count > 0 )
2659 {
2660 if (
HasBase() && attachment_count == 1 )
2661 {
2662 return false;
2663 }
2664
2665 return true;
2666 }
2667
2668 return false;
2669 }
2670
2672 {
2673 return true;
2674 }
2675
2677 {
2678 return false;
2679 }
2680
2681
2683 {
2684 return false;
2685 }
2686
2688 {
2689 return false;
2690 }
2691
2692
2694 {
2695 return false;
2696 }
2697
2698
2699
2701 {
2702 return true;
2703 }
2704
2706 {
2707 return true;
2708 }
2709
2712 {
2713 return false;
2714 }
2715
2716
2718 {
2719 return true;
2720 }
2721
2722
2724 {
2725 return false;
2726 }
2727
2728
2730 {
2731 return true;
2732 }
2733
2734
2736 {
2737 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2738 {
2739 return false;
2740 }
2741
2742 return true;
2743 }
2744
2746 {
2749
2750 return item;
2751 }
2752
2753
2755 {
2757 {
2758
2760
2761
2764
2766 if ( MemoryPointExists( slot_name + "_min" ) )
2767 {
2768 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2769 }
2770 if ( MemoryPointExists( slot_name + "_max" ) )
2771 {
2772 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2773 }
2774
2775
2778
2779
2782 center = ModelToWorld( center );
2783
2784
2787
2788 areaDamage.SetExtents( extents[0], extents[1] );
2789 areaDamage.SetAreaPosition( center );
2790 areaDamage.SetAreaOrientation( orientation );
2793 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2794 areaDamage.SetAmmoName( "BarbedWireHit" );
2795 areaDamage.Spawn();
2796
2798 }
2799 }
2800
2802 {
2803 if ( angle_deg != 0 )
2804 {
2805
2806 orientation[0] = orientation[0] - angle_deg;
2807
2808
2810 if ( MemoryPointExists( "rotate_axis" ) )
2811 {
2812 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2813 }
2814 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];
2815 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];
2816 center[0] = r_center_x;
2817 center[2] = r_center_z;
2818 }
2819 }
2820
2822 {
2824 {
2827 {
2828 if (areaDamage)
2829 {
2830 areaDamage.Destroy();
2831 }
2832
2834 }
2835 }
2836 }
2837
2839 {
2840 return true;
2841 }
2842
2843
2844
2845
2847 {
2849 }
2850
2852 {
2854 }
2855
2857 {
2859 }
2860
2862 {
2864
2865 switch ( material_type )
2866 {
2872 }
2873
2874 return "";
2875 }
2876
2878 {
2880
2881 switch ( material_type )
2882 {
2888 }
2889
2890 return "";
2891 }
2892
2893
2895 {
2897 {
2898
2900 {
2901 SetHealth(slot_name,"Health",item.GetHealth());
2902 }
2903 }
2904 }
2905
2907 {
2908 return 111;
2909 }
2910
2912 {
2913 super.SetActions();
2914
2918 }
2919
2920
2921
2922
2924 {
2925 }
2926
2929 {
2930 return null;
2931 }
2932
2934 {
2936 }
2937
2939 {
2942
2943 Man p;
2944
2945 #ifdef SERVER
2948 if (players.Count())
2949 p = players[0];
2950 #else
2952 #endif
2953
2955 {
2956 bool excluded = false;
2958 if (excludes)
2959 {
2960 foreach (string exclude : excludes)
2961 {
2963 {
2964 excluded = true;
2965 break;
2966 }
2967 }
2968 }
2969
2970 if (!excluded)
2971 {
2973 }
2974 }
2975
2977 }
2978}
2979
2981{
2982#ifdef BSB_DEBUG
2984#else
2985
2986#endif
2987}
2989{
2990#ifdef BSB_DEBUG_SPAM
2992#else
2993
2994#endif
2995}
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.