2116{
2118
2120
2122
2124
2130
2131
2132
2138
2144
2146
2150
2151
2153 {
2155
2156
2157 RegisterNetSyncVariableInt( "m_SyncParts01" );
2158 RegisterNetSyncVariableInt( "m_SyncParts02" );
2159 RegisterNetSyncVariableInt( "m_SyncParts03" );
2160 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2161 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2162 RegisterNetSyncVariableBool( "m_HasBase" );
2163
2164
2166
2167 if (ConfigIsExisting("hybridAttachments"))
2168 {
2171 }
2172 if (ConfigIsExisting("mountables"))
2173 {
2176 }
2177
2179 }
2180
2182 {
2183 super.EEDelete(parent);
2184
2186 {
2187 areaDamage.Destroy();
2188 }
2189
2190 }
2191
2193 {
2194 return "disableBaseDamage";
2195 }
2196
2198 {
2199 return true;
2200 }
2201
2203 {
2204 return EInventoryIconVisibility.HIDE_VICINITY;
2205 }
2206
2208 {
2209 super.InitItemSounds();
2210
2214
2219 }
2220
2222 {
2223 return "putDown_FenceKit_SoundSet";
2224 }
2225
2227 {
2228 return "Shelter_Site_Build_Loop_SoundSet";
2229 }
2230
2231
2233 {
2235 {
2236 SetSynchDirty();
2237 }
2238 }
2239
2241 {
2243 super.OnVariablesSynchronized();
2244
2246 }
2247
2249 {
2250
2252
2253
2255
2256
2258 }
2259
2260
2262 {
2263
2264 int offset;
2265 int mask;
2266
2267 if ( part_id >= 1 && part_id <= 31 )
2268 {
2269 offset = part_id - 1;
2270 mask = 1 << offset;
2271
2273 }
2274 else if ( part_id >= 32 && part_id <= 62 )
2275 {
2276 offset = ( part_id % 32 );
2277 mask = 1 << offset;
2278
2280 }
2281 else if ( part_id >= 63 && part_id <= 93 )
2282 {
2283 offset = ( part_id % 63 );
2284 mask = 1 << offset;
2285
2287 }
2288 }
2289
2291 {
2292
2293 int offset;
2294 int mask;
2295
2296 if ( part_id >= 1 && part_id <= 31 )
2297 {
2298 offset = part_id - 1;
2299 mask = 1 << offset;
2300
2302 }
2303 else if ( part_id >= 32 && part_id <= 62 )
2304 {
2305 offset = ( part_id % 32 );
2306 mask = 1 << offset;
2307
2309 }
2310 else if ( part_id >= 63 && part_id <= 93 )
2311 {
2312 offset = ( part_id % 63 );
2313 mask = 1 << offset;
2314
2316 }
2317 }
2318
2320 {
2321
2322 int offset;
2323 int mask;
2324
2325 if ( part_id >= 1 && part_id <= 31 )
2326 {
2327 offset = part_id - 1;
2328 mask = 1 << offset;
2329
2331 {
2332 return true;
2333 }
2334 }
2335 else if ( part_id >= 32 && part_id <= 62 )
2336 {
2337 offset = ( part_id % 32 );
2338 mask = 1 << offset;
2339
2341 {
2342 return true;
2343 }
2344 }
2345 else if ( part_id >= 63 && part_id <= 93 )
2346 {
2347 offset = ( part_id % 63 );
2348 mask = 1 << offset;
2349
2351 {
2352 return true;
2353 }
2354 }
2355
2356 return false;
2357 }
2358
2360 {
2363 }
2364
2366 {
2367
2370 }
2371
2373 {
2375 {
2378
2379 switch( build_action_id )
2380 {
2384 }
2385 }
2386 }
2387
2388
2390 {
2392 bool is_base = part.
IsBase();
2395 if ( is_part_built_sync )
2396 {
2398 {
2402
2403 if (is_base)
2404 {
2407 }
2408 }
2409 }
2410 else
2411 {
2413 {
2417
2418 if (is_base)
2419 {
2422 }
2423 }
2424 }
2425
2426
2428 }
2429
2430
2432 {
2435
2436 for ( int i = 0; i < construction_parts.Count(); ++i )
2437 {
2438 string key = construction_parts.GetKey( i );
2441 }
2442
2443
2445 }
2446
2448 {
2451
2452 for ( int i = 0; i < construction_parts.Count(); ++i )
2453 {
2454 string key = construction_parts.GetKey( i );
2456
2457 if ( value.
GetId() ==
id )
2458 {
2459 return value;
2460 }
2461 }
2462
2463 return NULL;
2464 }
2465
2466
2467
2469 {
2471 }
2472
2474 {
2476 }
2477
2479 {
2480 return true;
2481 }
2482
2484 {
2485 return false;
2486 }
2487
2488
2490 {
2493 {
2495 }
2496
2497 return construction_kit;
2498 }
2499
2501 {
2504 {
2506 }
2507 }
2508
2510 {
2512 }
2513
2515 {
2516 return "";
2517 }
2518
2520 {
2523 }
2524
2525
2527 {
2530 }
2531
2532
2534 {
2535 super.OnStoreSave( ctx );
2536
2537
2541
2543 }
2544
2546 {
2547 if ( !super.OnStoreLoad( ctx, version ) )
2548 return false;
2549
2550
2551
2553 {
2555 return false;
2556 }
2558 {
2560 return false;
2561 }
2563 {
2565 return false;
2566 }
2567
2568
2570 {
2572 return false;
2573 }
2574
2575
2576 return true;
2577 }
2578
2580 {
2581 super.AfterStoreLoad();
2582
2584 {
2586 }
2587 }
2588
2590 {
2591
2593
2594
2597
2598
2600 }
2601
2603 {
2604 super.OnCreatePhysics();
2607 }
2608
2610 {
2612 return;
2613
2614 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2615
2617 return;
2618
2620 string part_name = zone;
2622
2624 {
2625 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2626
2627 if ( construction_part && construction.IsPartConstructed( part_name ) )
2628 {
2630 construction.DestroyConnectedParts(part_name);
2631 }
2632
2633
2634 if ( part_name.
Contains(
"barbed") )
2635 {
2636 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2637 if (barbed_wire)
2638 barbed_wire.SetMountedState( false );
2639 }
2640 }
2641 }
2642
2644 {
2646 {
2648 }
2649
2650 super.EEOnAfterLoad();
2651 }
2652
2654 {
2655 super.EEInit();
2656
2657
2659
2660
2661 #ifdef DEVELOPER
2663 #endif
2664 }
2665
2667 {
2668 super.EEItemAttached( item, slot_name );
2669
2673 }
2674
2676 {
2677 super.EEItemDetached( item, slot_name );
2678
2681 }
2682
2683 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2684 {
2687
2690 }
2691
2692
2694 {
2695 return true;
2696 }
2697
2698
2699
2701 {
2703
2704
2705 if (construtionPart.
IsBase())
2706 {
2708
2709
2711 }
2712
2713
2715
2716
2718
2719
2721
2723
2725
2726
2728
2729
2731 }
2732
2734 {
2735
2737 }
2738
2739
2741 {
2744
2745
2747
2748
2750
2751
2753
2754
2756
2758
2759
2761
2762
2764
2765
2766 if (construtionPart.
IsBase())
2767 {
2768
2770 }
2771 }
2772
2774 {
2775
2777 }
2778
2779
2780 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2781 {
2784
2785
2787
2788
2790
2791
2793
2794
2796
2798
2799
2801
2802
2804
2805
2806 if (construtionPart.
IsBase())
2807 {
2808
2810 }
2811 }
2812
2814 {
2815
2817 }
2818
2821 {
2822 bool process = false;
2823
2824
2828
2829 if (process)
2830 {
2831 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2832 {
2834 return;
2835 }
2836
2838 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2839 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2840
2841
2843 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2844 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2845 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2846 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2847 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2848 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2849 mins = minTmp;
2850 maxs = maxTmp;
2851
2852 maxs[1] = maxs[1] + 0.35;
2853
2855 }
2856 }
2857
2860 {
2863
2864
2866 foreach (
EntityAI entity : foundEntities)
2867 {
2870 }
2871 }
2872
2873
2875 {
2877
2881 }
2882
2884 {
2886
2888 {
2890 }
2891 else
2892 {
2894 }
2895
2897 }
2898
2900 {
2902
2904 foreach (
string slotName : attachmentSlots)
2905 {
2907 }
2908
2909
2912 else
2914
2916 }
2917
2919 {
2920 string slotNameMounted = slot_name + "_Mounted";
2921 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2922
2923 if (attachment)
2924 {
2925 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2926 if (barbedWire && barbedWire.IsMounted())
2928 else
2930
2931 if (is_locked)
2932 {
2933 SetAnimationPhase(slotNameMounted, 0);
2934 SetAnimationPhase(slot_name, 1);
2935 }
2936 else
2937 {
2938 SetAnimationPhase(slotNameMounted, 1);
2939 SetAnimationPhase(slot_name, 0);
2940 }
2941 }
2942 else
2943 {
2944 SetAnimationPhase(slotNameMounted, 1);
2945 SetAnimationPhase(slot_name, 1);
2946
2948 }
2949 }
2950
2951
2953 {
2956
2959
2962
2963 foreach (
string slotName : attachmentSlots)
2964 {
2966 }
2967
2968
2970 {
2973
2975 }
2976 else
2977 {
2980
2982 }
2983
2986 }
2987
2989 {
2990
2992 return;
2993
2994 string slot_name_mounted = slot_name + "_Mounted";
2995 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2996
2997
2999 RemoveProxyPhysics( slot_name_mounted );
3000 RemoveProxyPhysics( slot_name );
3001
3002 if ( attachment )
3003 {
3005 if ( is_locked )
3006 {
3008 AddProxyPhysics( slot_name_mounted );
3009 }
3010 else
3011 {
3013 AddProxyPhysics( slot_name );
3014 }
3015 }
3016 }
3017
3019 {
3020 SetAffectPathgraph( true, false );
3022 }
3023
3025 {
3026 return true;
3027 }
3028
3030 {
3031 return true;
3032 }
3033
3035 {
3036 if ( attachment )
3037 {
3039 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3040
3041 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3042 }
3043
3044 return false;
3045 }
3046
3048 {
3050 }
3051
3052
3054 {
3055 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3056 if (
GetGame().ConfigIsExisting( config_path ) )
3057 {
3059 }
3060 }
3061
3063 {
3064 return true;
3065 }
3066
3068 {
3069 return true;
3070 }
3071
3073 {
3074 return true;
3075 }
3076
3077
3079 {
3081 {
3083 }
3084
3086 }
3087
3089 {
3091 }
3092
3093
3094
3096 {
3097 return super.CanReceiveAttachment(attachment, slotId);
3098 }
3099
3101 {
3102 int attachment_count = GetInventory().AttachmentCount();
3103 if ( attachment_count > 0 )
3104 {
3105 if (
HasBase() && attachment_count == 1 )
3106 {
3107 return false;
3108 }
3109
3110 return true;
3111 }
3112
3113 return false;
3114 }
3115
3117 {
3118 return true;
3119 }
3120
3122 {
3123 return false;
3124 }
3125
3126
3128 {
3129 return false;
3130 }
3131
3133 {
3134 return false;
3135 }
3136
3137
3139 {
3140 return false;
3141 }
3142
3143
3144
3146 {
3147 return true;
3148 }
3149
3151 {
3152 return true;
3153 }
3154
3157 {
3158 return false;
3159 }
3160
3161
3163 {
3164 return true;
3165 }
3166
3167
3169 {
3170 return false;
3171 }
3172
3173
3175 {
3176 return true;
3177 }
3178
3179
3181 {
3182 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3183 {
3184 return false;
3185 }
3186
3187 return true;
3188 }
3189
3191 {
3194
3195 return item;
3196 }
3197
3198
3200 {
3202 {
3203
3205
3206
3209
3211 if ( MemoryPointExists( slot_name + "_min" ) )
3212 {
3213 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3214 }
3215 if ( MemoryPointExists( slot_name + "_max" ) )
3216 {
3217 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3218 }
3219
3220
3223
3224
3227 center = ModelToWorld( center );
3228
3229
3232
3233 areaDamage.SetExtents( extents[0], extents[1] );
3234 areaDamage.SetAreaPosition( center );
3235 areaDamage.SetAreaOrientation( orientation );
3238 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3239 areaDamage.SetAmmoName( "BarbedWireHit" );
3240 areaDamage.Spawn();
3241
3243 }
3244 }
3245
3247 {
3248 if ( angle_deg != 0 )
3249 {
3250
3251 orientation[0] = orientation[0] - angle_deg;
3252
3253
3255 if ( MemoryPointExists( "rotate_axis" ) )
3256 {
3257 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3258 }
3259 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];
3260 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];
3261 center[0] = r_center_x;
3262 center[2] = r_center_z;
3263 }
3264 }
3265
3267 {
3269 {
3272 {
3273 if (areaDamage)
3274 {
3275 areaDamage.Destroy();
3276 }
3277
3279 }
3280 }
3281 }
3282
3284 {
3285 return true;
3286 }
3287
3288
3289
3290
3292 {
3294 }
3295
3297 {
3299 }
3300
3302 {
3304 }
3305
3307 {
3309
3310 switch ( material_type )
3311 {
3317 }
3318
3319 return "";
3320 }
3321
3323 {
3325
3326 switch ( material_type )
3327 {
3333 }
3334
3335 return "";
3336 }
3337
3338
3340 {
3342 {
3343
3345 {
3346 SetHealth(slot_name,"Health",item.GetHealth());
3347 }
3348 }
3349 }
3350
3352 {
3353 return 111;
3354 }
3355
3357 {
3358 super.SetActions();
3359
3363 }
3364
3365
3366
3367
3369 {
3370 }
3371
3374 {
3375 return null;
3376 }
3377
3379 {
3381 }
3382
3384 {
3387
3388 Man p;
3389
3390 #ifdef SERVER
3393 if (players.Count())
3394 p = players[0];
3395 #else
3397 #endif
3398
3400 {
3401 bool excluded = false;
3403 if (excludes)
3404 {
3405 foreach (string exclude : excludes)
3406 {
3408 {
3409 excluded = true;
3410 break;
3411 }
3412 }
3413 }
3414
3415 if (!excluded)
3416 {
3418 }
3419 }
3420
3422 }
3423}
3424
3426{
3427#ifdef BSB_DEBUG
3429#else
3430
3431#endif
3432}
3434{
3435#ifdef BSB_DEBUG_SPAM
3437#else
3438
3439#endif
3440}
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.