1724{
1726
1728
1730
1732
1738
1739
1740
1746
1752
1754
1758
1759
1761 {
1763
1764
1765 RegisterNetSyncVariableInt( "m_SyncParts01" );
1766 RegisterNetSyncVariableInt( "m_SyncParts02" );
1767 RegisterNetSyncVariableInt( "m_SyncParts03" );
1768 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1769 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1770 RegisterNetSyncVariableBool( "m_HasBase" );
1771
1772
1774
1775 if (ConfigIsExisting("hybridAttachments"))
1776 {
1779 }
1780 if (ConfigIsExisting("mountables"))
1781 {
1784 }
1785
1787 }
1788
1790 {
1791 super.EEDelete(parent);
1792
1794 {
1795 areaDamage.Destroy();
1796 }
1797
1798 }
1799
1801 {
1802 return "disableBaseDamage";
1803 }
1804
1806 {
1807 return true;
1808 }
1809
1811 {
1812 return EInventoryIconVisibility.HIDE_VICINITY;
1813 }
1814
1816 {
1817 super.InitItemSounds();
1818
1822
1827 }
1828
1830 {
1831 return "putDown_FenceKit_SoundSet";
1832 }
1833
1835 {
1836 return "Shelter_Site_Build_Loop_SoundSet";
1837 }
1838
1839
1841 {
1843 {
1844 SetSynchDirty();
1845 }
1846 }
1847
1849 {
1851 super.OnVariablesSynchronized();
1852
1854 }
1855
1857 {
1858
1860
1861
1863
1864
1866 }
1867
1868
1870 {
1871
1872 int offset;
1873 int mask;
1874
1875 if ( part_id >= 1 && part_id <= 31 )
1876 {
1877 offset = part_id - 1;
1878 mask = 1 << offset;
1879
1881 }
1882 else if ( part_id >= 32 && part_id <= 62 )
1883 {
1884 offset = ( part_id % 32 );
1885 mask = 1 << offset;
1886
1888 }
1889 else if ( part_id >= 63 && part_id <= 93 )
1890 {
1891 offset = ( part_id % 63 );
1892 mask = 1 << offset;
1893
1895 }
1896 }
1897
1899 {
1900
1901 int offset;
1902 int mask;
1903
1904 if ( part_id >= 1 && part_id <= 31 )
1905 {
1906 offset = part_id - 1;
1907 mask = 1 << offset;
1908
1910 }
1911 else if ( part_id >= 32 && part_id <= 62 )
1912 {
1913 offset = ( part_id % 32 );
1914 mask = 1 << offset;
1915
1917 }
1918 else if ( part_id >= 63 && part_id <= 93 )
1919 {
1920 offset = ( part_id % 63 );
1921 mask = 1 << offset;
1922
1924 }
1925 }
1926
1928 {
1929
1930 int offset;
1931 int mask;
1932
1933 if ( part_id >= 1 && part_id <= 31 )
1934 {
1935 offset = part_id - 1;
1936 mask = 1 << offset;
1937
1939 {
1940 return true;
1941 }
1942 }
1943 else if ( part_id >= 32 && part_id <= 62 )
1944 {
1945 offset = ( part_id % 32 );
1946 mask = 1 << offset;
1947
1949 {
1950 return true;
1951 }
1952 }
1953 else if ( part_id >= 63 && part_id <= 93 )
1954 {
1955 offset = ( part_id % 63 );
1956 mask = 1 << offset;
1957
1959 {
1960 return true;
1961 }
1962 }
1963
1964 return false;
1965 }
1966
1968 {
1971 }
1972
1974 {
1975
1978 }
1979
1981 {
1983 {
1986
1987 switch( build_action_id )
1988 {
1992 }
1993 }
1994 }
1995
1996
1998 {
2000 bool is_base = part.
IsBase();
2003 if ( is_part_built_sync )
2004 {
2006 {
2010
2011 if (is_base)
2012 {
2015 }
2016 }
2017 }
2018 else
2019 {
2021 {
2025
2026 if (is_base)
2027 {
2030 }
2031 }
2032 }
2033
2034
2036 }
2037
2038
2040 {
2043
2044 for ( int i = 0; i < construction_parts.Count(); ++i )
2045 {
2046 string key = construction_parts.GetKey( i );
2049 }
2050
2051
2053 }
2054
2056 {
2059
2060 for ( int i = 0; i < construction_parts.Count(); ++i )
2061 {
2062 string key = construction_parts.GetKey( i );
2064
2065 if ( value.
GetId() ==
id )
2066 {
2067 return value;
2068 }
2069 }
2070
2071 return NULL;
2072 }
2073
2074
2075
2077 {
2079 }
2080
2082 {
2084 }
2085
2087 {
2088 return true;
2089 }
2090
2092 {
2093 return false;
2094 }
2095
2096
2098 {
2101 {
2103 }
2104
2105 return construction_kit;
2106 }
2107
2109 {
2112 {
2114 }
2115 }
2116
2118 {
2120 }
2121
2123 {
2124 return "";
2125 }
2126
2128 {
2131 }
2132
2133
2135 {
2138 }
2139
2140
2142 {
2143 super.OnStoreSave( ctx );
2144
2145
2149
2151 }
2152
2154 {
2155 if ( !super.OnStoreLoad( ctx, version ) )
2156 return false;
2157
2158
2159
2161 {
2163 return false;
2164 }
2166 {
2168 return false;
2169 }
2171 {
2173 return false;
2174 }
2175
2176
2178 {
2180 return false;
2181 }
2182
2183
2184 return true;
2185 }
2186
2188 {
2189 super.AfterStoreLoad();
2190
2192 {
2194 }
2195 }
2196
2198 {
2199
2201
2202
2205
2206
2208 }
2209
2211 {
2212 super.OnCreatePhysics();
2215 }
2216
2218 {
2220 return;
2221
2222 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2223
2225 return;
2226
2228 string part_name = zone;
2230
2232 {
2233 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2234
2235 if ( construction_part && construction.IsPartConstructed( part_name ) )
2236 {
2238 construction.DestroyConnectedParts(part_name);
2239 }
2240
2241
2242 if ( part_name.
Contains(
"barbed") )
2243 {
2244 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2245 if (barbed_wire)
2246 barbed_wire.SetMountedState( false );
2247 }
2248 }
2249 }
2250
2252 {
2254 {
2256 }
2257
2258 super.EEOnAfterLoad();
2259 }
2260
2262 {
2263 super.EEInit();
2264
2265
2267
2268
2269 #ifdef DEVELOPER
2271 #endif
2272 }
2273
2275 {
2276 super.EEItemAttached( item, slot_name );
2277
2281 }
2282
2284 {
2285 super.EEItemDetached( item, slot_name );
2286
2289 }
2290
2291 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2292 {
2295
2298 }
2299
2300
2302 {
2303 return true;
2304 }
2305
2306
2307
2309 {
2311
2312
2313 if (construtionPart.
IsBase())
2314 {
2316
2317
2319 }
2320
2321
2323
2324
2326
2327
2329
2331
2333
2334
2336
2337
2339 }
2340
2342 {
2343
2345 }
2346
2347
2349 {
2352
2353
2355
2356
2358
2359
2361
2362
2364
2366
2367
2369
2370
2372
2373
2374 if (construtionPart.
IsBase())
2375 {
2376
2378 }
2379 }
2380
2382 {
2383
2385 }
2386
2387
2388 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2389 {
2392
2393
2395
2396
2398
2399
2401
2402
2404
2406
2407
2409
2410
2412
2413
2414 if (construtionPart.
IsBase())
2415 {
2416
2418 }
2419 }
2420
2422 {
2423
2425 }
2426
2429 {
2430 bool process = false;
2431
2432
2436
2437 if (process)
2438 {
2439 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2440 {
2442 return;
2443 }
2444
2446 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2447 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2448
2449
2451 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2452 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2453 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2454 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2455 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2456 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2457 mins = minTmp;
2458 maxs = maxTmp;
2459
2460 maxs[1] = maxs[1] + 0.35;
2461
2463 }
2464 }
2465
2468 {
2471
2472
2474 foreach (
EntityAI entity : foundEntities)
2475 {
2478 }
2479 }
2480
2481
2483 {
2485
2489 }
2490
2492 {
2494
2496 {
2498 }
2499 else
2500 {
2502 }
2503
2505 }
2506
2508 {
2510
2512 foreach (
string slotName : attachmentSlots)
2513 {
2515 }
2516
2517
2520 else
2522
2524 }
2525
2527 {
2528 string slotNameMounted = slot_name + "_Mounted";
2529 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2530
2531 if (attachment)
2532 {
2533 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2534 if (barbedWire && barbedWire.IsMounted())
2536 else
2538
2539 if (is_locked)
2540 {
2541 SetAnimationPhase(slotNameMounted, 0);
2542 SetAnimationPhase(slot_name, 1);
2543 }
2544 else
2545 {
2546 SetAnimationPhase(slotNameMounted, 1);
2547 SetAnimationPhase(slot_name, 0);
2548 }
2549 }
2550 else
2551 {
2552 SetAnimationPhase(slotNameMounted, 1);
2553 SetAnimationPhase(slot_name, 1);
2554
2556 }
2557 }
2558
2559
2561 {
2564
2567
2570
2571 foreach (
string slotName : attachmentSlots)
2572 {
2574 }
2575
2576
2578 {
2581
2583 }
2584 else
2585 {
2588
2590 }
2591
2594 }
2595
2597 {
2598
2600 return;
2601
2602 string slot_name_mounted = slot_name + "_Mounted";
2603 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2604
2605
2607 RemoveProxyPhysics( slot_name_mounted );
2608 RemoveProxyPhysics( slot_name );
2609
2610 if ( attachment )
2611 {
2613 if ( is_locked )
2614 {
2616 AddProxyPhysics( slot_name_mounted );
2617 }
2618 else
2619 {
2621 AddProxyPhysics( slot_name );
2622 }
2623 }
2624 }
2625
2627 {
2628 SetAffectPathgraph( true, false );
2630 }
2631
2633 {
2634 return true;
2635 }
2636
2638 {
2639 return true;
2640 }
2641
2643 {
2644 if ( attachment )
2645 {
2647 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2648
2649 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2650 }
2651
2652 return false;
2653 }
2654
2656 {
2658 }
2659
2660
2662 {
2663 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2664 if (
GetGame().ConfigIsExisting( config_path ) )
2665 {
2667 }
2668 }
2669
2671 {
2672 return true;
2673 }
2674
2676 {
2677 return true;
2678 }
2679
2681 {
2682 return true;
2683 }
2684
2685
2687 {
2689 {
2691 }
2692
2694 }
2695
2697 {
2699 }
2700
2701
2702
2704 {
2705 return super.CanReceiveAttachment(attachment, slotId);
2706 }
2707
2709 {
2710 int attachment_count = GetInventory().AttachmentCount();
2711 if ( attachment_count > 0 )
2712 {
2713 if (
HasBase() && attachment_count == 1 )
2714 {
2715 return false;
2716 }
2717
2718 return true;
2719 }
2720
2721 return false;
2722 }
2723
2725 {
2726 return true;
2727 }
2728
2730 {
2731 return false;
2732 }
2733
2734
2736 {
2737 return false;
2738 }
2739
2741 {
2742 return false;
2743 }
2744
2745
2747 {
2748 return false;
2749 }
2750
2751
2752
2754 {
2755 return true;
2756 }
2757
2759 {
2760 return true;
2761 }
2762
2765 {
2766 return false;
2767 }
2768
2769
2771 {
2772 return true;
2773 }
2774
2775
2777 {
2778 return false;
2779 }
2780
2781
2783 {
2784 return true;
2785 }
2786
2787
2789 {
2790 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2791 {
2792 return false;
2793 }
2794
2795 return true;
2796 }
2797
2799 {
2802
2803 return item;
2804 }
2805
2806
2808 {
2810 {
2811
2813
2814
2817
2819 if ( MemoryPointExists( slot_name + "_min" ) )
2820 {
2821 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2822 }
2823 if ( MemoryPointExists( slot_name + "_max" ) )
2824 {
2825 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2826 }
2827
2828
2831
2832
2835 center = ModelToWorld( center );
2836
2837
2840
2841 areaDamage.SetExtents( extents[0], extents[1] );
2842 areaDamage.SetAreaPosition( center );
2843 areaDamage.SetAreaOrientation( orientation );
2846 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2847 areaDamage.SetAmmoName( "BarbedWireHit" );
2848 areaDamage.Spawn();
2849
2851 }
2852 }
2853
2855 {
2856 if ( angle_deg != 0 )
2857 {
2858
2859 orientation[0] = orientation[0] - angle_deg;
2860
2861
2863 if ( MemoryPointExists( "rotate_axis" ) )
2864 {
2865 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2866 }
2867 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];
2868 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];
2869 center[0] = r_center_x;
2870 center[2] = r_center_z;
2871 }
2872 }
2873
2875 {
2877 {
2880 {
2881 if (areaDamage)
2882 {
2883 areaDamage.Destroy();
2884 }
2885
2887 }
2888 }
2889 }
2890
2892 {
2893 return true;
2894 }
2895
2896
2897
2898
2900 {
2902 }
2903
2905 {
2907 }
2908
2910 {
2912 }
2913
2915 {
2917
2918 switch ( material_type )
2919 {
2925 }
2926
2927 return "";
2928 }
2929
2931 {
2933
2934 switch ( material_type )
2935 {
2941 }
2942
2943 return "";
2944 }
2945
2946
2948 {
2950 {
2951
2953 {
2954 SetHealth(slot_name,"Health",item.GetHealth());
2955 }
2956 }
2957 }
2958
2960 {
2961 return 111;
2962 }
2963
2965 {
2966 super.SetActions();
2967
2971 }
2972
2973
2974
2975
2977 {
2978 }
2979
2982 {
2983 return null;
2984 }
2985
2987 {
2989 }
2990
2992 {
2995
2996 Man p;
2997
2998 #ifdef SERVER
3001 if (players.Count())
3002 p = players[0];
3003 #else
3005 #endif
3006
3008 {
3009 bool excluded = false;
3011 if (excludes)
3012 {
3013 foreach (string exclude : excludes)
3014 {
3016 {
3017 excluded = true;
3018 break;
3019 }
3020 }
3021 }
3022
3023 if (!excluded)
3024 {
3026 }
3027 }
3028
3030 }
3031}
3032
3034{
3035#ifdef BSB_DEBUG
3037#else
3038
3039#endif
3040}
3042{
3043#ifdef BSB_DEBUG_SPAM
3045#else
3046
3047#endif
3048}
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.