2444{
2446
2448
2450
2452
2458
2459
2460
2466
2472
2474
2478
2479
2481 {
2483
2484
2485 RegisterNetSyncVariableInt( "m_SyncParts01" );
2486 RegisterNetSyncVariableInt( "m_SyncParts02" );
2487 RegisterNetSyncVariableInt( "m_SyncParts03" );
2488 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2489 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2490 RegisterNetSyncVariableBool( "m_HasBase" );
2491
2492
2494
2495 if (ConfigIsExisting("hybridAttachments"))
2496 {
2499 }
2500 if (ConfigIsExisting("mountables"))
2501 {
2504 }
2505
2507 }
2508
2510 {
2511 super.EEDelete(parent);
2512
2514 {
2515 areaDamage.Destroy();
2516 }
2517
2518 }
2519
2521 {
2522 return "disableBaseDamage";
2523 }
2524
2526 {
2527 return true;
2528 }
2529
2531 {
2532 return EInventoryIconVisibility.HIDE_VICINITY;
2533 }
2534
2536 {
2537 super.InitItemSounds();
2538
2542
2547 }
2548
2550 {
2551 return "putDown_FenceKit_SoundSet";
2552 }
2553
2555 {
2556 return "Shelter_Site_Build_Loop_SoundSet";
2557 }
2558
2559
2561 {
2563 {
2564 SetSynchDirty();
2565 }
2566 }
2567
2569 {
2571 super.OnVariablesSynchronized();
2572
2574 }
2575
2577 {
2578
2580
2581
2583
2584
2586 }
2587
2588
2590 {
2591
2592 int offset;
2593 int mask;
2594
2595 if ( part_id >= 1 && part_id <= 31 )
2596 {
2597 offset = part_id - 1;
2598 mask = 1 << offset;
2599
2601 }
2602 else if ( part_id >= 32 && part_id <= 62 )
2603 {
2604 offset = ( part_id % 32 );
2605 mask = 1 << offset;
2606
2608 }
2609 else if ( part_id >= 63 && part_id <= 93 )
2610 {
2611 offset = ( part_id % 63 );
2612 mask = 1 << offset;
2613
2615 }
2616 }
2617
2619 {
2620
2621 int offset;
2622 int mask;
2623
2624 if ( part_id >= 1 && part_id <= 31 )
2625 {
2626 offset = part_id - 1;
2627 mask = 1 << offset;
2628
2630 }
2631 else if ( part_id >= 32 && part_id <= 62 )
2632 {
2633 offset = ( part_id % 32 );
2634 mask = 1 << offset;
2635
2637 }
2638 else if ( part_id >= 63 && part_id <= 93 )
2639 {
2640 offset = ( part_id % 63 );
2641 mask = 1 << offset;
2642
2644 }
2645 }
2646
2648 {
2649
2650 int offset;
2651 int mask;
2652
2653 if ( part_id >= 1 && part_id <= 31 )
2654 {
2655 offset = part_id - 1;
2656 mask = 1 << offset;
2657
2659 {
2660 return true;
2661 }
2662 }
2663 else if ( part_id >= 32 && part_id <= 62 )
2664 {
2665 offset = ( part_id % 32 );
2666 mask = 1 << offset;
2667
2669 {
2670 return true;
2671 }
2672 }
2673 else if ( part_id >= 63 && part_id <= 93 )
2674 {
2675 offset = ( part_id % 63 );
2676 mask = 1 << offset;
2677
2679 {
2680 return true;
2681 }
2682 }
2683
2684 return false;
2685 }
2686
2688 {
2691 }
2692
2694 {
2695
2698 }
2699
2701 {
2703 {
2706
2707 switch( build_action_id )
2708 {
2712 }
2713 }
2714 }
2715
2716
2718 {
2720 bool is_base = part.
IsBase();
2723 if ( is_part_built_sync )
2724 {
2726 {
2730
2731 if (is_base)
2732 {
2735 }
2736 }
2737 }
2738 else
2739 {
2741 {
2745
2746 if (is_base)
2747 {
2750 }
2751 }
2752 }
2753
2754
2756 }
2757
2758
2760 {
2763
2764 for ( int i = 0; i < construction_parts.Count(); ++i )
2765 {
2766 string key = construction_parts.GetKey( i );
2769 }
2770
2771
2773 }
2774
2776 {
2779
2780 for ( int i = 0; i < construction_parts.Count(); ++i )
2781 {
2782 string key = construction_parts.GetKey( i );
2784
2785 if ( value.
GetId() ==
id )
2786 {
2787 return value;
2788 }
2789 }
2790
2791 return NULL;
2792 }
2793
2794
2795
2797 {
2799 }
2800
2802 {
2804 }
2805
2807 {
2808 return true;
2809 }
2810
2812 {
2813 return false;
2814 }
2815
2816
2818 {
2821 {
2823 }
2824
2825 return construction_kit;
2826 }
2827
2829 {
2832 {
2834 }
2835 }
2836
2838 {
2840 }
2841
2843 {
2844 return "";
2845 }
2846
2848 {
2851 }
2852
2853
2855 {
2858 }
2859
2860
2862 {
2863 super.OnStoreSave( ctx );
2864
2865
2869
2871 }
2872
2874 {
2875 if ( !super.OnStoreLoad( ctx, version ) )
2876 return false;
2877
2878
2879
2881 {
2883 return false;
2884 }
2886 {
2888 return false;
2889 }
2891 {
2893 return false;
2894 }
2895
2896
2898 {
2900 return false;
2901 }
2902
2903
2904 return true;
2905 }
2906
2908 {
2909 super.AfterStoreLoad();
2910
2912 {
2914 }
2915 }
2916
2918 {
2919
2921
2922
2925
2926
2928 }
2929
2931 {
2932 super.OnCreatePhysics();
2935 }
2936
2938 {
2940 return;
2941
2942 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2943
2945 return;
2946
2948 string part_name = zone;
2950
2952 {
2953 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2954
2955 if ( construction_part && construction.IsPartConstructed( part_name ) )
2956 {
2958 construction.DestroyConnectedParts(part_name);
2959 }
2960
2961
2962 if ( part_name.
Contains(
"barbed") )
2963 {
2964 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2965 if (barbed_wire)
2966 barbed_wire.SetMountedState( false );
2967 }
2968 }
2969 }
2970
2972 {
2974 {
2976 }
2977
2978 super.EEOnAfterLoad();
2979 }
2980
2982 {
2983 super.EEInit();
2984
2985
2987
2988
2989 #ifdef DEVELOPER
2991 #endif
2992 }
2993
2995 {
2996 super.EEItemAttached( item, slot_name );
2997
3001 }
3002
3004 {
3005 super.EEItemDetached( item, slot_name );
3006
3009 }
3010
3011 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
3012 {
3015
3018 }
3019
3020
3022 {
3023 return true;
3024 }
3025
3026
3027
3029 {
3031
3032
3033 if (construtionPart.
IsBase())
3034 {
3036
3037
3039 }
3040
3041
3043
3044
3046
3047
3049
3051
3053
3054
3056
3057
3059 }
3060
3062 {
3063
3065 }
3066
3067
3069 {
3072
3073
3075
3076
3078
3079
3081
3082
3084
3086
3087
3089
3090
3092
3093
3094 if (construtionPart.
IsBase())
3095 {
3096
3098 }
3099 }
3100
3102 {
3103
3105 }
3106
3107
3108 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3109 {
3112
3113
3115
3116
3118
3119
3121
3122
3124
3126
3127
3129
3130
3132
3133
3134 if (construtionPart.
IsBase())
3135 {
3136
3138 }
3139 }
3140
3142 {
3143
3145 }
3146
3149 {
3150 bool process = false;
3151
3152
3156
3157 if (process)
3158 {
3159 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3160 {
3162 return;
3163 }
3164
3166 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3167 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3168
3169
3171 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3172 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3173 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3174 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3175 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3176 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3177 mins = minTmp;
3178 maxs = maxTmp;
3179
3180 maxs[1] = maxs[1] + 0.35;
3181
3183 }
3184 }
3185
3188 {
3191
3192
3194 foreach (
EntityAI entity : foundEntities)
3195 {
3198 }
3199 }
3200
3201
3203 {
3205
3209 }
3210
3212 {
3214
3216 {
3218 }
3219 else
3220 {
3222 }
3223
3225 }
3226
3228 {
3230
3232 foreach (
string slotName : attachmentSlots)
3233 {
3235 }
3236
3237
3240 else
3242
3244 }
3245
3247 {
3248 string slotNameMounted = slot_name + "_Mounted";
3249 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3250
3251 if (attachment)
3252 {
3253 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3254 if (barbedWire && barbedWire.IsMounted())
3256 else
3258
3259 if (is_locked)
3260 {
3261 SetAnimationPhase(slotNameMounted, 0);
3262 SetAnimationPhase(slot_name, 1);
3263 }
3264 else
3265 {
3266 SetAnimationPhase(slotNameMounted, 1);
3267 SetAnimationPhase(slot_name, 0);
3268 }
3269 }
3270 else
3271 {
3272 SetAnimationPhase(slotNameMounted, 1);
3273 SetAnimationPhase(slot_name, 1);
3274
3276 }
3277 }
3278
3279
3281 {
3284
3287
3290
3291 foreach (
string slotName : attachmentSlots)
3292 {
3294 }
3295
3296
3298 {
3301
3303 }
3304 else
3305 {
3308
3310 }
3311
3314 }
3315
3317 {
3318
3320 return;
3321
3322 string slot_name_mounted = slot_name + "_Mounted";
3323 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3324
3325
3327 RemoveProxyPhysics( slot_name_mounted );
3328 RemoveProxyPhysics( slot_name );
3329
3330 if ( attachment )
3331 {
3333 if ( is_locked )
3334 {
3336 AddProxyPhysics( slot_name_mounted );
3337 }
3338 else
3339 {
3341 AddProxyPhysics( slot_name );
3342 }
3343 }
3344 }
3345
3347 {
3348 SetAffectPathgraph( true, false );
3350 }
3351
3353 {
3354 return true;
3355 }
3356
3358 {
3359 return true;
3360 }
3361
3363 {
3364 if ( attachment )
3365 {
3367 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3368
3369 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3370 }
3371
3372 return false;
3373 }
3374
3376 {
3378 }
3379
3380
3382 {
3383 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3384 if (
GetGame().ConfigIsExisting( config_path ) )
3385 {
3387 }
3388 }
3389
3391 {
3392 return true;
3393 }
3394
3396 {
3397 return true;
3398 }
3399
3401 {
3402 return true;
3403 }
3404
3405
3407 {
3409 {
3411 }
3412
3414 }
3415
3417 {
3419 }
3420
3421
3422
3424 {
3425 return super.CanReceiveAttachment(attachment, slotId);
3426 }
3427
3429 {
3430 int attachment_count = GetInventory().AttachmentCount();
3431 if ( attachment_count > 0 )
3432 {
3433 if (
HasBase() && attachment_count == 1 )
3434 {
3435 return false;
3436 }
3437
3438 return true;
3439 }
3440
3441 return false;
3442 }
3443
3445 {
3446 return true;
3447 }
3448
3450 {
3451 return false;
3452 }
3453
3454
3456 {
3457 return false;
3458 }
3459
3461 {
3462 return false;
3463 }
3464
3465
3467 {
3468 return false;
3469 }
3470
3471
3472
3474 {
3475 return true;
3476 }
3477
3479 {
3480 return true;
3481 }
3482
3485 {
3486 return false;
3487 }
3488
3489
3491 {
3492 return true;
3493 }
3494
3495
3497 {
3498 return false;
3499 }
3500
3501
3503 {
3504 return true;
3505 }
3506
3507
3509 {
3510 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3511 {
3512 return false;
3513 }
3514
3515 return true;
3516 }
3517
3519 {
3522
3523 return item;
3524 }
3525
3526
3528 {
3530 {
3531
3533
3534
3537
3539 if ( MemoryPointExists( slot_name + "_min" ) )
3540 {
3541 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3542 }
3543 if ( MemoryPointExists( slot_name + "_max" ) )
3544 {
3545 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3546 }
3547
3548
3551
3552
3555 center = ModelToWorld( center );
3556
3557
3560
3561 areaDamage.SetExtents( extents[0], extents[1] );
3562 areaDamage.SetAreaPosition( center );
3563 areaDamage.SetAreaOrientation( orientation );
3566 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3567 areaDamage.SetAmmoName( "BarbedWireHit" );
3568 areaDamage.Spawn();
3569
3571 }
3572 }
3573
3575 {
3576 if ( angle_deg != 0 )
3577 {
3578
3579 orientation[0] = orientation[0] - angle_deg;
3580
3581
3583 if ( MemoryPointExists( "rotate_axis" ) )
3584 {
3585 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3586 }
3587 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];
3588 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];
3589 center[0] = r_center_x;
3590 center[2] = r_center_z;
3591 }
3592 }
3593
3595 {
3597 {
3600 {
3601 if (areaDamage)
3602 {
3603 areaDamage.Destroy();
3604 }
3605
3607 }
3608 }
3609 }
3610
3612 {
3613 return true;
3614 }
3615
3616
3617
3618
3620 {
3622 }
3623
3625 {
3627 }
3628
3630 {
3632 }
3633
3635 {
3637
3638 switch ( material_type )
3639 {
3645 }
3646
3647 return "";
3648 }
3649
3651 {
3653
3654 switch ( material_type )
3655 {
3661 }
3662
3663 return "";
3664 }
3665
3666
3668 {
3670 {
3671
3673 {
3674 SetHealth(slot_name,"Health",item.GetHealth());
3675 }
3676 }
3677 }
3678
3680 {
3681 return 111;
3682 }
3683
3685 {
3686 super.SetActions();
3687
3691 }
3692
3693
3694
3695
3697 {
3698 }
3699
3702 {
3703 return null;
3704 }
3705
3707 {
3709 }
3710
3712 {
3715
3716 Man p;
3717
3718 #ifdef SERVER
3721 if (players.Count())
3722 p = players[0];
3723 #else
3725 #endif
3726
3728 {
3729 bool excluded = false;
3731 if (excludes)
3732 {
3733 foreach (string exclude : excludes)
3734 {
3736 {
3737 excluded = true;
3738 break;
3739 }
3740 }
3741 }
3742
3743 if (!excluded)
3744 {
3746 }
3747 }
3748
3750 }
3751}
3752
3754{
3755#ifdef BSB_DEBUG
3757#else
3758
3759#endif
3760}
3762{
3763#ifdef BSB_DEBUG_SPAM
3765#else
3766
3767#endif
3768}
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.