1731{
1733
1735
1737
1739
1745
1746
1747
1753
1759
1761
1765
1766
1768 {
1770
1771
1772 RegisterNetSyncVariableInt( "m_SyncParts01" );
1773 RegisterNetSyncVariableInt( "m_SyncParts02" );
1774 RegisterNetSyncVariableInt( "m_SyncParts03" );
1775 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1776 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1777 RegisterNetSyncVariableBool( "m_HasBase" );
1778
1779
1781
1782 if (ConfigIsExisting("hybridAttachments"))
1783 {
1786 }
1787 if (ConfigIsExisting("mountables"))
1788 {
1791 }
1792
1794 }
1795
1797 {
1798 super.EEDelete(parent);
1799
1801 {
1802 areaDamage.Destroy();
1803 }
1804
1805 }
1806
1808 {
1809 return "disableBaseDamage";
1810 }
1811
1813 {
1814 return true;
1815 }
1816
1818 {
1819 return EInventoryIconVisibility.HIDE_VICINITY;
1820 }
1821
1823 {
1824 super.InitItemSounds();
1825
1829
1834 }
1835
1837 {
1838 return "putDown_FenceKit_SoundSet";
1839 }
1840
1842 {
1843 return "Shelter_Site_Build_Loop_SoundSet";
1844 }
1845
1846
1848 {
1850 {
1851 SetSynchDirty();
1852 }
1853 }
1854
1856 {
1858 super.OnVariablesSynchronized();
1859
1861 }
1862
1864 {
1865
1867
1868
1870
1871
1873 }
1874
1875
1877 {
1878
1879 int offset;
1880 int mask;
1881
1882 if ( part_id >= 1 && part_id <= 31 )
1883 {
1884 offset = part_id - 1;
1885 mask = 1 << offset;
1886
1888 }
1889 else if ( part_id >= 32 && part_id <= 62 )
1890 {
1891 offset = ( part_id % 32 );
1892 mask = 1 << offset;
1893
1895 }
1896 else if ( part_id >= 63 && part_id <= 93 )
1897 {
1898 offset = ( part_id % 63 );
1899 mask = 1 << offset;
1900
1902 }
1903 }
1904
1906 {
1907
1908 int offset;
1909 int mask;
1910
1911 if ( part_id >= 1 && part_id <= 31 )
1912 {
1913 offset = part_id - 1;
1914 mask = 1 << offset;
1915
1917 }
1918 else if ( part_id >= 32 && part_id <= 62 )
1919 {
1920 offset = ( part_id % 32 );
1921 mask = 1 << offset;
1922
1924 }
1925 else if ( part_id >= 63 && part_id <= 93 )
1926 {
1927 offset = ( part_id % 63 );
1928 mask = 1 << offset;
1929
1931 }
1932 }
1933
1935 {
1936
1937 int offset;
1938 int mask;
1939
1940 if ( part_id >= 1 && part_id <= 31 )
1941 {
1942 offset = part_id - 1;
1943 mask = 1 << offset;
1944
1946 {
1947 return true;
1948 }
1949 }
1950 else if ( part_id >= 32 && part_id <= 62 )
1951 {
1952 offset = ( part_id % 32 );
1953 mask = 1 << offset;
1954
1956 {
1957 return true;
1958 }
1959 }
1960 else if ( part_id >= 63 && part_id <= 93 )
1961 {
1962 offset = ( part_id % 63 );
1963 mask = 1 << offset;
1964
1966 {
1967 return true;
1968 }
1969 }
1970
1971 return false;
1972 }
1973
1975 {
1978 }
1979
1981 {
1982
1985 }
1986
1988 {
1990 {
1993
1994 switch( build_action_id )
1995 {
1999 }
2000 }
2001 }
2002
2003
2005 {
2007 bool is_base = part.
IsBase();
2010 if ( is_part_built_sync )
2011 {
2013 {
2017
2018 if (is_base)
2019 {
2022 }
2023 }
2024 }
2025 else
2026 {
2028 {
2032
2033 if (is_base)
2034 {
2037 }
2038 }
2039 }
2040
2041
2043 }
2044
2045
2047 {
2050
2051 for ( int i = 0; i < construction_parts.Count(); ++i )
2052 {
2053 string key = construction_parts.GetKey( i );
2056 }
2057
2058
2060 }
2061
2063 {
2066
2067 for ( int i = 0; i < construction_parts.Count(); ++i )
2068 {
2069 string key = construction_parts.GetKey( i );
2071
2072 if ( value.
GetId() ==
id )
2073 {
2074 return value;
2075 }
2076 }
2077
2078 return NULL;
2079 }
2080
2081
2082
2084 {
2086 }
2087
2089 {
2091 }
2092
2094 {
2095 return true;
2096 }
2097
2099 {
2100 return false;
2101 }
2102
2103
2105 {
2108 {
2110 }
2111
2112 return construction_kit;
2113 }
2114
2116 {
2119 {
2121 }
2122 }
2123
2125 {
2127 }
2128
2130 {
2131 return "";
2132 }
2133
2135 {
2138 }
2139
2140
2142 {
2145 }
2146
2147
2149 {
2150 super.OnStoreSave( ctx );
2151
2152
2156
2158 }
2159
2161 {
2162 if ( !super.OnStoreLoad( ctx, version ) )
2163 return false;
2164
2165
2166
2168 {
2170 return false;
2171 }
2173 {
2175 return false;
2176 }
2178 {
2180 return false;
2181 }
2182
2183
2185 {
2187 return false;
2188 }
2189
2190
2191 return true;
2192 }
2193
2195 {
2196 super.AfterStoreLoad();
2197
2199 {
2201 }
2202 }
2203
2205 {
2206
2208
2209
2212
2213
2215 }
2216
2218 {
2219 super.OnCreatePhysics();
2222 }
2223
2225 {
2227 return;
2228
2229 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2230
2232 return;
2233
2235 string part_name = zone;
2237
2239 {
2240 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2241
2242 if ( construction_part && construction.IsPartConstructed( part_name ) )
2243 {
2245 construction.DestroyConnectedParts(part_name);
2246 }
2247
2248
2249 if ( part_name.
Contains(
"barbed") )
2250 {
2251 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2252 if (barbed_wire)
2253 barbed_wire.SetMountedState( false );
2254 }
2255 }
2256 }
2257
2259 {
2261 {
2263 }
2264
2265 super.EEOnAfterLoad();
2266 }
2267
2269 {
2270 super.EEInit();
2271
2272
2274
2275
2276 #ifdef DEVELOPER
2278 #endif
2279 }
2280
2282 {
2283 super.EEItemAttached( item, slot_name );
2284
2288 }
2289
2291 {
2292 super.EEItemDetached( item, slot_name );
2293
2296 }
2297
2298 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2299 {
2302
2305 }
2306
2307
2309 {
2310 return true;
2311 }
2312
2313
2314
2316 {
2318
2319
2320 if (construtionPart.
IsBase())
2321 {
2323
2324
2326 }
2327
2328
2330
2331
2333
2334
2336
2338
2340
2341
2343
2344
2346 }
2347
2349 {
2350
2352 }
2353
2354
2356 {
2359
2360
2362
2363
2365
2366
2368
2369
2371
2373
2374
2376
2377
2379
2380
2381 if (construtionPart.
IsBase())
2382 {
2383
2385 }
2386 }
2387
2389 {
2390
2392 }
2393
2394
2395 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2396 {
2399
2400
2402
2403
2405
2406
2408
2409
2411
2413
2414
2416
2417
2419
2420
2421 if (construtionPart.
IsBase())
2422 {
2423
2425 }
2426 }
2427
2429 {
2430
2432 }
2433
2436 {
2437 bool process = false;
2438
2439
2443
2444 if (process)
2445 {
2446 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2447 {
2449 return;
2450 }
2451
2453 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2454 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2455
2456
2458 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2459 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2460 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2461 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2462 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2463 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2464 mins = minTmp;
2465 maxs = maxTmp;
2466
2467 maxs[1] = maxs[1] + 0.35;
2468
2470 }
2471 }
2472
2475 {
2478
2479
2481 foreach (
EntityAI entity : foundEntities)
2482 {
2485 }
2486 }
2487
2488
2490 {
2492
2496 }
2497
2499 {
2501
2503 {
2505 }
2506 else
2507 {
2509 }
2510
2512 }
2513
2515 {
2517
2519 foreach (
string slotName : attachmentSlots)
2520 {
2522 }
2523
2524
2527 else
2529
2531 }
2532
2534 {
2535 string slotNameMounted = slot_name + "_Mounted";
2536 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2537
2538 if (attachment)
2539 {
2540 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2541 if (barbedWire && barbedWire.IsMounted())
2543 else
2545
2546 if (is_locked)
2547 {
2548 SetAnimationPhase(slotNameMounted, 0);
2549 SetAnimationPhase(slot_name, 1);
2550 }
2551 else
2552 {
2553 SetAnimationPhase(slotNameMounted, 1);
2554 SetAnimationPhase(slot_name, 0);
2555 }
2556 }
2557 else
2558 {
2559 SetAnimationPhase(slotNameMounted, 1);
2560 SetAnimationPhase(slot_name, 1);
2561
2563 }
2564 }
2565
2566
2568 {
2571
2574
2577
2578 foreach (
string slotName : attachmentSlots)
2579 {
2581 }
2582
2583
2585 {
2588
2590 }
2591 else
2592 {
2595
2597 }
2598
2601 }
2602
2604 {
2605
2607 return;
2608
2609 string slot_name_mounted = slot_name + "_Mounted";
2610 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2611
2612
2614 RemoveProxyPhysics( slot_name_mounted );
2615 RemoveProxyPhysics( slot_name );
2616
2617 if ( attachment )
2618 {
2620 if ( is_locked )
2621 {
2623 AddProxyPhysics( slot_name_mounted );
2624 }
2625 else
2626 {
2628 AddProxyPhysics( slot_name );
2629 }
2630 }
2631 }
2632
2634 {
2635 SetAffectPathgraph( true, false );
2637 }
2638
2640 {
2641 return true;
2642 }
2643
2645 {
2646 return true;
2647 }
2648
2650 {
2651 if ( attachment )
2652 {
2654 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2655
2656 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2657 }
2658
2659 return false;
2660 }
2661
2663 {
2665 }
2666
2667
2669 {
2670 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2671 if (
GetGame().ConfigIsExisting( config_path ) )
2672 {
2674 }
2675 }
2676
2678 {
2679 return true;
2680 }
2681
2683 {
2684 return true;
2685 }
2686
2688 {
2689 return true;
2690 }
2691
2692
2694 {
2696 {
2698 }
2699
2701 }
2702
2704 {
2706 }
2707
2708
2709
2711 {
2712 return super.CanReceiveAttachment(attachment, slotId);
2713 }
2714
2716 {
2717 int attachment_count = GetInventory().AttachmentCount();
2718 if ( attachment_count > 0 )
2719 {
2720 if (
HasBase() && attachment_count == 1 )
2721 {
2722 return false;
2723 }
2724
2725 return true;
2726 }
2727
2728 return false;
2729 }
2730
2732 {
2733 return true;
2734 }
2735
2737 {
2738 return false;
2739 }
2740
2741
2743 {
2744 return false;
2745 }
2746
2748 {
2749 return false;
2750 }
2751
2752
2754 {
2755 return false;
2756 }
2757
2758
2759
2761 {
2762 return true;
2763 }
2764
2766 {
2767 return true;
2768 }
2769
2772 {
2773 return false;
2774 }
2775
2776
2778 {
2779 return true;
2780 }
2781
2782
2784 {
2785 return false;
2786 }
2787
2788
2790 {
2791 return true;
2792 }
2793
2794
2796 {
2797 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2798 {
2799 return false;
2800 }
2801
2802 return true;
2803 }
2804
2806 {
2809
2810 return item;
2811 }
2812
2813
2815 {
2817 {
2818
2820
2821
2824
2826 if ( MemoryPointExists( slot_name + "_min" ) )
2827 {
2828 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2829 }
2830 if ( MemoryPointExists( slot_name + "_max" ) )
2831 {
2832 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2833 }
2834
2835
2838
2839
2842 center = ModelToWorld( center );
2843
2844
2847
2848 areaDamage.SetExtents( extents[0], extents[1] );
2849 areaDamage.SetAreaPosition( center );
2850 areaDamage.SetAreaOrientation( orientation );
2853 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2854 areaDamage.SetAmmoName( "BarbedWireHit" );
2855 areaDamage.Spawn();
2856
2858 }
2859 }
2860
2862 {
2863 if ( angle_deg != 0 )
2864 {
2865
2866 orientation[0] = orientation[0] - angle_deg;
2867
2868
2870 if ( MemoryPointExists( "rotate_axis" ) )
2871 {
2872 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2873 }
2874 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];
2875 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];
2876 center[0] = r_center_x;
2877 center[2] = r_center_z;
2878 }
2879 }
2880
2882 {
2884 {
2887 {
2888 if (areaDamage)
2889 {
2890 areaDamage.Destroy();
2891 }
2892
2894 }
2895 }
2896 }
2897
2899 {
2900 return true;
2901 }
2902
2903
2904
2905
2907 {
2909 }
2910
2912 {
2914 }
2915
2917 {
2919 }
2920
2922 {
2924
2925 switch ( material_type )
2926 {
2932 }
2933
2934 return "";
2935 }
2936
2938 {
2940
2941 switch ( material_type )
2942 {
2948 }
2949
2950 return "";
2951 }
2952
2953
2955 {
2957 {
2958
2960 {
2961 SetHealth(slot_name,"Health",item.GetHealth());
2962 }
2963 }
2964 }
2965
2967 {
2968 return 111;
2969 }
2970
2972 {
2973 super.SetActions();
2974
2978 }
2979
2980
2981
2982
2984 {
2985 }
2986
2989 {
2990 return null;
2991 }
2992
2994 {
2996 }
2997
2999 {
3002
3003 Man p;
3004
3005 #ifdef SERVER
3008 if (players.Count())
3009 p = players[0];
3010 #else
3012 #endif
3013
3015 {
3016 bool excluded = false;
3018 if (excludes)
3019 {
3020 foreach (string exclude : excludes)
3021 {
3023 {
3024 excluded = true;
3025 break;
3026 }
3027 }
3028 }
3029
3030 if (!excluded)
3031 {
3033 }
3034 }
3035
3037 }
3038}
3039
3041{
3042#ifdef BSB_DEBUG
3044#else
3045
3046#endif
3047}
3049{
3050#ifdef BSB_DEBUG_SPAM
3052#else
3053
3054#endif
3055}
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.