1938{
1940
1942
1944
1946
1952
1953
1954
1960
1966
1968
1972
1973
1975 {
1977
1978
1979 RegisterNetSyncVariableInt( "m_SyncParts01" );
1980 RegisterNetSyncVariableInt( "m_SyncParts02" );
1981 RegisterNetSyncVariableInt( "m_SyncParts03" );
1982 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1983 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1984 RegisterNetSyncVariableBool( "m_HasBase" );
1985
1986
1988
1989 if (ConfigIsExisting("hybridAttachments"))
1990 {
1993 }
1994 if (ConfigIsExisting("mountables"))
1995 {
1998 }
1999
2001 }
2002
2004 {
2005 super.EEDelete(parent);
2006
2008 {
2009 areaDamage.Destroy();
2010 }
2011
2012 }
2013
2015 {
2016 return "disableBaseDamage";
2017 }
2018
2020 {
2021 return true;
2022 }
2023
2025 {
2026 return EInventoryIconVisibility.HIDE_VICINITY;
2027 }
2028
2030 {
2031 super.InitItemSounds();
2032
2036
2041 }
2042
2044 {
2045 return "putDown_FenceKit_SoundSet";
2046 }
2047
2049 {
2050 return "Shelter_Site_Build_Loop_SoundSet";
2051 }
2052
2053
2055 {
2057 {
2058 SetSynchDirty();
2059 }
2060 }
2061
2063 {
2065 super.OnVariablesSynchronized();
2066
2068 }
2069
2071 {
2072
2074
2075
2077
2078
2080 }
2081
2082
2084 {
2085
2086 int offset;
2087 int mask;
2088
2089 if ( part_id >= 1 && part_id <= 31 )
2090 {
2091 offset = part_id - 1;
2092 mask = 1 << offset;
2093
2095 }
2096 else if ( part_id >= 32 && part_id <= 62 )
2097 {
2098 offset = ( part_id % 32 );
2099 mask = 1 << offset;
2100
2102 }
2103 else if ( part_id >= 63 && part_id <= 93 )
2104 {
2105 offset = ( part_id % 63 );
2106 mask = 1 << offset;
2107
2109 }
2110 }
2111
2113 {
2114
2115 int offset;
2116 int mask;
2117
2118 if ( part_id >= 1 && part_id <= 31 )
2119 {
2120 offset = part_id - 1;
2121 mask = 1 << offset;
2122
2124 }
2125 else if ( part_id >= 32 && part_id <= 62 )
2126 {
2127 offset = ( part_id % 32 );
2128 mask = 1 << offset;
2129
2131 }
2132 else if ( part_id >= 63 && part_id <= 93 )
2133 {
2134 offset = ( part_id % 63 );
2135 mask = 1 << offset;
2136
2138 }
2139 }
2140
2142 {
2143
2144 int offset;
2145 int mask;
2146
2147 if ( part_id >= 1 && part_id <= 31 )
2148 {
2149 offset = part_id - 1;
2150 mask = 1 << offset;
2151
2153 {
2154 return true;
2155 }
2156 }
2157 else if ( part_id >= 32 && part_id <= 62 )
2158 {
2159 offset = ( part_id % 32 );
2160 mask = 1 << offset;
2161
2163 {
2164 return true;
2165 }
2166 }
2167 else if ( part_id >= 63 && part_id <= 93 )
2168 {
2169 offset = ( part_id % 63 );
2170 mask = 1 << offset;
2171
2173 {
2174 return true;
2175 }
2176 }
2177
2178 return false;
2179 }
2180
2182 {
2185 }
2186
2188 {
2189
2192 }
2193
2195 {
2197 {
2200
2201 switch( build_action_id )
2202 {
2206 }
2207 }
2208 }
2209
2210
2212 {
2214 bool is_base = part.
IsBase();
2217 if ( is_part_built_sync )
2218 {
2220 {
2224
2225 if (is_base)
2226 {
2229 }
2230 }
2231 }
2232 else
2233 {
2235 {
2239
2240 if (is_base)
2241 {
2244 }
2245 }
2246 }
2247
2248
2250 }
2251
2252
2254 {
2257
2258 for ( int i = 0; i < construction_parts.Count(); ++i )
2259 {
2260 string key = construction_parts.GetKey( i );
2263 }
2264
2265
2267 }
2268
2270 {
2273
2274 for ( int i = 0; i < construction_parts.Count(); ++i )
2275 {
2276 string key = construction_parts.GetKey( i );
2278
2279 if ( value.
GetId() ==
id )
2280 {
2281 return value;
2282 }
2283 }
2284
2285 return NULL;
2286 }
2287
2288
2289
2291 {
2293 }
2294
2296 {
2298 }
2299
2301 {
2302 return true;
2303 }
2304
2306 {
2307 return false;
2308 }
2309
2310
2312 {
2315 {
2317 }
2318
2319 return construction_kit;
2320 }
2321
2323 {
2326 {
2328 }
2329 }
2330
2332 {
2334 }
2335
2337 {
2338 return "";
2339 }
2340
2342 {
2345 }
2346
2347
2349 {
2352 }
2353
2354
2356 {
2357 super.OnStoreSave( ctx );
2358
2359
2363
2365 }
2366
2368 {
2369 if ( !super.OnStoreLoad( ctx, version ) )
2370 return false;
2371
2372
2373
2375 {
2377 return false;
2378 }
2380 {
2382 return false;
2383 }
2385 {
2387 return false;
2388 }
2389
2390
2392 {
2394 return false;
2395 }
2396
2397
2398 return true;
2399 }
2400
2402 {
2403 super.AfterStoreLoad();
2404
2406 {
2408 }
2409 }
2410
2412 {
2413
2415
2416
2419
2420
2422 }
2423
2425 {
2426 super.OnCreatePhysics();
2429 }
2430
2432 {
2434 return;
2435
2436 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2437
2439 return;
2440
2442 string part_name = zone;
2444
2446 {
2447 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2448
2449 if ( construction_part && construction.IsPartConstructed( part_name ) )
2450 {
2452 construction.DestroyConnectedParts(part_name);
2453 }
2454
2455
2456 if ( part_name.
Contains(
"barbed") )
2457 {
2458 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2459 if (barbed_wire)
2460 barbed_wire.SetMountedState( false );
2461 }
2462 }
2463 }
2464
2466 {
2468 {
2470 }
2471
2472 super.EEOnAfterLoad();
2473 }
2474
2476 {
2477 super.EEInit();
2478
2479
2481
2482
2483 #ifdef DEVELOPER
2485 #endif
2486 }
2487
2489 {
2490 super.EEItemAttached( item, slot_name );
2491
2495 }
2496
2498 {
2499 super.EEItemDetached( item, slot_name );
2500
2503 }
2504
2505 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2506 {
2509
2512 }
2513
2514
2516 {
2517 return true;
2518 }
2519
2520
2521
2523 {
2525
2526
2527 if (construtionPart.
IsBase())
2528 {
2530
2531
2533 }
2534
2535
2537
2538
2540
2541
2543
2545
2547
2548
2550
2551
2553 }
2554
2556 {
2557
2559 }
2560
2561
2563 {
2566
2567
2569
2570
2572
2573
2575
2576
2578
2580
2581
2583
2584
2586
2587
2588 if (construtionPart.
IsBase())
2589 {
2590
2592 }
2593 }
2594
2596 {
2597
2599 }
2600
2601
2602 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2603 {
2606
2607
2609
2610
2612
2613
2615
2616
2618
2620
2621
2623
2624
2626
2627
2628 if (construtionPart.
IsBase())
2629 {
2630
2632 }
2633 }
2634
2636 {
2637
2639 }
2640
2643 {
2644 bool process = false;
2645
2646
2650
2651 if (process)
2652 {
2653 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2654 {
2656 return;
2657 }
2658
2660 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2661 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2662
2663
2665 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2666 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2667 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2668 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2669 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2670 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2671 mins = minTmp;
2672 maxs = maxTmp;
2673
2674 maxs[1] = maxs[1] + 0.35;
2675
2677 }
2678 }
2679
2682 {
2685
2686
2688 foreach (
EntityAI entity : foundEntities)
2689 {
2692 }
2693 }
2694
2695
2697 {
2699
2703 }
2704
2706 {
2708
2710 {
2712 }
2713 else
2714 {
2716 }
2717
2719 }
2720
2722 {
2724
2726 foreach (
string slotName : attachmentSlots)
2727 {
2729 }
2730
2731
2734 else
2736
2738 }
2739
2741 {
2742 string slotNameMounted = slot_name + "_Mounted";
2743 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2744
2745 if (attachment)
2746 {
2747 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2748 if (barbedWire && barbedWire.IsMounted())
2750 else
2752
2753 if (is_locked)
2754 {
2755 SetAnimationPhase(slotNameMounted, 0);
2756 SetAnimationPhase(slot_name, 1);
2757 }
2758 else
2759 {
2760 SetAnimationPhase(slotNameMounted, 1);
2761 SetAnimationPhase(slot_name, 0);
2762 }
2763 }
2764 else
2765 {
2766 SetAnimationPhase(slotNameMounted, 1);
2767 SetAnimationPhase(slot_name, 1);
2768
2770 }
2771 }
2772
2773
2775 {
2778
2781
2784
2785 foreach (
string slotName : attachmentSlots)
2786 {
2788 }
2789
2790
2792 {
2795
2797 }
2798 else
2799 {
2802
2804 }
2805
2808 }
2809
2811 {
2812
2814 return;
2815
2816 string slot_name_mounted = slot_name + "_Mounted";
2817 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2818
2819
2821 RemoveProxyPhysics( slot_name_mounted );
2822 RemoveProxyPhysics( slot_name );
2823
2824 if ( attachment )
2825 {
2827 if ( is_locked )
2828 {
2830 AddProxyPhysics( slot_name_mounted );
2831 }
2832 else
2833 {
2835 AddProxyPhysics( slot_name );
2836 }
2837 }
2838 }
2839
2841 {
2842 SetAffectPathgraph( true, false );
2844 }
2845
2847 {
2848 return true;
2849 }
2850
2852 {
2853 return true;
2854 }
2855
2857 {
2858 if ( attachment )
2859 {
2861 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2862
2863 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2864 }
2865
2866 return false;
2867 }
2868
2870 {
2872 }
2873
2874
2876 {
2877 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2878 if (
GetGame().ConfigIsExisting( config_path ) )
2879 {
2881 }
2882 }
2883
2885 {
2886 return true;
2887 }
2888
2890 {
2891 return true;
2892 }
2893
2895 {
2896 return true;
2897 }
2898
2899
2901 {
2903 {
2905 }
2906
2908 }
2909
2911 {
2913 }
2914
2915
2916
2918 {
2919 return super.CanReceiveAttachment(attachment, slotId);
2920 }
2921
2923 {
2924 int attachment_count = GetInventory().AttachmentCount();
2925 if ( attachment_count > 0 )
2926 {
2927 if (
HasBase() && attachment_count == 1 )
2928 {
2929 return false;
2930 }
2931
2932 return true;
2933 }
2934
2935 return false;
2936 }
2937
2939 {
2940 return true;
2941 }
2942
2944 {
2945 return false;
2946 }
2947
2948
2950 {
2951 return false;
2952 }
2953
2955 {
2956 return false;
2957 }
2958
2959
2961 {
2962 return false;
2963 }
2964
2965
2966
2968 {
2969 return true;
2970 }
2971
2973 {
2974 return true;
2975 }
2976
2979 {
2980 return false;
2981 }
2982
2983
2985 {
2986 return true;
2987 }
2988
2989
2991 {
2992 return false;
2993 }
2994
2995
2997 {
2998 return true;
2999 }
3000
3001
3003 {
3004 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3005 {
3006 return false;
3007 }
3008
3009 return true;
3010 }
3011
3013 {
3016
3017 return item;
3018 }
3019
3020
3022 {
3024 {
3025
3027
3028
3031
3033 if ( MemoryPointExists( slot_name + "_min" ) )
3034 {
3035 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3036 }
3037 if ( MemoryPointExists( slot_name + "_max" ) )
3038 {
3039 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3040 }
3041
3042
3045
3046
3049 center = ModelToWorld( center );
3050
3051
3054
3055 areaDamage.SetExtents( extents[0], extents[1] );
3056 areaDamage.SetAreaPosition( center );
3057 areaDamage.SetAreaOrientation( orientation );
3060 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3061 areaDamage.SetAmmoName( "BarbedWireHit" );
3062 areaDamage.Spawn();
3063
3065 }
3066 }
3067
3069 {
3070 if ( angle_deg != 0 )
3071 {
3072
3073 orientation[0] = orientation[0] - angle_deg;
3074
3075
3077 if ( MemoryPointExists( "rotate_axis" ) )
3078 {
3079 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3080 }
3081 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];
3082 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];
3083 center[0] = r_center_x;
3084 center[2] = r_center_z;
3085 }
3086 }
3087
3089 {
3091 {
3094 {
3095 if (areaDamage)
3096 {
3097 areaDamage.Destroy();
3098 }
3099
3101 }
3102 }
3103 }
3104
3106 {
3107 return true;
3108 }
3109
3110
3111
3112
3114 {
3116 }
3117
3119 {
3121 }
3122
3124 {
3126 }
3127
3129 {
3131
3132 switch ( material_type )
3133 {
3139 }
3140
3141 return "";
3142 }
3143
3145 {
3147
3148 switch ( material_type )
3149 {
3155 }
3156
3157 return "";
3158 }
3159
3160
3162 {
3164 {
3165
3167 {
3168 SetHealth(slot_name,"Health",item.GetHealth());
3169 }
3170 }
3171 }
3172
3174 {
3175 return 111;
3176 }
3177
3179 {
3180 super.SetActions();
3181
3185 }
3186
3187
3188
3189
3191 {
3192 }
3193
3196 {
3197 return null;
3198 }
3199
3201 {
3203 }
3204
3206 {
3209
3210 Man p;
3211
3212 #ifdef SERVER
3215 if (players.Count())
3216 p = players[0];
3217 #else
3219 #endif
3220
3222 {
3223 bool excluded = false;
3225 if (excludes)
3226 {
3227 foreach (string exclude : excludes)
3228 {
3230 {
3231 excluded = true;
3232 break;
3233 }
3234 }
3235 }
3236
3237 if (!excluded)
3238 {
3240 }
3241 }
3242
3244 }
3245}
3246
3248{
3249#ifdef BSB_DEBUG
3251#else
3252
3253#endif
3254}
3256{
3257#ifdef BSB_DEBUG_SPAM
3259#else
3260
3261#endif
3262}
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.