2319{
2321
2323
2325
2327
2333
2334
2335
2341
2347
2349
2353
2354
2356 {
2358
2359
2360 RegisterNetSyncVariableInt( "m_SyncParts01" );
2361 RegisterNetSyncVariableInt( "m_SyncParts02" );
2362 RegisterNetSyncVariableInt( "m_SyncParts03" );
2363 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2364 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2365 RegisterNetSyncVariableBool( "m_HasBase" );
2366
2367
2369
2370 if (ConfigIsExisting("hybridAttachments"))
2371 {
2374 }
2375 if (ConfigIsExisting("mountables"))
2376 {
2379 }
2380
2382 }
2383
2385 {
2386 super.EEDelete(parent);
2387
2389 {
2390 areaDamage.Destroy();
2391 }
2392
2393 }
2394
2396 {
2397 return "disableBaseDamage";
2398 }
2399
2401 {
2402 return true;
2403 }
2404
2406 {
2407 return EInventoryIconVisibility.HIDE_VICINITY;
2408 }
2409
2411 {
2412 super.InitItemSounds();
2413
2417
2422 }
2423
2425 {
2426 return "putDown_FenceKit_SoundSet";
2427 }
2428
2430 {
2431 return "Shelter_Site_Build_Loop_SoundSet";
2432 }
2433
2434
2436 {
2438 {
2439 SetSynchDirty();
2440 }
2441 }
2442
2444 {
2446 super.OnVariablesSynchronized();
2447
2449 }
2450
2452 {
2453
2455
2456
2458
2459
2461 }
2462
2463
2465 {
2466
2467 int offset;
2468 int mask;
2469
2470 if ( part_id >= 1 && part_id <= 31 )
2471 {
2472 offset = part_id - 1;
2473 mask = 1 << offset;
2474
2476 }
2477 else if ( part_id >= 32 && part_id <= 62 )
2478 {
2479 offset = ( part_id % 32 );
2480 mask = 1 << offset;
2481
2483 }
2484 else if ( part_id >= 63 && part_id <= 93 )
2485 {
2486 offset = ( part_id % 63 );
2487 mask = 1 << offset;
2488
2490 }
2491 }
2492
2494 {
2495
2496 int offset;
2497 int mask;
2498
2499 if ( part_id >= 1 && part_id <= 31 )
2500 {
2501 offset = part_id - 1;
2502 mask = 1 << offset;
2503
2505 }
2506 else if ( part_id >= 32 && part_id <= 62 )
2507 {
2508 offset = ( part_id % 32 );
2509 mask = 1 << offset;
2510
2512 }
2513 else if ( part_id >= 63 && part_id <= 93 )
2514 {
2515 offset = ( part_id % 63 );
2516 mask = 1 << offset;
2517
2519 }
2520 }
2521
2523 {
2524
2525 int offset;
2526 int mask;
2527
2528 if ( part_id >= 1 && part_id <= 31 )
2529 {
2530 offset = part_id - 1;
2531 mask = 1 << offset;
2532
2534 {
2535 return true;
2536 }
2537 }
2538 else if ( part_id >= 32 && part_id <= 62 )
2539 {
2540 offset = ( part_id % 32 );
2541 mask = 1 << offset;
2542
2544 {
2545 return true;
2546 }
2547 }
2548 else if ( part_id >= 63 && part_id <= 93 )
2549 {
2550 offset = ( part_id % 63 );
2551 mask = 1 << offset;
2552
2554 {
2555 return true;
2556 }
2557 }
2558
2559 return false;
2560 }
2561
2563 {
2566 }
2567
2569 {
2570
2573 }
2574
2576 {
2578 {
2581
2582 switch( build_action_id )
2583 {
2587 }
2588 }
2589 }
2590
2591
2593 {
2595 bool is_base = part.
IsBase();
2598 if ( is_part_built_sync )
2599 {
2601 {
2605
2606 if (is_base)
2607 {
2610 }
2611 }
2612 }
2613 else
2614 {
2616 {
2620
2621 if (is_base)
2622 {
2625 }
2626 }
2627 }
2628
2629
2631 }
2632
2633
2635 {
2638
2639 for ( int i = 0; i < construction_parts.Count(); ++i )
2640 {
2641 string key = construction_parts.GetKey( i );
2644 }
2645
2646
2648 }
2649
2651 {
2654
2655 for ( int i = 0; i < construction_parts.Count(); ++i )
2656 {
2657 string key = construction_parts.GetKey( i );
2659
2660 if ( value.
GetId() ==
id )
2661 {
2662 return value;
2663 }
2664 }
2665
2666 return NULL;
2667 }
2668
2669
2670
2672 {
2674 }
2675
2677 {
2679 }
2680
2682 {
2683 return true;
2684 }
2685
2687 {
2688 return false;
2689 }
2690
2691
2693 {
2696 {
2698 }
2699
2700 return construction_kit;
2701 }
2702
2704 {
2707 {
2709 }
2710 }
2711
2713 {
2715 }
2716
2718 {
2719 return "";
2720 }
2721
2723 {
2726 }
2727
2728
2730 {
2733 }
2734
2735
2737 {
2738 super.OnStoreSave( ctx );
2739
2740
2744
2746 }
2747
2749 {
2750 if ( !super.OnStoreLoad( ctx, version ) )
2751 return false;
2752
2753
2754
2756 {
2758 return false;
2759 }
2761 {
2763 return false;
2764 }
2766 {
2768 return false;
2769 }
2770
2771
2773 {
2775 return false;
2776 }
2777
2778
2779 return true;
2780 }
2781
2783 {
2784 super.AfterStoreLoad();
2785
2787 {
2789 }
2790 }
2791
2793 {
2794
2796
2797
2800
2801
2803 }
2804
2806 {
2807 super.OnCreatePhysics();
2810 }
2811
2813 {
2815 return;
2816
2817 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2818
2820 return;
2821
2823 string part_name = zone;
2825
2827 {
2828 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2829
2830 if ( construction_part && construction.IsPartConstructed( part_name ) )
2831 {
2833 construction.DestroyConnectedParts(part_name);
2834 }
2835
2836
2837 if ( part_name.
Contains(
"barbed") )
2838 {
2839 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2840 if (barbed_wire)
2841 barbed_wire.SetMountedState( false );
2842 }
2843 }
2844 }
2845
2847 {
2849 {
2851 }
2852
2853 super.EEOnAfterLoad();
2854 }
2855
2857 {
2858 super.EEInit();
2859
2860
2862
2863
2864 #ifdef DEVELOPER
2866 #endif
2867 }
2868
2870 {
2871 super.EEItemAttached( item, slot_name );
2872
2876 }
2877
2879 {
2880 super.EEItemDetached( item, slot_name );
2881
2884 }
2885
2886 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2887 {
2890
2893 }
2894
2895
2897 {
2898 return true;
2899 }
2900
2901
2902
2904 {
2906
2907
2908 if (construtionPart.
IsBase())
2909 {
2911
2912
2914 }
2915
2916
2918
2919
2921
2922
2924
2926
2928
2929
2931
2932
2934 }
2935
2937 {
2938
2940 }
2941
2942
2944 {
2947
2948
2950
2951
2953
2954
2956
2957
2959
2961
2962
2964
2965
2967
2968
2969 if (construtionPart.
IsBase())
2970 {
2971
2973 }
2974 }
2975
2977 {
2978
2980 }
2981
2982
2983 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2984 {
2987
2988
2990
2991
2993
2994
2996
2997
2999
3001
3002
3004
3005
3007
3008
3009 if (construtionPart.
IsBase())
3010 {
3011
3013 }
3014 }
3015
3017 {
3018
3020 }
3021
3024 {
3025 bool process = false;
3026
3027
3031
3032 if (process)
3033 {
3034 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3035 {
3037 return;
3038 }
3039
3041 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3042 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3043
3044
3046 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3047 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3048 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3049 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3050 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3051 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3052 mins = minTmp;
3053 maxs = maxTmp;
3054
3055 maxs[1] = maxs[1] + 0.35;
3056
3058 }
3059 }
3060
3063 {
3066
3067
3069 foreach (
EntityAI entity : foundEntities)
3070 {
3073 }
3074 }
3075
3076
3078 {
3080
3084 }
3085
3087 {
3089
3091 {
3093 }
3094 else
3095 {
3097 }
3098
3100 }
3101
3103 {
3105
3107 foreach (
string slotName : attachmentSlots)
3108 {
3110 }
3111
3112
3115 else
3117
3119 }
3120
3122 {
3123 string slotNameMounted = slot_name + "_Mounted";
3124 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3125
3126 if (attachment)
3127 {
3128 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3129 if (barbedWire && barbedWire.IsMounted())
3131 else
3133
3134 if (is_locked)
3135 {
3136 SetAnimationPhase(slotNameMounted, 0);
3137 SetAnimationPhase(slot_name, 1);
3138 }
3139 else
3140 {
3141 SetAnimationPhase(slotNameMounted, 1);
3142 SetAnimationPhase(slot_name, 0);
3143 }
3144 }
3145 else
3146 {
3147 SetAnimationPhase(slotNameMounted, 1);
3148 SetAnimationPhase(slot_name, 1);
3149
3151 }
3152 }
3153
3154
3156 {
3159
3162
3165
3166 foreach (
string slotName : attachmentSlots)
3167 {
3169 }
3170
3171
3173 {
3176
3178 }
3179 else
3180 {
3183
3185 }
3186
3189 }
3190
3192 {
3193
3195 return;
3196
3197 string slot_name_mounted = slot_name + "_Mounted";
3198 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3199
3200
3202 RemoveProxyPhysics( slot_name_mounted );
3203 RemoveProxyPhysics( slot_name );
3204
3205 if ( attachment )
3206 {
3208 if ( is_locked )
3209 {
3211 AddProxyPhysics( slot_name_mounted );
3212 }
3213 else
3214 {
3216 AddProxyPhysics( slot_name );
3217 }
3218 }
3219 }
3220
3222 {
3223 SetAffectPathgraph( true, false );
3225 }
3226
3228 {
3229 return true;
3230 }
3231
3233 {
3234 return true;
3235 }
3236
3238 {
3239 if ( attachment )
3240 {
3242 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3243
3244 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3245 }
3246
3247 return false;
3248 }
3249
3251 {
3253 }
3254
3255
3257 {
3258 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3259 if (
GetGame().ConfigIsExisting( config_path ) )
3260 {
3262 }
3263 }
3264
3266 {
3267 return true;
3268 }
3269
3271 {
3272 return true;
3273 }
3274
3276 {
3277 return true;
3278 }
3279
3280
3282 {
3284 {
3286 }
3287
3289 }
3290
3292 {
3294 }
3295
3296
3297
3299 {
3300 return super.CanReceiveAttachment(attachment, slotId);
3301 }
3302
3304 {
3305 int attachment_count = GetInventory().AttachmentCount();
3306 if ( attachment_count > 0 )
3307 {
3308 if (
HasBase() && attachment_count == 1 )
3309 {
3310 return false;
3311 }
3312
3313 return true;
3314 }
3315
3316 return false;
3317 }
3318
3320 {
3321 return true;
3322 }
3323
3325 {
3326 return false;
3327 }
3328
3329
3331 {
3332 return false;
3333 }
3334
3336 {
3337 return false;
3338 }
3339
3340
3342 {
3343 return false;
3344 }
3345
3346
3347
3349 {
3350 return true;
3351 }
3352
3354 {
3355 return true;
3356 }
3357
3360 {
3361 return false;
3362 }
3363
3364
3366 {
3367 return true;
3368 }
3369
3370
3372 {
3373 return false;
3374 }
3375
3376
3378 {
3379 return true;
3380 }
3381
3382
3384 {
3385 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3386 {
3387 return false;
3388 }
3389
3390 return true;
3391 }
3392
3394 {
3397
3398 return item;
3399 }
3400
3401
3403 {
3405 {
3406
3408
3409
3412
3414 if ( MemoryPointExists( slot_name + "_min" ) )
3415 {
3416 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3417 }
3418 if ( MemoryPointExists( slot_name + "_max" ) )
3419 {
3420 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3421 }
3422
3423
3426
3427
3430 center = ModelToWorld( center );
3431
3432
3435
3436 areaDamage.SetExtents( extents[0], extents[1] );
3437 areaDamage.SetAreaPosition( center );
3438 areaDamage.SetAreaOrientation( orientation );
3441 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3442 areaDamage.SetAmmoName( "BarbedWireHit" );
3443 areaDamage.Spawn();
3444
3446 }
3447 }
3448
3450 {
3451 if ( angle_deg != 0 )
3452 {
3453
3454 orientation[0] = orientation[0] - angle_deg;
3455
3456
3458 if ( MemoryPointExists( "rotate_axis" ) )
3459 {
3460 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3461 }
3462 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];
3463 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];
3464 center[0] = r_center_x;
3465 center[2] = r_center_z;
3466 }
3467 }
3468
3470 {
3472 {
3475 {
3476 if (areaDamage)
3477 {
3478 areaDamage.Destroy();
3479 }
3480
3482 }
3483 }
3484 }
3485
3487 {
3488 return true;
3489 }
3490
3491
3492
3493
3495 {
3497 }
3498
3500 {
3502 }
3503
3505 {
3507 }
3508
3510 {
3512
3513 switch ( material_type )
3514 {
3520 }
3521
3522 return "";
3523 }
3524
3526 {
3528
3529 switch ( material_type )
3530 {
3536 }
3537
3538 return "";
3539 }
3540
3541
3543 {
3545 {
3546
3548 {
3549 SetHealth(slot_name,"Health",item.GetHealth());
3550 }
3551 }
3552 }
3553
3555 {
3556 return 111;
3557 }
3558
3560 {
3561 super.SetActions();
3562
3566 }
3567
3568
3569
3570
3572 {
3573 }
3574
3577 {
3578 return null;
3579 }
3580
3582 {
3584 }
3585
3587 {
3590
3591 Man p;
3592
3593 #ifdef SERVER
3596 if (players.Count())
3597 p = players[0];
3598 #else
3600 #endif
3601
3603 {
3604 bool excluded = false;
3606 if (excludes)
3607 {
3608 foreach (string exclude : excludes)
3609 {
3611 {
3612 excluded = true;
3613 break;
3614 }
3615 }
3616 }
3617
3618 if (!excluded)
3619 {
3621 }
3622 }
3623
3625 }
3626}
3627
3629{
3630#ifdef BSB_DEBUG
3632#else
3633
3634#endif
3635}
3637{
3638#ifdef BSB_DEBUG_SPAM
3640#else
3641
3642#endif
3643}
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.