1978{
1980
1982
1984
1986
1992
1993
1994
2000
2006
2008
2012
2013
2015 {
2017
2018
2019 RegisterNetSyncVariableInt( "m_SyncParts01" );
2020 RegisterNetSyncVariableInt( "m_SyncParts02" );
2021 RegisterNetSyncVariableInt( "m_SyncParts03" );
2022 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2023 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2024 RegisterNetSyncVariableBool( "m_HasBase" );
2025
2026
2028
2029 if (ConfigIsExisting("hybridAttachments"))
2030 {
2033 }
2034 if (ConfigIsExisting("mountables"))
2035 {
2038 }
2039
2041 }
2042
2044 {
2045 super.EEDelete(parent);
2046
2048 {
2049 areaDamage.Destroy();
2050 }
2051
2052 }
2053
2055 {
2056 return "disableBaseDamage";
2057 }
2058
2060 {
2061 return true;
2062 }
2063
2065 {
2066 return EInventoryIconVisibility.HIDE_VICINITY;
2067 }
2068
2070 {
2071 super.InitItemSounds();
2072
2076
2081 }
2082
2084 {
2085 return "putDown_FenceKit_SoundSet";
2086 }
2087
2089 {
2090 return "Shelter_Site_Build_Loop_SoundSet";
2091 }
2092
2093
2095 {
2097 {
2098 SetSynchDirty();
2099 }
2100 }
2101
2103 {
2105 super.OnVariablesSynchronized();
2106
2108 }
2109
2111 {
2112
2114
2115
2117
2118
2120 }
2121
2122
2124 {
2125
2126 int offset;
2127 int mask;
2128
2129 if ( part_id >= 1 && part_id <= 31 )
2130 {
2131 offset = part_id - 1;
2132 mask = 1 << offset;
2133
2135 }
2136 else if ( part_id >= 32 && part_id <= 62 )
2137 {
2138 offset = ( part_id % 32 );
2139 mask = 1 << offset;
2140
2142 }
2143 else if ( part_id >= 63 && part_id <= 93 )
2144 {
2145 offset = ( part_id % 63 );
2146 mask = 1 << offset;
2147
2149 }
2150 }
2151
2153 {
2154
2155 int offset;
2156 int mask;
2157
2158 if ( part_id >= 1 && part_id <= 31 )
2159 {
2160 offset = part_id - 1;
2161 mask = 1 << offset;
2162
2164 }
2165 else if ( part_id >= 32 && part_id <= 62 )
2166 {
2167 offset = ( part_id % 32 );
2168 mask = 1 << offset;
2169
2171 }
2172 else if ( part_id >= 63 && part_id <= 93 )
2173 {
2174 offset = ( part_id % 63 );
2175 mask = 1 << offset;
2176
2178 }
2179 }
2180
2182 {
2183
2184 int offset;
2185 int mask;
2186
2187 if ( part_id >= 1 && part_id <= 31 )
2188 {
2189 offset = part_id - 1;
2190 mask = 1 << offset;
2191
2193 {
2194 return true;
2195 }
2196 }
2197 else if ( part_id >= 32 && part_id <= 62 )
2198 {
2199 offset = ( part_id % 32 );
2200 mask = 1 << offset;
2201
2203 {
2204 return true;
2205 }
2206 }
2207 else if ( part_id >= 63 && part_id <= 93 )
2208 {
2209 offset = ( part_id % 63 );
2210 mask = 1 << offset;
2211
2213 {
2214 return true;
2215 }
2216 }
2217
2218 return false;
2219 }
2220
2222 {
2225 }
2226
2228 {
2229
2232 }
2233
2235 {
2237 {
2240
2241 switch( build_action_id )
2242 {
2246 }
2247 }
2248 }
2249
2250
2252 {
2254 bool is_base = part.
IsBase();
2257 if ( is_part_built_sync )
2258 {
2260 {
2264
2265 if (is_base)
2266 {
2269 }
2270 }
2271 }
2272 else
2273 {
2275 {
2279
2280 if (is_base)
2281 {
2284 }
2285 }
2286 }
2287
2288
2290 }
2291
2292
2294 {
2297
2298 for ( int i = 0; i < construction_parts.Count(); ++i )
2299 {
2300 string key = construction_parts.GetKey( i );
2303 }
2304
2305
2307 }
2308
2310 {
2313
2314 for ( int i = 0; i < construction_parts.Count(); ++i )
2315 {
2316 string key = construction_parts.GetKey( i );
2318
2319 if ( value.
GetId() ==
id )
2320 {
2321 return value;
2322 }
2323 }
2324
2325 return NULL;
2326 }
2327
2328
2329
2331 {
2333 }
2334
2336 {
2338 }
2339
2341 {
2342 return true;
2343 }
2344
2346 {
2347 return false;
2348 }
2349
2350
2352 {
2355 {
2357 }
2358
2359 return construction_kit;
2360 }
2361
2363 {
2366 {
2368 }
2369 }
2370
2372 {
2374 }
2375
2377 {
2378 return "";
2379 }
2380
2382 {
2385 }
2386
2387
2389 {
2392 }
2393
2394
2396 {
2397 super.OnStoreSave( ctx );
2398
2399
2403
2405 }
2406
2408 {
2409 if ( !super.OnStoreLoad( ctx, version ) )
2410 return false;
2411
2412
2413
2415 {
2417 return false;
2418 }
2420 {
2422 return false;
2423 }
2425 {
2427 return false;
2428 }
2429
2430
2432 {
2434 return false;
2435 }
2436
2437
2438 return true;
2439 }
2440
2442 {
2443 super.AfterStoreLoad();
2444
2446 {
2448 }
2449 }
2450
2452 {
2453
2455
2456
2459
2460
2462 }
2463
2465 {
2466 super.OnCreatePhysics();
2469 }
2470
2472 {
2474 return;
2475
2476 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2477
2479 return;
2480
2482 string part_name = zone;
2484
2486 {
2487 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2488
2489 if ( construction_part && construction.IsPartConstructed( part_name ) )
2490 {
2492 construction.DestroyConnectedParts(part_name);
2493 }
2494
2495
2496 if ( part_name.
Contains(
"barbed") )
2497 {
2498 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2499 if (barbed_wire)
2500 barbed_wire.SetMountedState( false );
2501 }
2502 }
2503 }
2504
2506 {
2508 {
2510 }
2511
2512 super.EEOnAfterLoad();
2513 }
2514
2516 {
2517 super.EEInit();
2518
2519
2521
2522
2523 #ifdef DEVELOPER
2525 #endif
2526 }
2527
2529 {
2530 super.EEItemAttached( item, slot_name );
2531
2535 }
2536
2538 {
2539 super.EEItemDetached( item, slot_name );
2540
2543 }
2544
2545 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2546 {
2549
2552 }
2553
2554
2556 {
2557 return true;
2558 }
2559
2560
2561
2563 {
2565
2566
2567 if (construtionPart.
IsBase())
2568 {
2570
2571
2573 }
2574
2575
2577
2578
2580
2581
2583
2585
2587
2588
2590
2591
2593 }
2594
2596 {
2597
2599 }
2600
2601
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
2641
2642 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2643 {
2646
2647
2649
2650
2652
2653
2655
2656
2658
2660
2661
2663
2664
2666
2667
2668 if (construtionPart.
IsBase())
2669 {
2670
2672 }
2673 }
2674
2676 {
2677
2679 }
2680
2683 {
2684 bool process = false;
2685
2686
2690
2691 if (process)
2692 {
2693 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2694 {
2696 return;
2697 }
2698
2700 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2701 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2702
2703
2705 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2706 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2707 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2708 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2709 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2710 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2711 mins = minTmp;
2712 maxs = maxTmp;
2713
2714 maxs[1] = maxs[1] + 0.35;
2715
2717 }
2718 }
2719
2722 {
2725
2726
2728 foreach (
EntityAI entity : foundEntities)
2729 {
2732 }
2733 }
2734
2735
2737 {
2739
2743 }
2744
2746 {
2748
2750 {
2752 }
2753 else
2754 {
2756 }
2757
2759 }
2760
2762 {
2764
2766 foreach (
string slotName : attachmentSlots)
2767 {
2769 }
2770
2771
2774 else
2776
2778 }
2779
2781 {
2782 string slotNameMounted = slot_name + "_Mounted";
2783 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2784
2785 if (attachment)
2786 {
2787 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2788 if (barbedWire && barbedWire.IsMounted())
2790 else
2792
2793 if (is_locked)
2794 {
2795 SetAnimationPhase(slotNameMounted, 0);
2796 SetAnimationPhase(slot_name, 1);
2797 }
2798 else
2799 {
2800 SetAnimationPhase(slotNameMounted, 1);
2801 SetAnimationPhase(slot_name, 0);
2802 }
2803 }
2804 else
2805 {
2806 SetAnimationPhase(slotNameMounted, 1);
2807 SetAnimationPhase(slot_name, 1);
2808
2810 }
2811 }
2812
2813
2815 {
2818
2821
2824
2825 foreach (
string slotName : attachmentSlots)
2826 {
2828 }
2829
2830
2832 {
2835
2837 }
2838 else
2839 {
2842
2844 }
2845
2848 }
2849
2851 {
2852
2854 return;
2855
2856 string slot_name_mounted = slot_name + "_Mounted";
2857 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2858
2859
2861 RemoveProxyPhysics( slot_name_mounted );
2862 RemoveProxyPhysics( slot_name );
2863
2864 if ( attachment )
2865 {
2867 if ( is_locked )
2868 {
2870 AddProxyPhysics( slot_name_mounted );
2871 }
2872 else
2873 {
2875 AddProxyPhysics( slot_name );
2876 }
2877 }
2878 }
2879
2881 {
2882 SetAffectPathgraph( true, false );
2884 }
2885
2887 {
2888 return true;
2889 }
2890
2892 {
2893 return true;
2894 }
2895
2897 {
2898 if ( attachment )
2899 {
2901 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2902
2903 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2904 }
2905
2906 return false;
2907 }
2908
2910 {
2912 }
2913
2914
2916 {
2917 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2918 if (
GetGame().ConfigIsExisting( config_path ) )
2919 {
2921 }
2922 }
2923
2925 {
2926 return true;
2927 }
2928
2930 {
2931 return true;
2932 }
2933
2935 {
2936 return true;
2937 }
2938
2939
2941 {
2943 {
2945 }
2946
2948 }
2949
2951 {
2953 }
2954
2955
2956
2958 {
2959 return super.CanReceiveAttachment(attachment, slotId);
2960 }
2961
2963 {
2964 int attachment_count = GetInventory().AttachmentCount();
2965 if ( attachment_count > 0 )
2966 {
2967 if (
HasBase() && attachment_count == 1 )
2968 {
2969 return false;
2970 }
2971
2972 return true;
2973 }
2974
2975 return false;
2976 }
2977
2979 {
2980 return true;
2981 }
2982
2984 {
2985 return false;
2986 }
2987
2988
2990 {
2991 return false;
2992 }
2993
2995 {
2996 return false;
2997 }
2998
2999
3001 {
3002 return false;
3003 }
3004
3005
3006
3008 {
3009 return true;
3010 }
3011
3013 {
3014 return true;
3015 }
3016
3019 {
3020 return false;
3021 }
3022
3023
3025 {
3026 return true;
3027 }
3028
3029
3031 {
3032 return false;
3033 }
3034
3035
3037 {
3038 return true;
3039 }
3040
3041
3043 {
3044 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3045 {
3046 return false;
3047 }
3048
3049 return true;
3050 }
3051
3053 {
3056
3057 return item;
3058 }
3059
3060
3062 {
3064 {
3065
3067
3068
3071
3073 if ( MemoryPointExists( slot_name + "_min" ) )
3074 {
3075 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3076 }
3077 if ( MemoryPointExists( slot_name + "_max" ) )
3078 {
3079 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3080 }
3081
3082
3085
3086
3089 center = ModelToWorld( center );
3090
3091
3094
3095 areaDamage.SetExtents( extents[0], extents[1] );
3096 areaDamage.SetAreaPosition( center );
3097 areaDamage.SetAreaOrientation( orientation );
3100 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3101 areaDamage.SetAmmoName( "BarbedWireHit" );
3102 areaDamage.Spawn();
3103
3105 }
3106 }
3107
3109 {
3110 if ( angle_deg != 0 )
3111 {
3112
3113 orientation[0] = orientation[0] - angle_deg;
3114
3115
3117 if ( MemoryPointExists( "rotate_axis" ) )
3118 {
3119 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3120 }
3121 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];
3122 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];
3123 center[0] = r_center_x;
3124 center[2] = r_center_z;
3125 }
3126 }
3127
3129 {
3131 {
3134 {
3135 if (areaDamage)
3136 {
3137 areaDamage.Destroy();
3138 }
3139
3141 }
3142 }
3143 }
3144
3146 {
3147 return true;
3148 }
3149
3150
3151
3152
3154 {
3156 }
3157
3159 {
3161 }
3162
3164 {
3166 }
3167
3169 {
3171
3172 switch ( material_type )
3173 {
3179 }
3180
3181 return "";
3182 }
3183
3185 {
3187
3188 switch ( material_type )
3189 {
3195 }
3196
3197 return "";
3198 }
3199
3200
3202 {
3204 {
3205
3207 {
3208 SetHealth(slot_name,"Health",item.GetHealth());
3209 }
3210 }
3211 }
3212
3214 {
3215 return 111;
3216 }
3217
3219 {
3220 super.SetActions();
3221
3225 }
3226
3227
3228
3229
3231 {
3232 }
3233
3236 {
3237 return null;
3238 }
3239
3241 {
3243 }
3244
3246 {
3249
3250 Man p;
3251
3252 #ifdef SERVER
3255 if (players.Count())
3256 p = players[0];
3257 #else
3259 #endif
3260
3262 {
3263 bool excluded = false;
3265 if (excludes)
3266 {
3267 foreach (string exclude : excludes)
3268 {
3270 {
3271 excluded = true;
3272 break;
3273 }
3274 }
3275 }
3276
3277 if (!excluded)
3278 {
3280 }
3281 }
3282
3284 }
3285}
3286
3288{
3289#ifdef BSB_DEBUG
3291#else
3292
3293#endif
3294}
3296{
3297#ifdef BSB_DEBUG_SPAM
3299#else
3300
3301#endif
3302}
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.