2566{
2568
2570
2572
2574
2580
2581
2582
2588
2594
2596
2600
2601
2603 {
2605
2606
2607 RegisterNetSyncVariableInt( "m_SyncParts01" );
2608 RegisterNetSyncVariableInt( "m_SyncParts02" );
2609 RegisterNetSyncVariableInt( "m_SyncParts03" );
2610 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2611 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2612 RegisterNetSyncVariableBool( "m_HasBase" );
2613
2614
2616
2617 if (ConfigIsExisting("hybridAttachments"))
2618 {
2621 }
2622 if (ConfigIsExisting("mountables"))
2623 {
2626 }
2627
2629 }
2630
2632 {
2633 super.EEDelete(parent);
2634
2636 {
2637 areaDamage.Destroy();
2638 }
2639
2640 }
2641
2643 {
2644 return "disableBaseDamage";
2645 }
2646
2648 {
2649 return true;
2650 }
2651
2653 {
2654 return EInventoryIconVisibility.HIDE_VICINITY;
2655 }
2656
2658 {
2659 super.InitItemSounds();
2660
2664
2669 }
2670
2672 {
2673 return "putDown_FenceKit_SoundSet";
2674 }
2675
2677 {
2678 return "Shelter_Site_Build_Loop_SoundSet";
2679 }
2680
2681
2683 {
2685 {
2686 SetSynchDirty();
2687 }
2688 }
2689
2691 {
2693 super.OnVariablesSynchronized();
2694
2696 }
2697
2699 {
2700
2702
2703
2705
2706
2708 }
2709
2710
2712 {
2713
2714 int offset;
2715 int mask;
2716
2717 if ( part_id >= 1 && part_id <= 31 )
2718 {
2719 offset = part_id - 1;
2720 mask = 1 << offset;
2721
2723 }
2724 else if ( part_id >= 32 && part_id <= 62 )
2725 {
2726 offset = ( part_id % 32 );
2727 mask = 1 << offset;
2728
2730 }
2731 else if ( part_id >= 63 && part_id <= 93 )
2732 {
2733 offset = ( part_id % 63 );
2734 mask = 1 << offset;
2735
2737 }
2738 }
2739
2741 {
2742
2743 int offset;
2744 int mask;
2745
2746 if ( part_id >= 1 && part_id <= 31 )
2747 {
2748 offset = part_id - 1;
2749 mask = 1 << offset;
2750
2752 }
2753 else if ( part_id >= 32 && part_id <= 62 )
2754 {
2755 offset = ( part_id % 32 );
2756 mask = 1 << offset;
2757
2759 }
2760 else if ( part_id >= 63 && part_id <= 93 )
2761 {
2762 offset = ( part_id % 63 );
2763 mask = 1 << offset;
2764
2766 }
2767 }
2768
2770 {
2771
2772 int offset;
2773 int mask;
2774
2775 if ( part_id >= 1 && part_id <= 31 )
2776 {
2777 offset = part_id - 1;
2778 mask = 1 << offset;
2779
2781 {
2782 return true;
2783 }
2784 }
2785 else if ( part_id >= 32 && part_id <= 62 )
2786 {
2787 offset = ( part_id % 32 );
2788 mask = 1 << offset;
2789
2791 {
2792 return true;
2793 }
2794 }
2795 else if ( part_id >= 63 && part_id <= 93 )
2796 {
2797 offset = ( part_id % 63 );
2798 mask = 1 << offset;
2799
2801 {
2802 return true;
2803 }
2804 }
2805
2806 return false;
2807 }
2808
2810 {
2813 }
2814
2816 {
2817
2820 }
2821
2823 {
2825 {
2828
2829 switch( build_action_id )
2830 {
2834 }
2835 }
2836 }
2837
2838
2840 {
2842 bool is_base = part.
IsBase();
2845 if ( is_part_built_sync )
2846 {
2848 {
2852
2853 if (is_base)
2854 {
2857 }
2858 }
2859 }
2860 else
2861 {
2863 {
2867
2868 if (is_base)
2869 {
2872 }
2873 }
2874 }
2875
2876
2878 }
2879
2880
2882 {
2885
2886 for ( int i = 0; i < construction_parts.Count(); ++i )
2887 {
2888 string key = construction_parts.GetKey( i );
2891 }
2892
2893
2895 }
2896
2898 {
2901
2902 for ( int i = 0; i < construction_parts.Count(); ++i )
2903 {
2904 string key = construction_parts.GetKey( i );
2906
2907 if ( value.
GetId() ==
id )
2908 {
2909 return value;
2910 }
2911 }
2912
2913 return NULL;
2914 }
2915
2916
2917
2919 {
2921 }
2922
2924 {
2926 }
2927
2929 {
2930 return true;
2931 }
2932
2934 {
2935 return false;
2936 }
2937
2938
2940 {
2943 {
2945 }
2946
2947 return construction_kit;
2948 }
2949
2951 {
2954 {
2956 }
2957 }
2958
2960 {
2962 }
2963
2965 {
2966 return "";
2967 }
2968
2970 {
2973 }
2974
2975
2977 {
2980 }
2981
2982
2984 {
2985 super.OnStoreSave( ctx );
2986
2987
2991
2993 }
2994
2996 {
2997 if ( !super.OnStoreLoad( ctx, version ) )
2998 return false;
2999
3000
3001
3003 {
3005 return false;
3006 }
3008 {
3010 return false;
3011 }
3013 {
3015 return false;
3016 }
3017
3018
3020 {
3022 return false;
3023 }
3024
3025
3026 return true;
3027 }
3028
3030 {
3031 super.AfterStoreLoad();
3032
3034 {
3036 }
3037 }
3038
3040 {
3041
3043
3044
3047
3048
3050 }
3051
3053 {
3054 super.OnCreatePhysics();
3057 }
3058
3060 {
3062 return;
3063
3064 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
3065
3067 return;
3068
3070 string part_name = zone;
3072
3074 {
3075 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
3076
3077 if ( construction_part && construction.IsPartConstructed( part_name ) )
3078 {
3080 construction.DestroyConnectedParts(part_name);
3081 }
3082
3083
3084 if ( part_name.
Contains(
"barbed") )
3085 {
3086 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
3087 if (barbed_wire)
3088 barbed_wire.SetMountedState( false );
3089 }
3090 }
3091 }
3092
3094 {
3096 {
3098 }
3099
3100 super.EEOnAfterLoad();
3101 }
3102
3104 {
3105 super.EEInit();
3106
3107
3109
3110
3111 #ifdef DEVELOPER
3113 #endif
3114 }
3115
3117 {
3118 super.EEItemAttached( item, slot_name );
3119
3123 }
3124
3126 {
3127 super.EEItemDetached( item, slot_name );
3128
3131 }
3132
3133 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
3134 {
3137
3140 }
3141
3142
3144 {
3145 return true;
3146 }
3147
3148
3149
3151 {
3153
3154
3155 if (construtionPart.
IsBase())
3156 {
3158
3159
3161 }
3162
3163
3165
3166
3168
3169
3171
3173
3175
3176
3178
3179
3181 }
3182
3184 {
3185
3187 }
3188
3189
3191 {
3194
3195
3197
3198
3200
3201
3203
3204
3206
3208
3209
3211
3212
3214
3215
3216 if (construtionPart.
IsBase())
3217 {
3218
3220 }
3221 }
3222
3224 {
3225
3227 }
3228
3229
3230 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3231 {
3234
3235
3237
3238
3240
3241
3243
3244
3246
3248
3249
3251
3252
3254
3255
3256 if (construtionPart.
IsBase())
3257 {
3258
3260 }
3261 }
3262
3264 {
3265
3267 }
3268
3271 {
3272 bool process = false;
3273
3274
3278
3279 if (process)
3280 {
3281 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3282 {
3284 return;
3285 }
3286
3288 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3289 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3290
3291
3293 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3294 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3295 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3296 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3297 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3298 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3299 mins = minTmp;
3300 maxs = maxTmp;
3301
3302 maxs[1] = maxs[1] + 0.35;
3303
3305 }
3306 }
3307
3310 {
3313
3314
3316 foreach (
EntityAI entity : foundEntities)
3317 {
3320 }
3321 }
3322
3323
3325 {
3327
3331 }
3332
3334 {
3336
3338 {
3340 }
3341 else
3342 {
3344 }
3345
3347 }
3348
3350 {
3352
3354 foreach (
string slotName : attachmentSlots)
3355 {
3357 }
3358
3359
3362 else
3364
3366 }
3367
3369 {
3370 string slotNameMounted = slot_name + "_Mounted";
3371 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3372
3373 if (attachment)
3374 {
3375 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3376 if (barbedWire && barbedWire.IsMounted())
3378 else
3380
3381 if (is_locked)
3382 {
3383 SetAnimationPhase(slotNameMounted, 0);
3384 SetAnimationPhase(slot_name, 1);
3385 }
3386 else
3387 {
3388 SetAnimationPhase(slotNameMounted, 1);
3389 SetAnimationPhase(slot_name, 0);
3390 }
3391 }
3392 else
3393 {
3394 SetAnimationPhase(slotNameMounted, 1);
3395 SetAnimationPhase(slot_name, 1);
3396
3398 }
3399 }
3400
3401
3403 {
3406
3409
3412
3413 foreach (
string slotName : attachmentSlots)
3414 {
3416 }
3417
3418
3420 {
3423
3425 }
3426 else
3427 {
3430
3432 }
3433
3436 }
3437
3439 {
3440
3442 return;
3443
3444 string slot_name_mounted = slot_name + "_Mounted";
3445 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3446
3447
3449 RemoveProxyPhysics( slot_name_mounted );
3450 RemoveProxyPhysics( slot_name );
3451
3452 if ( attachment )
3453 {
3455 if ( is_locked )
3456 {
3458 AddProxyPhysics( slot_name_mounted );
3459 }
3460 else
3461 {
3463 AddProxyPhysics( slot_name );
3464 }
3465 }
3466 }
3467
3469 {
3470 SetAffectPathgraph( true, false );
3472 }
3473
3475 {
3476 return true;
3477 }
3478
3480 {
3481 return true;
3482 }
3483
3485 {
3486 if ( attachment )
3487 {
3489 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3490
3491 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3492 }
3493
3494 return false;
3495 }
3496
3498 {
3500 }
3501
3502
3504 {
3505 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3506 if (
GetGame().ConfigIsExisting( config_path ) )
3507 {
3509 }
3510 }
3511
3513 {
3514 return true;
3515 }
3516
3518 {
3519 return true;
3520 }
3521
3523 {
3524 return true;
3525 }
3526
3527
3529 {
3531 {
3533 }
3534
3536 }
3537
3539 {
3541 }
3542
3543
3544
3546 {
3547 return super.CanReceiveAttachment(attachment, slotId);
3548 }
3549
3551 {
3552 int attachment_count = GetInventory().AttachmentCount();
3553 if ( attachment_count > 0 )
3554 {
3555 if (
HasBase() && attachment_count == 1 )
3556 {
3557 return false;
3558 }
3559
3560 return true;
3561 }
3562
3563 return false;
3564 }
3565
3567 {
3568 return true;
3569 }
3570
3572 {
3573 return false;
3574 }
3575
3576
3578 {
3579 return false;
3580 }
3581
3583 {
3584 return false;
3585 }
3586
3587
3589 {
3590 return false;
3591 }
3592
3593
3594
3596 {
3597 return true;
3598 }
3599
3601 {
3602 return true;
3603 }
3604
3607 {
3608 return false;
3609 }
3610
3611
3613 {
3614 return true;
3615 }
3616
3617
3619 {
3620 return false;
3621 }
3622
3623
3625 {
3626 return true;
3627 }
3628
3629
3631 {
3632 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3633 {
3634 return false;
3635 }
3636
3637 return true;
3638 }
3639
3641 {
3644
3645 return item;
3646 }
3647
3648
3650 {
3652 {
3653
3655
3656
3659
3661 if ( MemoryPointExists( slot_name + "_min" ) )
3662 {
3663 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3664 }
3665 if ( MemoryPointExists( slot_name + "_max" ) )
3666 {
3667 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3668 }
3669
3670
3673
3674
3677 center = ModelToWorld( center );
3678
3679
3682
3683 areaDamage.SetExtents( extents[0], extents[1] );
3684 areaDamage.SetAreaPosition( center );
3685 areaDamage.SetAreaOrientation( orientation );
3688 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3689 areaDamage.SetAmmoName( "BarbedWireHit" );
3690 areaDamage.Spawn();
3691
3693 }
3694 }
3695
3697 {
3698 if ( angle_deg != 0 )
3699 {
3700
3701 orientation[0] = orientation[0] - angle_deg;
3702
3703
3705 if ( MemoryPointExists( "rotate_axis" ) )
3706 {
3707 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3708 }
3709 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];
3710 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];
3711 center[0] = r_center_x;
3712 center[2] = r_center_z;
3713 }
3714 }
3715
3717 {
3719 {
3722 {
3723 if (areaDamage)
3724 {
3725 areaDamage.Destroy();
3726 }
3727
3729 }
3730 }
3731 }
3732
3734 {
3735 return true;
3736 }
3737
3738
3739
3740
3742 {
3744 }
3745
3747 {
3749 }
3750
3752 {
3754 }
3755
3757 {
3759
3760 switch ( material_type )
3761 {
3767 }
3768
3769 return "";
3770 }
3771
3773 {
3775
3776 switch ( material_type )
3777 {
3783 }
3784
3785 return "";
3786 }
3787
3788
3790 {
3792 {
3793
3795 {
3796 SetHealth(slot_name,"Health",item.GetHealth());
3797 }
3798 }
3799 }
3800
3802 {
3803 return 111;
3804 }
3805
3807 {
3808 super.SetActions();
3809
3813 }
3814
3815
3816
3817
3819 {
3820 }
3821
3824 {
3825 return null;
3826 }
3827
3829 {
3831 }
3832
3834 {
3837
3838 Man p;
3839
3840 #ifdef SERVER
3843 if (players.Count())
3844 p = players[0];
3845 #else
3847 #endif
3848
3850 {
3851 bool excluded = false;
3853 if (excludes)
3854 {
3855 foreach (string exclude : excludes)
3856 {
3858 {
3859 excluded = true;
3860 break;
3861 }
3862 }
3863 }
3864
3865 if (!excluded)
3866 {
3868 }
3869 }
3870
3872 }
3873}
3874
3876{
3877#ifdef BSB_DEBUG
3879#else
3880
3881#endif
3882}
3884{
3885#ifdef BSB_DEBUG_SPAM
3887#else
3888
3889#endif
3890}
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.