1707{
1709
1711
1713
1715
1721
1722
1723
1729
1735
1737
1741
1742
1744 {
1746
1747
1748 RegisterNetSyncVariableInt( "m_SyncParts01" );
1749 RegisterNetSyncVariableInt( "m_SyncParts02" );
1750 RegisterNetSyncVariableInt( "m_SyncParts03" );
1751 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1752 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1753 RegisterNetSyncVariableBool( "m_HasBase" );
1754
1755
1757
1758 if (ConfigIsExisting("hybridAttachments"))
1759 {
1762 }
1763 if (ConfigIsExisting("mountables"))
1764 {
1767 }
1768
1770 }
1771
1773 {
1774 super.EEDelete(parent);
1775
1777 {
1778 areaDamage.Destroy();
1779 }
1780
1781 }
1782
1784 {
1785 return "disableBaseDamage";
1786 }
1787
1789 {
1790 return true;
1791 }
1792
1794 {
1795 return EInventoryIconVisibility.HIDE_VICINITY;
1796 }
1797
1799 {
1800 super.InitItemSounds();
1801
1805
1810 }
1811
1813 {
1814 return "putDown_FenceKit_SoundSet";
1815 }
1816
1818 {
1819 return "Shelter_Site_Build_Loop_SoundSet";
1820 }
1821
1822
1824 {
1826 {
1827 SetSynchDirty();
1828 }
1829 }
1830
1832 {
1834 super.OnVariablesSynchronized();
1835
1837 }
1838
1840 {
1841
1843
1844
1846
1847
1849 }
1850
1851
1853 {
1854
1855 int offset;
1856 int mask;
1857
1858 if ( part_id >= 1 && part_id <= 31 )
1859 {
1860 offset = part_id - 1;
1861 mask = 1 << offset;
1862
1864 }
1865 else if ( part_id >= 32 && part_id <= 62 )
1866 {
1867 offset = ( part_id % 32 );
1868 mask = 1 << offset;
1869
1871 }
1872 else if ( part_id >= 63 && part_id <= 93 )
1873 {
1874 offset = ( part_id % 63 );
1875 mask = 1 << offset;
1876
1878 }
1879 }
1880
1882 {
1883
1884 int offset;
1885 int mask;
1886
1887 if ( part_id >= 1 && part_id <= 31 )
1888 {
1889 offset = part_id - 1;
1890 mask = 1 << offset;
1891
1893 }
1894 else if ( part_id >= 32 && part_id <= 62 )
1895 {
1896 offset = ( part_id % 32 );
1897 mask = 1 << offset;
1898
1900 }
1901 else if ( part_id >= 63 && part_id <= 93 )
1902 {
1903 offset = ( part_id % 63 );
1904 mask = 1 << offset;
1905
1907 }
1908 }
1909
1911 {
1912
1913 int offset;
1914 int mask;
1915
1916 if ( part_id >= 1 && part_id <= 31 )
1917 {
1918 offset = part_id - 1;
1919 mask = 1 << offset;
1920
1922 {
1923 return true;
1924 }
1925 }
1926 else if ( part_id >= 32 && part_id <= 62 )
1927 {
1928 offset = ( part_id % 32 );
1929 mask = 1 << offset;
1930
1932 {
1933 return true;
1934 }
1935 }
1936 else if ( part_id >= 63 && part_id <= 93 )
1937 {
1938 offset = ( part_id % 63 );
1939 mask = 1 << offset;
1940
1942 {
1943 return true;
1944 }
1945 }
1946
1947 return false;
1948 }
1949
1951 {
1954 }
1955
1957 {
1958
1961 }
1962
1964 {
1966 {
1969
1970 switch( build_action_id )
1971 {
1975 }
1976 }
1977 }
1978
1979
1981 {
1983 bool is_base = part.
IsBase();
1986 if ( is_part_built_sync )
1987 {
1989 {
1993
1994 if (is_base)
1995 {
1998 }
1999 }
2000 }
2001 else
2002 {
2004 {
2008
2009 if (is_base)
2010 {
2013 }
2014 }
2015 }
2016
2017
2019 }
2020
2021
2023 {
2026
2027 for ( int i = 0; i < construction_parts.Count(); ++i )
2028 {
2029 string key = construction_parts.GetKey( i );
2032 }
2033
2034
2036 }
2037
2039 {
2042
2043 for ( int i = 0; i < construction_parts.Count(); ++i )
2044 {
2045 string key = construction_parts.GetKey( i );
2047
2048 if ( value.
GetId() ==
id )
2049 {
2050 return value;
2051 }
2052 }
2053
2054 return NULL;
2055 }
2056
2057
2058
2060 {
2062 }
2063
2065 {
2067 }
2068
2070 {
2071 return true;
2072 }
2073
2075 {
2076 return false;
2077 }
2078
2079
2081 {
2084 {
2086 }
2087
2088 return construction_kit;
2089 }
2090
2092 {
2095 {
2097 }
2098 }
2099
2101 {
2103 }
2104
2106 {
2107 return "";
2108 }
2109
2111 {
2114 }
2115
2116
2118 {
2121 }
2122
2123
2125 {
2126 super.OnStoreSave( ctx );
2127
2128
2132
2134 }
2135
2137 {
2138 if ( !super.OnStoreLoad( ctx, version ) )
2139 return false;
2140
2141
2142
2144 {
2146 return false;
2147 }
2149 {
2151 return false;
2152 }
2154 {
2156 return false;
2157 }
2158
2159
2161 {
2163 return false;
2164 }
2165
2166
2167 return true;
2168 }
2169
2171 {
2172 super.AfterStoreLoad();
2173
2175 {
2177 }
2178 }
2179
2181 {
2182
2184
2185
2188
2189
2191 }
2192
2194 {
2195 super.OnCreatePhysics();
2198 }
2199
2201 {
2203 return;
2204
2205 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2206
2208 return;
2209
2211 string part_name = zone;
2213
2215 {
2216 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2217
2218 if ( construction_part && construction.IsPartConstructed( part_name ) )
2219 {
2221 construction.DestroyConnectedParts(part_name);
2222 }
2223
2224
2225 if ( part_name.
Contains(
"barbed") )
2226 {
2227 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2228 if (barbed_wire)
2229 barbed_wire.SetMountedState( false );
2230 }
2231 }
2232 }
2233
2235 {
2237 {
2239 }
2240
2241 super.EEOnAfterLoad();
2242 }
2243
2245 {
2246 super.EEInit();
2247
2248
2250
2251
2252 #ifdef DEVELOPER
2254 #endif
2255 }
2256
2258 {
2259 super.EEItemAttached( item, slot_name );
2260
2264 }
2265
2267 {
2268 super.EEItemDetached( item, slot_name );
2269
2272 }
2273
2274 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2275 {
2278
2281 }
2282
2283
2285 {
2286 return true;
2287 }
2288
2289
2290
2292 {
2294
2295
2296 if (construtionPart.
IsBase())
2297 {
2299
2300
2302 }
2303
2304
2306
2307
2309
2310
2312
2314
2316
2317
2319
2320
2322 }
2323
2325 {
2326
2328 }
2329
2330
2332 {
2335
2336
2338
2339
2341
2342
2344
2345
2347
2349
2350
2352
2353
2355
2356
2357 if (construtionPart.
IsBase())
2358 {
2359
2361 }
2362 }
2363
2365 {
2366
2368 }
2369
2370
2371 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2372 {
2375
2376
2378
2379
2381
2382
2384
2385
2387
2389
2390
2392
2393
2395
2396
2397 if (construtionPart.
IsBase())
2398 {
2399
2401 }
2402 }
2403
2405 {
2406
2408 }
2409
2412 {
2413 bool process = false;
2414
2415
2419
2420 if (process)
2421 {
2422 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2423 {
2425 return;
2426 }
2427
2429 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2430 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2431
2432
2434 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2435 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2436 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2437 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2438 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2439 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2440 mins = minTmp;
2441 maxs = maxTmp;
2442
2443 maxs[1] = maxs[1] + 0.35;
2444
2446 }
2447 }
2448
2451 {
2454
2455
2457 foreach (
EntityAI entity : foundEntities)
2458 {
2461 }
2462 }
2463
2464
2466 {
2468
2472 }
2473
2475 {
2477
2479 {
2481 }
2482 else
2483 {
2485 }
2486
2488 }
2489
2491 {
2493
2495 foreach (
string slotName : attachmentSlots)
2496 {
2498 }
2499
2500
2503 else
2505
2507 }
2508
2510 {
2511 string slotNameMounted = slot_name + "_Mounted";
2512 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2513
2514 if (attachment)
2515 {
2516 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2517 if (barbedWire && barbedWire.IsMounted())
2519 else
2521
2522 if (is_locked)
2523 {
2524 SetAnimationPhase(slotNameMounted, 0);
2525 SetAnimationPhase(slot_name, 1);
2526 }
2527 else
2528 {
2529 SetAnimationPhase(slotNameMounted, 1);
2530 SetAnimationPhase(slot_name, 0);
2531 }
2532 }
2533 else
2534 {
2535 SetAnimationPhase(slotNameMounted, 1);
2536 SetAnimationPhase(slot_name, 1);
2537
2539 }
2540 }
2541
2542
2544 {
2547
2550
2553
2554 foreach (
string slotName : attachmentSlots)
2555 {
2557 }
2558
2559
2561 {
2564
2566 }
2567 else
2568 {
2571
2573 }
2574
2577 }
2578
2580 {
2581
2583 return;
2584
2585 string slot_name_mounted = slot_name + "_Mounted";
2586 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2587
2588
2590 RemoveProxyPhysics( slot_name_mounted );
2591 RemoveProxyPhysics( slot_name );
2592
2593 if ( attachment )
2594 {
2596 if ( is_locked )
2597 {
2599 AddProxyPhysics( slot_name_mounted );
2600 }
2601 else
2602 {
2604 AddProxyPhysics( slot_name );
2605 }
2606 }
2607 }
2608
2610 {
2611 SetAffectPathgraph( true, false );
2613 }
2614
2616 {
2617 return true;
2618 }
2619
2621 {
2622 return true;
2623 }
2624
2626 {
2627 if ( attachment )
2628 {
2630 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2631
2632 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2633 }
2634
2635 return false;
2636 }
2637
2639 {
2641 }
2642
2643
2645 {
2646 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2647 if (
GetGame().ConfigIsExisting( config_path ) )
2648 {
2650 }
2651 }
2652
2654 {
2655 return true;
2656 }
2657
2659 {
2660 return true;
2661 }
2662
2664 {
2665 return true;
2666 }
2667
2668
2670 {
2672 {
2674 }
2675
2677 }
2678
2680 {
2682 }
2683
2684
2685
2687 {
2688 return super.CanReceiveAttachment(attachment, slotId);
2689 }
2690
2692 {
2693 int attachment_count = GetInventory().AttachmentCount();
2694 if ( attachment_count > 0 )
2695 {
2696 if (
HasBase() && attachment_count == 1 )
2697 {
2698 return false;
2699 }
2700
2701 return true;
2702 }
2703
2704 return false;
2705 }
2706
2708 {
2709 return true;
2710 }
2711
2713 {
2714 return false;
2715 }
2716
2717
2719 {
2720 return false;
2721 }
2722
2724 {
2725 return false;
2726 }
2727
2728
2730 {
2731 return false;
2732 }
2733
2734
2735
2737 {
2738 return true;
2739 }
2740
2742 {
2743 return true;
2744 }
2745
2748 {
2749 return false;
2750 }
2751
2752
2754 {
2755 return true;
2756 }
2757
2758
2760 {
2761 return false;
2762 }
2763
2764
2766 {
2767 return true;
2768 }
2769
2770
2772 {
2773 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2774 {
2775 return false;
2776 }
2777
2778 return true;
2779 }
2780
2782 {
2785
2786 return item;
2787 }
2788
2789
2791 {
2793 {
2794
2796
2797
2800
2802 if ( MemoryPointExists( slot_name + "_min" ) )
2803 {
2804 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2805 }
2806 if ( MemoryPointExists( slot_name + "_max" ) )
2807 {
2808 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2809 }
2810
2811
2814
2815
2818 center = ModelToWorld( center );
2819
2820
2823
2824 areaDamage.SetExtents( extents[0], extents[1] );
2825 areaDamage.SetAreaPosition( center );
2826 areaDamage.SetAreaOrientation( orientation );
2829 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2830 areaDamage.SetAmmoName( "BarbedWireHit" );
2831 areaDamage.Spawn();
2832
2834 }
2835 }
2836
2838 {
2839 if ( angle_deg != 0 )
2840 {
2841
2842 orientation[0] = orientation[0] - angle_deg;
2843
2844
2846 if ( MemoryPointExists( "rotate_axis" ) )
2847 {
2848 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2849 }
2850 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];
2851 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];
2852 center[0] = r_center_x;
2853 center[2] = r_center_z;
2854 }
2855 }
2856
2858 {
2860 {
2863 {
2864 if (areaDamage)
2865 {
2866 areaDamage.Destroy();
2867 }
2868
2870 }
2871 }
2872 }
2873
2875 {
2876 return true;
2877 }
2878
2879
2880
2881
2883 {
2885 }
2886
2888 {
2890 }
2891
2893 {
2895 }
2896
2898 {
2900
2901 switch ( material_type )
2902 {
2908 }
2909
2910 return "";
2911 }
2912
2914 {
2916
2917 switch ( material_type )
2918 {
2924 }
2925
2926 return "";
2927 }
2928
2929
2931 {
2933 {
2934
2936 {
2937 SetHealth(slot_name,"Health",item.GetHealth());
2938 }
2939 }
2940 }
2941
2943 {
2944 return 111;
2945 }
2946
2948 {
2949 super.SetActions();
2950
2954 }
2955
2956
2957
2958
2960 {
2961 }
2962
2965 {
2966 return null;
2967 }
2968
2970 {
2972 }
2973
2975 {
2978
2979 Man p;
2980
2981 #ifdef SERVER
2984 if (players.Count())
2985 p = players[0];
2986 #else
2988 #endif
2989
2991 {
2992 bool excluded = false;
2994 if (excludes)
2995 {
2996 foreach (string exclude : excludes)
2997 {
2999 {
3000 excluded = true;
3001 break;
3002 }
3003 }
3004 }
3005
3006 if (!excluded)
3007 {
3009 }
3010 }
3011
3013 }
3014}
3015
3017{
3018#ifdef BSB_DEBUG
3020#else
3021
3022#endif
3023}
3025{
3026#ifdef BSB_DEBUG_SPAM
3028#else
3029
3030#endif
3031}
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.