2520{
2522
2524
2526
2528
2534
2535
2536
2542
2548
2550
2554
2555
2557 {
2559
2560
2561 RegisterNetSyncVariableInt( "m_SyncParts01" );
2562 RegisterNetSyncVariableInt( "m_SyncParts02" );
2563 RegisterNetSyncVariableInt( "m_SyncParts03" );
2564 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2565 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2566 RegisterNetSyncVariableBool( "m_HasBase" );
2567
2568
2570
2571 if (ConfigIsExisting("hybridAttachments"))
2572 {
2575 }
2576 if (ConfigIsExisting("mountables"))
2577 {
2580 }
2581
2583 }
2584
2586 {
2587 super.EEDelete(parent);
2588
2590 {
2591 areaDamage.Destroy();
2592 }
2593
2594 }
2595
2597 {
2598 return "disableBaseDamage";
2599 }
2600
2602 {
2603 return true;
2604 }
2605
2607 {
2608 return EInventoryIconVisibility.HIDE_VICINITY;
2609 }
2610
2612 {
2613 super.InitItemSounds();
2614
2618
2623 }
2624
2626 {
2627 return "putDown_FenceKit_SoundSet";
2628 }
2629
2631 {
2632 return "Shelter_Site_Build_Loop_SoundSet";
2633 }
2634
2635
2637 {
2639 {
2640 SetSynchDirty();
2641 }
2642 }
2643
2645 {
2647 super.OnVariablesSynchronized();
2648
2650 }
2651
2653 {
2654
2656
2657
2659
2660
2662 }
2663
2664
2666 {
2667
2668 int offset;
2669 int mask;
2670
2671 if ( part_id >= 1 && part_id <= 31 )
2672 {
2673 offset = part_id - 1;
2674 mask = 1 << offset;
2675
2677 }
2678 else if ( part_id >= 32 && part_id <= 62 )
2679 {
2680 offset = ( part_id % 32 );
2681 mask = 1 << offset;
2682
2684 }
2685 else if ( part_id >= 63 && part_id <= 93 )
2686 {
2687 offset = ( part_id % 63 );
2688 mask = 1 << offset;
2689
2691 }
2692 }
2693
2695 {
2696
2697 int offset;
2698 int mask;
2699
2700 if ( part_id >= 1 && part_id <= 31 )
2701 {
2702 offset = part_id - 1;
2703 mask = 1 << offset;
2704
2706 }
2707 else if ( part_id >= 32 && part_id <= 62 )
2708 {
2709 offset = ( part_id % 32 );
2710 mask = 1 << offset;
2711
2713 }
2714 else if ( part_id >= 63 && part_id <= 93 )
2715 {
2716 offset = ( part_id % 63 );
2717 mask = 1 << offset;
2718
2720 }
2721 }
2722
2724 {
2725
2726 int offset;
2727 int mask;
2728
2729 if ( part_id >= 1 && part_id <= 31 )
2730 {
2731 offset = part_id - 1;
2732 mask = 1 << offset;
2733
2735 {
2736 return true;
2737 }
2738 }
2739 else if ( part_id >= 32 && part_id <= 62 )
2740 {
2741 offset = ( part_id % 32 );
2742 mask = 1 << offset;
2743
2745 {
2746 return true;
2747 }
2748 }
2749 else if ( part_id >= 63 && part_id <= 93 )
2750 {
2751 offset = ( part_id % 63 );
2752 mask = 1 << offset;
2753
2755 {
2756 return true;
2757 }
2758 }
2759
2760 return false;
2761 }
2762
2764 {
2767 }
2768
2770 {
2771
2774 }
2775
2777 {
2779 {
2782
2783 switch( build_action_id )
2784 {
2788 }
2789 }
2790 }
2791
2792
2794 {
2796 bool is_base = part.
IsBase();
2799 if ( is_part_built_sync )
2800 {
2802 {
2806
2807 if (is_base)
2808 {
2811 }
2812 }
2813 }
2814 else
2815 {
2817 {
2821
2822 if (is_base)
2823 {
2826 }
2827 }
2828 }
2829
2830
2832 }
2833
2834
2836 {
2839
2840 for ( int i = 0; i < construction_parts.Count(); ++i )
2841 {
2842 string key = construction_parts.GetKey( i );
2845 }
2846
2847
2849 }
2850
2852 {
2855
2856 for ( int i = 0; i < construction_parts.Count(); ++i )
2857 {
2858 string key = construction_parts.GetKey( i );
2860
2861 if ( value.
GetId() ==
id )
2862 {
2863 return value;
2864 }
2865 }
2866
2867 return NULL;
2868 }
2869
2870
2871
2873 {
2875 }
2876
2878 {
2880 }
2881
2883 {
2884 return true;
2885 }
2886
2888 {
2889 return false;
2890 }
2891
2892
2894 {
2897 {
2899 }
2900
2901 return construction_kit;
2902 }
2903
2905 {
2908 {
2910 }
2911 }
2912
2914 {
2916 }
2917
2919 {
2920 return "";
2921 }
2922
2924 {
2927 }
2928
2929
2931 {
2934 }
2935
2936
2938 {
2939 super.OnStoreSave( ctx );
2940
2941
2945
2947 }
2948
2950 {
2951 if ( !super.OnStoreLoad( ctx, version ) )
2952 return false;
2953
2954
2955
2957 {
2959 return false;
2960 }
2962 {
2964 return false;
2965 }
2967 {
2969 return false;
2970 }
2971
2972
2974 {
2976 return false;
2977 }
2978
2979
2980 return true;
2981 }
2982
2984 {
2985 super.AfterStoreLoad();
2986
2988 {
2990 }
2991 }
2992
2994 {
2995
2997
2998
3001
3002
3004 }
3005
3007 {
3008 super.OnCreatePhysics();
3011 }
3012
3014 {
3016 return;
3017
3018 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
3019
3021 return;
3022
3024 string part_name = zone;
3026
3028 {
3029 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
3030
3031 if ( construction_part && construction.IsPartConstructed( part_name ) )
3032 {
3034 construction.DestroyConnectedParts(part_name);
3035 }
3036
3037
3038 if ( part_name.
Contains(
"barbed") )
3039 {
3040 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
3041 if (barbed_wire)
3042 barbed_wire.SetMountedState( false );
3043 }
3044 }
3045 }
3046
3048 {
3050 {
3052 }
3053
3054 super.EEOnAfterLoad();
3055 }
3056
3058 {
3059 super.EEInit();
3060
3061
3063
3064
3065 #ifdef DEVELOPER
3067 #endif
3068 }
3069
3071 {
3072 super.EEItemAttached( item, slot_name );
3073
3077 }
3078
3080 {
3081 super.EEItemDetached( item, slot_name );
3082
3085 }
3086
3087 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
3088 {
3091
3094 }
3095
3096
3098 {
3099 return true;
3100 }
3101
3102
3103
3105 {
3107
3108
3109 if (construtionPart.
IsBase())
3110 {
3112
3113
3115 }
3116
3117
3119
3120
3122
3123
3125
3127
3129
3130
3132
3133
3135 }
3136
3138 {
3139
3141 }
3142
3143
3145 {
3148
3149
3151
3152
3154
3155
3157
3158
3160
3162
3163
3165
3166
3168
3169
3170 if (construtionPart.
IsBase())
3171 {
3172
3174 }
3175 }
3176
3178 {
3179
3181 }
3182
3183
3184 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3185 {
3188
3189
3191
3192
3194
3195
3197
3198
3200
3202
3203
3205
3206
3208
3209
3210 if (construtionPart.
IsBase())
3211 {
3212
3214 }
3215 }
3216
3218 {
3219
3221 }
3222
3225 {
3226 bool process = false;
3227
3228
3232
3233 if (process)
3234 {
3235 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3236 {
3238 return;
3239 }
3240
3242 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3243 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3244
3245
3247 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3248 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3249 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3250 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3251 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3252 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3253 mins = minTmp;
3254 maxs = maxTmp;
3255
3256 maxs[1] = maxs[1] + 0.35;
3257
3259 }
3260 }
3261
3264 {
3267
3268
3270 foreach (
EntityAI entity : foundEntities)
3271 {
3274 }
3275 }
3276
3277
3279 {
3281
3285 }
3286
3288 {
3290
3292 {
3294 }
3295 else
3296 {
3298 }
3299
3301 }
3302
3304 {
3306
3308 foreach (
string slotName : attachmentSlots)
3309 {
3311 }
3312
3313
3316 else
3318
3320 }
3321
3323 {
3324 string slotNameMounted = slot_name + "_Mounted";
3325 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3326
3327 if (attachment)
3328 {
3329 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3330 if (barbedWire && barbedWire.IsMounted())
3332 else
3334
3335 if (is_locked)
3336 {
3337 SetAnimationPhase(slotNameMounted, 0);
3338 SetAnimationPhase(slot_name, 1);
3339 }
3340 else
3341 {
3342 SetAnimationPhase(slotNameMounted, 1);
3343 SetAnimationPhase(slot_name, 0);
3344 }
3345 }
3346 else
3347 {
3348 SetAnimationPhase(slotNameMounted, 1);
3349 SetAnimationPhase(slot_name, 1);
3350
3352 }
3353 }
3354
3355
3357 {
3360
3363
3366
3367 foreach (
string slotName : attachmentSlots)
3368 {
3370 }
3371
3372
3374 {
3377
3379 }
3380 else
3381 {
3384
3386 }
3387
3390 }
3391
3393 {
3394
3396 return;
3397
3398 string slot_name_mounted = slot_name + "_Mounted";
3399 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3400
3401
3403 RemoveProxyPhysics( slot_name_mounted );
3404 RemoveProxyPhysics( slot_name );
3405
3406 if ( attachment )
3407 {
3409 if ( is_locked )
3410 {
3412 AddProxyPhysics( slot_name_mounted );
3413 }
3414 else
3415 {
3417 AddProxyPhysics( slot_name );
3418 }
3419 }
3420 }
3421
3423 {
3424 SetAffectPathgraph( true, false );
3426 }
3427
3429 {
3430 return true;
3431 }
3432
3434 {
3435 return true;
3436 }
3437
3439 {
3440 if ( attachment )
3441 {
3443 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3444
3445 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3446 }
3447
3448 return false;
3449 }
3450
3452 {
3454 }
3455
3456
3458 {
3459 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3460 if (
GetGame().ConfigIsExisting( config_path ) )
3461 {
3463 }
3464 }
3465
3467 {
3468 return true;
3469 }
3470
3472 {
3473 return true;
3474 }
3475
3477 {
3478 return true;
3479 }
3480
3481
3483 {
3485 {
3487 }
3488
3490 }
3491
3493 {
3495 }
3496
3497
3498
3500 {
3501 return super.CanReceiveAttachment(attachment, slotId);
3502 }
3503
3505 {
3506 int attachment_count = GetInventory().AttachmentCount();
3507 if ( attachment_count > 0 )
3508 {
3509 if (
HasBase() && attachment_count == 1 )
3510 {
3511 return false;
3512 }
3513
3514 return true;
3515 }
3516
3517 return false;
3518 }
3519
3521 {
3522 return true;
3523 }
3524
3526 {
3527 return false;
3528 }
3529
3530
3532 {
3533 return false;
3534 }
3535
3537 {
3538 return false;
3539 }
3540
3541
3543 {
3544 return false;
3545 }
3546
3547
3548
3550 {
3551 return true;
3552 }
3553
3555 {
3556 return true;
3557 }
3558
3561 {
3562 return false;
3563 }
3564
3565
3567 {
3568 return true;
3569 }
3570
3571
3573 {
3574 return false;
3575 }
3576
3577
3579 {
3580 return true;
3581 }
3582
3583
3585 {
3586 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3587 {
3588 return false;
3589 }
3590
3591 return true;
3592 }
3593
3595 {
3598
3599 return item;
3600 }
3601
3602
3604 {
3606 {
3607
3609
3610
3613
3615 if ( MemoryPointExists( slot_name + "_min" ) )
3616 {
3617 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3618 }
3619 if ( MemoryPointExists( slot_name + "_max" ) )
3620 {
3621 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3622 }
3623
3624
3627
3628
3631 center = ModelToWorld( center );
3632
3633
3636
3637 areaDamage.SetExtents( extents[0], extents[1] );
3638 areaDamage.SetAreaPosition( center );
3639 areaDamage.SetAreaOrientation( orientation );
3642 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3643 areaDamage.SetAmmoName( "BarbedWireHit" );
3644 areaDamage.Spawn();
3645
3647 }
3648 }
3649
3651 {
3652 if ( angle_deg != 0 )
3653 {
3654
3655 orientation[0] = orientation[0] - angle_deg;
3656
3657
3659 if ( MemoryPointExists( "rotate_axis" ) )
3660 {
3661 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3662 }
3663 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];
3664 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];
3665 center[0] = r_center_x;
3666 center[2] = r_center_z;
3667 }
3668 }
3669
3671 {
3673 {
3676 {
3677 if (areaDamage)
3678 {
3679 areaDamage.Destroy();
3680 }
3681
3683 }
3684 }
3685 }
3686
3688 {
3689 return true;
3690 }
3691
3692
3693
3694
3696 {
3698 }
3699
3701 {
3703 }
3704
3706 {
3708 }
3709
3711 {
3713
3714 switch ( material_type )
3715 {
3721 }
3722
3723 return "";
3724 }
3725
3727 {
3729
3730 switch ( material_type )
3731 {
3737 }
3738
3739 return "";
3740 }
3741
3742
3744 {
3746 {
3747
3749 {
3750 SetHealth(slot_name,"Health",item.GetHealth());
3751 }
3752 }
3753 }
3754
3756 {
3757 return 111;
3758 }
3759
3761 {
3762 super.SetActions();
3763
3767 }
3768
3769
3770
3771
3773 {
3774 }
3775
3778 {
3779 return null;
3780 }
3781
3783 {
3785 }
3786
3788 {
3791
3792 Man p;
3793
3794 #ifdef SERVER
3797 if (players.Count())
3798 p = players[0];
3799 #else
3801 #endif
3802
3804 {
3805 bool excluded = false;
3807 if (excludes)
3808 {
3809 foreach (string exclude : excludes)
3810 {
3812 {
3813 excluded = true;
3814 break;
3815 }
3816 }
3817 }
3818
3819 if (!excluded)
3820 {
3822 }
3823 }
3824
3826 }
3827}
3828
3830{
3831#ifdef BSB_DEBUG
3833#else
3834
3835#endif
3836}
3838{
3839#ifdef BSB_DEBUG_SPAM
3841#else
3842
3843#endif
3844}
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.