1800{
1802
1804
1806
1808
1814
1815
1816
1822
1828
1830
1834
1835
1837 {
1839
1840
1841 RegisterNetSyncVariableInt( "m_SyncParts01" );
1842 RegisterNetSyncVariableInt( "m_SyncParts02" );
1843 RegisterNetSyncVariableInt( "m_SyncParts03" );
1844 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1845 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1846 RegisterNetSyncVariableBool( "m_HasBase" );
1847
1848
1850
1851 if (ConfigIsExisting("hybridAttachments"))
1852 {
1855 }
1856 if (ConfigIsExisting("mountables"))
1857 {
1860 }
1861
1863 }
1864
1866 {
1867 super.EEDelete(parent);
1868
1870 {
1871 areaDamage.Destroy();
1872 }
1873
1874 }
1875
1877 {
1878 return "disableBaseDamage";
1879 }
1880
1882 {
1883 return true;
1884 }
1885
1887 {
1888 return EInventoryIconVisibility.HIDE_VICINITY;
1889 }
1890
1892 {
1893 super.InitItemSounds();
1894
1898
1903 }
1904
1906 {
1907 return "putDown_FenceKit_SoundSet";
1908 }
1909
1911 {
1912 return "Shelter_Site_Build_Loop_SoundSet";
1913 }
1914
1915
1917 {
1919 {
1920 SetSynchDirty();
1921 }
1922 }
1923
1925 {
1927 super.OnVariablesSynchronized();
1928
1930 }
1931
1933 {
1934
1936
1937
1939
1940
1942 }
1943
1944
1946 {
1947
1948 int offset;
1949 int mask;
1950
1951 if ( part_id >= 1 && part_id <= 31 )
1952 {
1953 offset = part_id - 1;
1954 mask = 1 << offset;
1955
1957 }
1958 else if ( part_id >= 32 && part_id <= 62 )
1959 {
1960 offset = ( part_id % 32 );
1961 mask = 1 << offset;
1962
1964 }
1965 else if ( part_id >= 63 && part_id <= 93 )
1966 {
1967 offset = ( part_id % 63 );
1968 mask = 1 << offset;
1969
1971 }
1972 }
1973
1975 {
1976
1977 int offset;
1978 int mask;
1979
1980 if ( part_id >= 1 && part_id <= 31 )
1981 {
1982 offset = part_id - 1;
1983 mask = 1 << offset;
1984
1986 }
1987 else if ( part_id >= 32 && part_id <= 62 )
1988 {
1989 offset = ( part_id % 32 );
1990 mask = 1 << offset;
1991
1993 }
1994 else if ( part_id >= 63 && part_id <= 93 )
1995 {
1996 offset = ( part_id % 63 );
1997 mask = 1 << offset;
1998
2000 }
2001 }
2002
2004 {
2005
2006 int offset;
2007 int mask;
2008
2009 if ( part_id >= 1 && part_id <= 31 )
2010 {
2011 offset = part_id - 1;
2012 mask = 1 << offset;
2013
2015 {
2016 return true;
2017 }
2018 }
2019 else if ( part_id >= 32 && part_id <= 62 )
2020 {
2021 offset = ( part_id % 32 );
2022 mask = 1 << offset;
2023
2025 {
2026 return true;
2027 }
2028 }
2029 else if ( part_id >= 63 && part_id <= 93 )
2030 {
2031 offset = ( part_id % 63 );
2032 mask = 1 << offset;
2033
2035 {
2036 return true;
2037 }
2038 }
2039
2040 return false;
2041 }
2042
2044 {
2047 }
2048
2050 {
2051
2054 }
2055
2057 {
2059 {
2062
2063 switch( build_action_id )
2064 {
2068 }
2069 }
2070 }
2071
2072
2074 {
2076 bool is_base = part.
IsBase();
2079 if ( is_part_built_sync )
2080 {
2082 {
2086
2087 if (is_base)
2088 {
2091 }
2092 }
2093 }
2094 else
2095 {
2097 {
2101
2102 if (is_base)
2103 {
2106 }
2107 }
2108 }
2109
2110
2112 }
2113
2114
2116 {
2119
2120 for ( int i = 0; i < construction_parts.Count(); ++i )
2121 {
2122 string key = construction_parts.GetKey( i );
2125 }
2126
2127
2129 }
2130
2132 {
2135
2136 for ( int i = 0; i < construction_parts.Count(); ++i )
2137 {
2138 string key = construction_parts.GetKey( i );
2140
2141 if ( value.
GetId() ==
id )
2142 {
2143 return value;
2144 }
2145 }
2146
2147 return NULL;
2148 }
2149
2150
2151
2153 {
2155 }
2156
2158 {
2160 }
2161
2163 {
2164 return true;
2165 }
2166
2168 {
2169 return false;
2170 }
2171
2172
2174 {
2177 {
2179 }
2180
2181 return construction_kit;
2182 }
2183
2185 {
2188 {
2190 }
2191 }
2192
2194 {
2196 }
2197
2199 {
2200 return "";
2201 }
2202
2204 {
2207 }
2208
2209
2211 {
2214 }
2215
2216
2218 {
2219 super.OnStoreSave( ctx );
2220
2221
2225
2227 }
2228
2230 {
2231 if ( !super.OnStoreLoad( ctx, version ) )
2232 return false;
2233
2234
2235
2237 {
2239 return false;
2240 }
2242 {
2244 return false;
2245 }
2247 {
2249 return false;
2250 }
2251
2252
2254 {
2256 return false;
2257 }
2258
2259
2260 return true;
2261 }
2262
2264 {
2265 super.AfterStoreLoad();
2266
2268 {
2270 }
2271 }
2272
2274 {
2275
2277
2278
2281
2282
2284 }
2285
2287 {
2288 super.OnCreatePhysics();
2291 }
2292
2294 {
2296 return;
2297
2298 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2299
2301 return;
2302
2304 string part_name = zone;
2306
2308 {
2309 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2310
2311 if ( construction_part && construction.IsPartConstructed( part_name ) )
2312 {
2314 construction.DestroyConnectedParts(part_name);
2315 }
2316
2317
2318 if ( part_name.
Contains(
"barbed") )
2319 {
2320 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2321 if (barbed_wire)
2322 barbed_wire.SetMountedState( false );
2323 }
2324 }
2325 }
2326
2328 {
2330 {
2332 }
2333
2334 super.EEOnAfterLoad();
2335 }
2336
2338 {
2339 super.EEInit();
2340
2341
2343
2344
2345 #ifdef DEVELOPER
2347 #endif
2348 }
2349
2351 {
2352 super.EEItemAttached( item, slot_name );
2353
2357 }
2358
2360 {
2361 super.EEItemDetached( item, slot_name );
2362
2365 }
2366
2367 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2368 {
2371
2374 }
2375
2376
2378 {
2379 return true;
2380 }
2381
2382
2383
2385 {
2387
2388
2389 if (construtionPart.
IsBase())
2390 {
2392
2393
2395 }
2396
2397
2399
2400
2402
2403
2405
2407
2409
2410
2412
2413
2415 }
2416
2418 {
2419
2421 }
2422
2423
2425 {
2428
2429
2431
2432
2434
2435
2437
2438
2440
2442
2443
2445
2446
2448
2449
2450 if (construtionPart.
IsBase())
2451 {
2452
2454 }
2455 }
2456
2458 {
2459
2461 }
2462
2463
2464 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2465 {
2468
2469
2471
2472
2474
2475
2477
2478
2480
2482
2483
2485
2486
2488
2489
2490 if (construtionPart.
IsBase())
2491 {
2492
2494 }
2495 }
2496
2498 {
2499
2501 }
2502
2505 {
2506 bool process = false;
2507
2508
2512
2513 if (process)
2514 {
2515 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2516 {
2518 return;
2519 }
2520
2522 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2523 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2524
2525
2527 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2528 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2529 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2530 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2531 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2532 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2533 mins = minTmp;
2534 maxs = maxTmp;
2535
2536 maxs[1] = maxs[1] + 0.35;
2537
2539 }
2540 }
2541
2544 {
2547
2548
2550 foreach (
EntityAI entity : foundEntities)
2551 {
2554 }
2555 }
2556
2557
2559 {
2561
2565 }
2566
2568 {
2570
2572 {
2574 }
2575 else
2576 {
2578 }
2579
2581 }
2582
2584 {
2586
2588 foreach (
string slotName : attachmentSlots)
2589 {
2591 }
2592
2593
2596 else
2598
2600 }
2601
2603 {
2604 string slotNameMounted = slot_name + "_Mounted";
2605 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2606
2607 if (attachment)
2608 {
2609 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2610 if (barbedWire && barbedWire.IsMounted())
2612 else
2614
2615 if (is_locked)
2616 {
2617 SetAnimationPhase(slotNameMounted, 0);
2618 SetAnimationPhase(slot_name, 1);
2619 }
2620 else
2621 {
2622 SetAnimationPhase(slotNameMounted, 1);
2623 SetAnimationPhase(slot_name, 0);
2624 }
2625 }
2626 else
2627 {
2628 SetAnimationPhase(slotNameMounted, 1);
2629 SetAnimationPhase(slot_name, 1);
2630
2632 }
2633 }
2634
2635
2637 {
2640
2643
2646
2647 foreach (
string slotName : attachmentSlots)
2648 {
2650 }
2651
2652
2654 {
2657
2659 }
2660 else
2661 {
2664
2666 }
2667
2670 }
2671
2673 {
2674
2676 return;
2677
2678 string slot_name_mounted = slot_name + "_Mounted";
2679 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2680
2681
2683 RemoveProxyPhysics( slot_name_mounted );
2684 RemoveProxyPhysics( slot_name );
2685
2686 if ( attachment )
2687 {
2689 if ( is_locked )
2690 {
2692 AddProxyPhysics( slot_name_mounted );
2693 }
2694 else
2695 {
2697 AddProxyPhysics( slot_name );
2698 }
2699 }
2700 }
2701
2703 {
2704 SetAffectPathgraph( true, false );
2706 }
2707
2709 {
2710 return true;
2711 }
2712
2714 {
2715 return true;
2716 }
2717
2719 {
2720 if ( attachment )
2721 {
2723 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2724
2725 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2726 }
2727
2728 return false;
2729 }
2730
2732 {
2734 }
2735
2736
2738 {
2739 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2740 if (
GetGame().ConfigIsExisting( config_path ) )
2741 {
2743 }
2744 }
2745
2747 {
2748 return true;
2749 }
2750
2752 {
2753 return true;
2754 }
2755
2757 {
2758 return true;
2759 }
2760
2761
2763 {
2765 {
2767 }
2768
2770 }
2771
2773 {
2775 }
2776
2777
2778
2780 {
2781 return super.CanReceiveAttachment(attachment, slotId);
2782 }
2783
2785 {
2786 int attachment_count = GetInventory().AttachmentCount();
2787 if ( attachment_count > 0 )
2788 {
2789 if (
HasBase() && attachment_count == 1 )
2790 {
2791 return false;
2792 }
2793
2794 return true;
2795 }
2796
2797 return false;
2798 }
2799
2801 {
2802 return true;
2803 }
2804
2806 {
2807 return false;
2808 }
2809
2810
2812 {
2813 return false;
2814 }
2815
2817 {
2818 return false;
2819 }
2820
2821
2823 {
2824 return false;
2825 }
2826
2827
2828
2830 {
2831 return true;
2832 }
2833
2835 {
2836 return true;
2837 }
2838
2841 {
2842 return false;
2843 }
2844
2845
2847 {
2848 return true;
2849 }
2850
2851
2853 {
2854 return false;
2855 }
2856
2857
2859 {
2860 return true;
2861 }
2862
2863
2865 {
2866 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2867 {
2868 return false;
2869 }
2870
2871 return true;
2872 }
2873
2875 {
2878
2879 return item;
2880 }
2881
2882
2884 {
2886 {
2887
2889
2890
2893
2895 if ( MemoryPointExists( slot_name + "_min" ) )
2896 {
2897 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2898 }
2899 if ( MemoryPointExists( slot_name + "_max" ) )
2900 {
2901 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2902 }
2903
2904
2907
2908
2911 center = ModelToWorld( center );
2912
2913
2916
2917 areaDamage.SetExtents( extents[0], extents[1] );
2918 areaDamage.SetAreaPosition( center );
2919 areaDamage.SetAreaOrientation( orientation );
2922 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2923 areaDamage.SetAmmoName( "BarbedWireHit" );
2924 areaDamage.Spawn();
2925
2927 }
2928 }
2929
2931 {
2932 if ( angle_deg != 0 )
2933 {
2934
2935 orientation[0] = orientation[0] - angle_deg;
2936
2937
2939 if ( MemoryPointExists( "rotate_axis" ) )
2940 {
2941 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2942 }
2943 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];
2944 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];
2945 center[0] = r_center_x;
2946 center[2] = r_center_z;
2947 }
2948 }
2949
2951 {
2953 {
2956 {
2957 if (areaDamage)
2958 {
2959 areaDamage.Destroy();
2960 }
2961
2963 }
2964 }
2965 }
2966
2968 {
2969 return true;
2970 }
2971
2972
2973
2974
2976 {
2978 }
2979
2981 {
2983 }
2984
2986 {
2988 }
2989
2991 {
2993
2994 switch ( material_type )
2995 {
3001 }
3002
3003 return "";
3004 }
3005
3007 {
3009
3010 switch ( material_type )
3011 {
3017 }
3018
3019 return "";
3020 }
3021
3022
3024 {
3026 {
3027
3029 {
3030 SetHealth(slot_name,"Health",item.GetHealth());
3031 }
3032 }
3033 }
3034
3036 {
3037 return 111;
3038 }
3039
3041 {
3042 super.SetActions();
3043
3047 }
3048
3049
3050
3051
3053 {
3054 }
3055
3058 {
3059 return null;
3060 }
3061
3063 {
3065 }
3066
3068 {
3071
3072 Man p;
3073
3074 #ifdef SERVER
3077 if (players.Count())
3078 p = players[0];
3079 #else
3081 #endif
3082
3084 {
3085 bool excluded = false;
3087 if (excludes)
3088 {
3089 foreach (string exclude : excludes)
3090 {
3092 {
3093 excluded = true;
3094 break;
3095 }
3096 }
3097 }
3098
3099 if (!excluded)
3100 {
3102 }
3103 }
3104
3106 }
3107}
3108
3110{
3111#ifdef BSB_DEBUG
3113#else
3114
3115#endif
3116}
3118{
3119#ifdef BSB_DEBUG_SPAM
3121#else
3122
3123#endif
3124}
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.