2549{
2551
2553
2555
2557
2563
2564
2565
2571
2577
2579
2583
2584
2586 {
2588
2589
2590 RegisterNetSyncVariableInt( "m_SyncParts01" );
2591 RegisterNetSyncVariableInt( "m_SyncParts02" );
2592 RegisterNetSyncVariableInt( "m_SyncParts03" );
2593 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2594 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2595 RegisterNetSyncVariableBool( "m_HasBase" );
2596
2597
2599
2600 if (ConfigIsExisting("hybridAttachments"))
2601 {
2604 }
2605 if (ConfigIsExisting("mountables"))
2606 {
2609 }
2610
2612 }
2613
2615 {
2616 super.EEDelete(parent);
2617
2619 {
2620 areaDamage.Destroy();
2621 }
2622
2623 }
2624
2626 {
2627 return "disableBaseDamage";
2628 }
2629
2631 {
2632 return true;
2633 }
2634
2636 {
2637 return EInventoryIconVisibility.HIDE_VICINITY;
2638 }
2639
2641 {
2642 super.InitItemSounds();
2643
2647
2652 }
2653
2655 {
2656 return "putDown_FenceKit_SoundSet";
2657 }
2658
2660 {
2661 return "Shelter_Site_Build_Loop_SoundSet";
2662 }
2663
2664
2666 {
2668 {
2669 SetSynchDirty();
2670 }
2671 }
2672
2674 {
2676 super.OnVariablesSynchronized();
2677
2679 }
2680
2682 {
2683
2685
2686
2688
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 else if ( part_id >= 32 && part_id <= 62 )
2737 {
2738 offset = ( part_id % 32 );
2739 mask = 1 << offset;
2740
2742 }
2743 else if ( part_id >= 63 && part_id <= 93 )
2744 {
2745 offset = ( part_id % 63 );
2746 mask = 1 << offset;
2747
2749 }
2750 }
2751
2753 {
2754
2755 int offset;
2756 int mask;
2757
2758 if ( part_id >= 1 && part_id <= 31 )
2759 {
2760 offset = part_id - 1;
2761 mask = 1 << offset;
2762
2764 {
2765 return true;
2766 }
2767 }
2768 else if ( part_id >= 32 && part_id <= 62 )
2769 {
2770 offset = ( part_id % 32 );
2771 mask = 1 << offset;
2772
2774 {
2775 return true;
2776 }
2777 }
2778 else if ( part_id >= 63 && part_id <= 93 )
2779 {
2780 offset = ( part_id % 63 );
2781 mask = 1 << offset;
2782
2784 {
2785 return true;
2786 }
2787 }
2788
2789 return false;
2790 }
2791
2793 {
2796 }
2797
2799 {
2800
2803 }
2804
2806 {
2808 {
2811
2812 switch( build_action_id )
2813 {
2817 }
2818 }
2819 }
2820
2821
2823 {
2825 bool is_base = part.
IsBase();
2828 if ( is_part_built_sync )
2829 {
2831 {
2835
2836 if (is_base)
2837 {
2840 }
2841 }
2842 }
2843 else
2844 {
2846 {
2850
2851 if (is_base)
2852 {
2855 }
2856 }
2857 }
2858
2859
2861 }
2862
2863
2865 {
2868
2869 for ( int i = 0; i < construction_parts.Count(); ++i )
2870 {
2871 string key = construction_parts.GetKey( i );
2874 }
2875
2876
2878 }
2879
2881 {
2884
2885 for ( int i = 0; i < construction_parts.Count(); ++i )
2886 {
2887 string key = construction_parts.GetKey( i );
2889
2890 if ( value.
GetId() ==
id )
2891 {
2892 return value;
2893 }
2894 }
2895
2896 return NULL;
2897 }
2898
2899
2900
2902 {
2904 }
2905
2907 {
2909 }
2910
2912 {
2913 return true;
2914 }
2915
2917 {
2918 return false;
2919 }
2920
2921
2923 {
2926 {
2928 }
2929
2930 return construction_kit;
2931 }
2932
2934 {
2937 {
2939 }
2940 }
2941
2943 {
2945 }
2946
2948 {
2949 return "";
2950 }
2951
2953 {
2956 }
2957
2958
2960 {
2963 }
2964
2965
2967 {
2968 super.OnStoreSave( ctx );
2969
2970
2974
2976 }
2977
2979 {
2980 if ( !super.OnStoreLoad( ctx, version ) )
2981 return false;
2982
2983
2984
2986 {
2988 return false;
2989 }
2991 {
2993 return false;
2994 }
2996 {
2998 return false;
2999 }
3000
3001
3003 {
3005 return false;
3006 }
3007
3008
3009 return true;
3010 }
3011
3013 {
3014 super.AfterStoreLoad();
3015
3017 {
3019 }
3020 }
3021
3023 {
3024
3026
3027
3030
3031
3033 }
3034
3036 {
3037 super.OnCreatePhysics();
3040 }
3041
3043 {
3045 return;
3046
3047 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
3048
3050 return;
3051
3053 string part_name = zone;
3055
3057 {
3058 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
3059
3060 if ( construction_part && construction.IsPartConstructed( part_name ) )
3061 {
3063 construction.DestroyConnectedParts(part_name);
3064 }
3065
3066
3067 if ( part_name.
Contains(
"barbed") )
3068 {
3069 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
3070 if (barbed_wire)
3071 barbed_wire.SetMountedState( false );
3072 }
3073 }
3074 }
3075
3077 {
3079 {
3081 }
3082
3083 super.EEOnAfterLoad();
3084 }
3085
3087 {
3088 super.EEInit();
3089
3090
3092
3093
3094 #ifdef DEVELOPER
3096 #endif
3097 }
3098
3100 {
3101 super.EEItemAttached( item, slot_name );
3102
3106 }
3107
3109 {
3110 super.EEItemDetached( item, slot_name );
3111
3114 }
3115
3116 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
3117 {
3120
3123 }
3124
3125
3127 {
3128 return true;
3129 }
3130
3131
3132
3134 {
3136
3137
3138 if (construtionPart.
IsBase())
3139 {
3141
3142
3144 }
3145
3146
3148
3149
3151
3152
3154
3156
3158
3159
3161
3162
3164 }
3165
3167 {
3168
3170 }
3171
3172
3174 {
3177
3178
3180
3181
3183
3184
3186
3187
3189
3191
3192
3194
3195
3197
3198
3199 if (construtionPart.
IsBase())
3200 {
3201
3203 }
3204 }
3205
3207 {
3208
3210 }
3211
3212
3213 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3214 {
3217
3218
3220
3221
3223
3224
3226
3227
3229
3231
3232
3234
3235
3237
3238
3239 if (construtionPart.
IsBase())
3240 {
3241
3243 }
3244 }
3245
3247 {
3248
3250 }
3251
3254 {
3255 bool process = false;
3256
3257
3261
3262 if (process)
3263 {
3264 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3265 {
3267 return;
3268 }
3269
3271 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3272 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3273
3274
3276 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3277 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3278 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3279 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3280 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3281 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3282 mins = minTmp;
3283 maxs = maxTmp;
3284
3285 maxs[1] = maxs[1] + 0.35;
3286
3288 }
3289 }
3290
3293 {
3296
3297
3299 foreach (
EntityAI entity : foundEntities)
3300 {
3303 }
3304 }
3305
3306
3308 {
3310
3314 }
3315
3317 {
3319
3321 {
3323 }
3324 else
3325 {
3327 }
3328
3330 }
3331
3333 {
3335
3337 foreach (
string slotName : attachmentSlots)
3338 {
3340 }
3341
3342
3345 else
3347
3349 }
3350
3352 {
3353 string slotNameMounted = slot_name + "_Mounted";
3354 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3355
3356 if (attachment)
3357 {
3358 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3359 if (barbedWire && barbedWire.IsMounted())
3361 else
3363
3364 if (is_locked)
3365 {
3366 SetAnimationPhase(slotNameMounted, 0);
3367 SetAnimationPhase(slot_name, 1);
3368 }
3369 else
3370 {
3371 SetAnimationPhase(slotNameMounted, 1);
3372 SetAnimationPhase(slot_name, 0);
3373 }
3374 }
3375 else
3376 {
3377 SetAnimationPhase(slotNameMounted, 1);
3378 SetAnimationPhase(slot_name, 1);
3379
3381 }
3382 }
3383
3384
3386 {
3389
3392
3395
3396 foreach (
string slotName : attachmentSlots)
3397 {
3399 }
3400
3401
3403 {
3406
3408 }
3409 else
3410 {
3413
3415 }
3416
3419 }
3420
3422 {
3423
3425 return;
3426
3427 string slot_name_mounted = slot_name + "_Mounted";
3428 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3429
3430
3432 RemoveProxyPhysics( slot_name_mounted );
3433 RemoveProxyPhysics( slot_name );
3434
3435 if ( attachment )
3436 {
3438 if ( is_locked )
3439 {
3441 AddProxyPhysics( slot_name_mounted );
3442 }
3443 else
3444 {
3446 AddProxyPhysics( slot_name );
3447 }
3448 }
3449 }
3450
3452 {
3453 SetAffectPathgraph( true, false );
3455 }
3456
3458 {
3459 return true;
3460 }
3461
3463 {
3464 return true;
3465 }
3466
3468 {
3469 if ( attachment )
3470 {
3472 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3473
3474 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3475 }
3476
3477 return false;
3478 }
3479
3481 {
3483 }
3484
3485
3487 {
3488 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3489 if (
GetGame().ConfigIsExisting( config_path ) )
3490 {
3492 }
3493 }
3494
3496 {
3497 return true;
3498 }
3499
3501 {
3502 return true;
3503 }
3504
3506 {
3507 return true;
3508 }
3509
3510
3512 {
3514 {
3516 }
3517
3519 }
3520
3522 {
3524 }
3525
3526
3527
3529 {
3530 return super.CanReceiveAttachment(attachment, slotId);
3531 }
3532
3534 {
3535 int attachment_count = GetInventory().AttachmentCount();
3536 if ( attachment_count > 0 )
3537 {
3538 if (
HasBase() && attachment_count == 1 )
3539 {
3540 return false;
3541 }
3542
3543 return true;
3544 }
3545
3546 return false;
3547 }
3548
3550 {
3551 return true;
3552 }
3553
3555 {
3556 return false;
3557 }
3558
3559
3561 {
3562 return false;
3563 }
3564
3566 {
3567 return false;
3568 }
3569
3570
3572 {
3573 return false;
3574 }
3575
3576
3577
3579 {
3580 return true;
3581 }
3582
3584 {
3585 return true;
3586 }
3587
3590 {
3591 return false;
3592 }
3593
3594
3596 {
3597 return true;
3598 }
3599
3600
3602 {
3603 return false;
3604 }
3605
3606
3608 {
3609 return true;
3610 }
3611
3612
3614 {
3615 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3616 {
3617 return false;
3618 }
3619
3620 return true;
3621 }
3622
3624 {
3627
3628 return item;
3629 }
3630
3631
3633 {
3635 {
3636
3638
3639
3642
3644 if ( MemoryPointExists( slot_name + "_min" ) )
3645 {
3646 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3647 }
3648 if ( MemoryPointExists( slot_name + "_max" ) )
3649 {
3650 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3651 }
3652
3653
3656
3657
3660 center = ModelToWorld( center );
3661
3662
3665
3666 areaDamage.SetExtents( extents[0], extents[1] );
3667 areaDamage.SetAreaPosition( center );
3668 areaDamage.SetAreaOrientation( orientation );
3671 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3672 areaDamage.SetAmmoName( "BarbedWireHit" );
3673 areaDamage.Spawn();
3674
3676 }
3677 }
3678
3680 {
3681 if ( angle_deg != 0 )
3682 {
3683
3684 orientation[0] = orientation[0] - angle_deg;
3685
3686
3688 if ( MemoryPointExists( "rotate_axis" ) )
3689 {
3690 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3691 }
3692 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];
3693 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];
3694 center[0] = r_center_x;
3695 center[2] = r_center_z;
3696 }
3697 }
3698
3700 {
3702 {
3705 {
3706 if (areaDamage)
3707 {
3708 areaDamage.Destroy();
3709 }
3710
3712 }
3713 }
3714 }
3715
3717 {
3718 return true;
3719 }
3720
3721
3722
3723
3725 {
3727 }
3728
3730 {
3732 }
3733
3735 {
3737 }
3738
3740 {
3742
3743 switch ( material_type )
3744 {
3750 }
3751
3752 return "";
3753 }
3754
3756 {
3758
3759 switch ( material_type )
3760 {
3766 }
3767
3768 return "";
3769 }
3770
3771
3773 {
3775 {
3776
3778 {
3779 SetHealth(slot_name,"Health",item.GetHealth());
3780 }
3781 }
3782 }
3783
3785 {
3786 return 111;
3787 }
3788
3790 {
3791 super.SetActions();
3792
3796 }
3797
3798
3799
3800
3802 {
3803 }
3804
3807 {
3808 return null;
3809 }
3810
3812 {
3814 }
3815
3817 {
3820
3821 Man p;
3822
3823 #ifdef SERVER
3826 if (players.Count())
3827 p = players[0];
3828 #else
3830 #endif
3831
3833 {
3834 bool excluded = false;
3836 if (excludes)
3837 {
3838 foreach (string exclude : excludes)
3839 {
3841 {
3842 excluded = true;
3843 break;
3844 }
3845 }
3846 }
3847
3848 if (!excluded)
3849 {
3851 }
3852 }
3853
3855 }
3856}
3857
3859{
3860#ifdef BSB_DEBUG
3862#else
3863
3864#endif
3865}
3867{
3868#ifdef BSB_DEBUG_SPAM
3870#else
3871
3872#endif
3873}
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.