2481{
2483
2485
2487
2489
2495
2496
2497
2503
2509
2511
2515
2516
2518 {
2520
2521
2522 RegisterNetSyncVariableInt( "m_SyncParts01" );
2523 RegisterNetSyncVariableInt( "m_SyncParts02" );
2524 RegisterNetSyncVariableInt( "m_SyncParts03" );
2525 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2526 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2527 RegisterNetSyncVariableBool( "m_HasBase" );
2528
2529
2531
2532 if (ConfigIsExisting("hybridAttachments"))
2533 {
2536 }
2537 if (ConfigIsExisting("mountables"))
2538 {
2541 }
2542
2544 }
2545
2547 {
2548 super.EEDelete(parent);
2549
2551 {
2552 areaDamage.Destroy();
2553 }
2554
2555 }
2556
2558 {
2559 return "disableBaseDamage";
2560 }
2561
2563 {
2564 return true;
2565 }
2566
2568 {
2569 return EInventoryIconVisibility.HIDE_VICINITY;
2570 }
2571
2573 {
2574 super.InitItemSounds();
2575
2579
2584 }
2585
2587 {
2588 return "putDown_FenceKit_SoundSet";
2589 }
2590
2592 {
2593 return "Shelter_Site_Build_Loop_SoundSet";
2594 }
2595
2596
2598 {
2600 {
2601 SetSynchDirty();
2602 }
2603 }
2604
2606 {
2608 super.OnVariablesSynchronized();
2609
2611 }
2612
2614 {
2615
2617
2618
2620
2621
2623 }
2624
2625
2627 {
2628
2629 int offset;
2630 int mask;
2631
2632 if ( part_id >= 1 && part_id <= 31 )
2633 {
2634 offset = part_id - 1;
2635 mask = 1 << offset;
2636
2638 }
2639 else if ( part_id >= 32 && part_id <= 62 )
2640 {
2641 offset = ( part_id % 32 );
2642 mask = 1 << offset;
2643
2645 }
2646 else if ( part_id >= 63 && part_id <= 93 )
2647 {
2648 offset = ( part_id % 63 );
2649 mask = 1 << offset;
2650
2652 }
2653 }
2654
2656 {
2657
2658 int offset;
2659 int mask;
2660
2661 if ( part_id >= 1 && part_id <= 31 )
2662 {
2663 offset = part_id - 1;
2664 mask = 1 << offset;
2665
2667 }
2668 else if ( part_id >= 32 && part_id <= 62 )
2669 {
2670 offset = ( part_id % 32 );
2671 mask = 1 << offset;
2672
2674 }
2675 else if ( part_id >= 63 && part_id <= 93 )
2676 {
2677 offset = ( part_id % 63 );
2678 mask = 1 << offset;
2679
2681 }
2682 }
2683
2685 {
2686
2687 int offset;
2688 int mask;
2689
2690 if ( part_id >= 1 && part_id <= 31 )
2691 {
2692 offset = part_id - 1;
2693 mask = 1 << offset;
2694
2696 {
2697 return true;
2698 }
2699 }
2700 else if ( part_id >= 32 && part_id <= 62 )
2701 {
2702 offset = ( part_id % 32 );
2703 mask = 1 << offset;
2704
2706 {
2707 return true;
2708 }
2709 }
2710 else if ( part_id >= 63 && part_id <= 93 )
2711 {
2712 offset = ( part_id % 63 );
2713 mask = 1 << offset;
2714
2716 {
2717 return true;
2718 }
2719 }
2720
2721 return false;
2722 }
2723
2725 {
2728 }
2729
2731 {
2732
2735 }
2736
2738 {
2740 {
2743
2744 switch( build_action_id )
2745 {
2749 }
2750 }
2751 }
2752
2753
2755 {
2757 bool is_base = part.
IsBase();
2760 if ( is_part_built_sync )
2761 {
2763 {
2767
2768 if (is_base)
2769 {
2772 }
2773 }
2774 }
2775 else
2776 {
2778 {
2782
2783 if (is_base)
2784 {
2787 }
2788 }
2789 }
2790
2791
2793 }
2794
2795
2797 {
2800
2801 for ( int i = 0; i < construction_parts.Count(); ++i )
2802 {
2803 string key = construction_parts.GetKey( i );
2806 }
2807
2808
2810 }
2811
2813 {
2816
2817 for ( int i = 0; i < construction_parts.Count(); ++i )
2818 {
2819 string key = construction_parts.GetKey( i );
2821
2822 if ( value.
GetId() ==
id )
2823 {
2824 return value;
2825 }
2826 }
2827
2828 return NULL;
2829 }
2830
2831
2832
2834 {
2836 }
2837
2839 {
2841 }
2842
2844 {
2845 return true;
2846 }
2847
2849 {
2850 return false;
2851 }
2852
2853
2855 {
2858 {
2860 }
2861
2862 return construction_kit;
2863 }
2864
2866 {
2869 {
2871 }
2872 }
2873
2875 {
2877 }
2878
2880 {
2881 return "";
2882 }
2883
2885 {
2888 }
2889
2890
2892 {
2895 }
2896
2897
2899 {
2900 super.OnStoreSave( ctx );
2901
2902
2906
2908 }
2909
2911 {
2912 if ( !super.OnStoreLoad( ctx, version ) )
2913 return false;
2914
2915
2916
2918 {
2920 return false;
2921 }
2923 {
2925 return false;
2926 }
2928 {
2930 return false;
2931 }
2932
2933
2935 {
2937 return false;
2938 }
2939
2940
2941 return true;
2942 }
2943
2945 {
2946 super.AfterStoreLoad();
2947
2949 {
2951 }
2952 }
2953
2955 {
2956
2958
2959
2962
2963
2965 }
2966
2968 {
2969 super.OnCreatePhysics();
2972 }
2973
2975 {
2977 return;
2978
2979 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2980
2982 return;
2983
2985 string part_name = zone;
2987
2989 {
2990 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2991
2992 if ( construction_part && construction.IsPartConstructed( part_name ) )
2993 {
2995 construction.DestroyConnectedParts(part_name);
2996 }
2997
2998
2999 if ( part_name.
Contains(
"barbed") )
3000 {
3001 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
3002 if (barbed_wire)
3003 barbed_wire.SetMountedState( false );
3004 }
3005 }
3006 }
3007
3009 {
3011 {
3013 }
3014
3015 super.EEOnAfterLoad();
3016 }
3017
3019 {
3020 super.EEInit();
3021
3022
3024
3025
3026 #ifdef DEVELOPER
3028 #endif
3029 }
3030
3032 {
3033 super.EEItemAttached( item, slot_name );
3034
3038 }
3039
3041 {
3042 super.EEItemDetached( item, slot_name );
3043
3046 }
3047
3048 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
3049 {
3052
3055 }
3056
3057
3059 {
3060 return true;
3061 }
3062
3063
3064
3066 {
3068
3069
3070 if (construtionPart.
IsBase())
3071 {
3073
3074
3076 }
3077
3078
3080
3081
3083
3084
3086
3088
3090
3091
3093
3094
3096 }
3097
3099 {
3100
3102 }
3103
3104
3106 {
3109
3110
3112
3113
3115
3116
3118
3119
3121
3123
3124
3126
3127
3129
3130
3131 if (construtionPart.
IsBase())
3132 {
3133
3135 }
3136 }
3137
3139 {
3140
3142 }
3143
3144
3145 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3146 {
3149
3150
3152
3153
3155
3156
3158
3159
3161
3163
3164
3166
3167
3169
3170
3171 if (construtionPart.
IsBase())
3172 {
3173
3175 }
3176 }
3177
3179 {
3180
3182 }
3183
3186 {
3187 bool process = false;
3188
3189
3193
3194 if (process)
3195 {
3196 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3197 {
3199 return;
3200 }
3201
3203 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3204 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3205
3206
3208 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3209 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3210 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3211 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3212 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3213 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3214 mins = minTmp;
3215 maxs = maxTmp;
3216
3217 maxs[1] = maxs[1] + 0.35;
3218
3220 }
3221 }
3222
3225 {
3228
3229
3231 foreach (
EntityAI entity : foundEntities)
3232 {
3235 }
3236 }
3237
3238
3240 {
3242
3246 }
3247
3249 {
3251
3253 {
3255 }
3256 else
3257 {
3259 }
3260
3262 }
3263
3265 {
3267
3269 foreach (
string slotName : attachmentSlots)
3270 {
3272 }
3273
3274
3277 else
3279
3281 }
3282
3284 {
3285 string slotNameMounted = slot_name + "_Mounted";
3286 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3287
3288 if (attachment)
3289 {
3290 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3291 if (barbedWire && barbedWire.IsMounted())
3293 else
3295
3296 if (is_locked)
3297 {
3298 SetAnimationPhase(slotNameMounted, 0);
3299 SetAnimationPhase(slot_name, 1);
3300 }
3301 else
3302 {
3303 SetAnimationPhase(slotNameMounted, 1);
3304 SetAnimationPhase(slot_name, 0);
3305 }
3306 }
3307 else
3308 {
3309 SetAnimationPhase(slotNameMounted, 1);
3310 SetAnimationPhase(slot_name, 1);
3311
3313 }
3314 }
3315
3316
3318 {
3321
3324
3327
3328 foreach (
string slotName : attachmentSlots)
3329 {
3331 }
3332
3333
3335 {
3338
3340 }
3341 else
3342 {
3345
3347 }
3348
3351 }
3352
3354 {
3355
3357 return;
3358
3359 string slot_name_mounted = slot_name + "_Mounted";
3360 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3361
3362
3364 RemoveProxyPhysics( slot_name_mounted );
3365 RemoveProxyPhysics( slot_name );
3366
3367 if ( attachment )
3368 {
3370 if ( is_locked )
3371 {
3373 AddProxyPhysics( slot_name_mounted );
3374 }
3375 else
3376 {
3378 AddProxyPhysics( slot_name );
3379 }
3380 }
3381 }
3382
3384 {
3385 SetAffectPathgraph( true, false );
3387 }
3388
3390 {
3391 return true;
3392 }
3393
3395 {
3396 return true;
3397 }
3398
3400 {
3401 if ( attachment )
3402 {
3404 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3405
3406 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3407 }
3408
3409 return false;
3410 }
3411
3413 {
3415 }
3416
3417
3419 {
3420 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3421 if (
GetGame().ConfigIsExisting( config_path ) )
3422 {
3424 }
3425 }
3426
3428 {
3429 return true;
3430 }
3431
3433 {
3434 return true;
3435 }
3436
3438 {
3439 return true;
3440 }
3441
3442
3444 {
3446 {
3448 }
3449
3451 }
3452
3454 {
3456 }
3457
3458
3459
3461 {
3462 return super.CanReceiveAttachment(attachment, slotId);
3463 }
3464
3466 {
3467 int attachment_count = GetInventory().AttachmentCount();
3468 if ( attachment_count > 0 )
3469 {
3470 if (
HasBase() && attachment_count == 1 )
3471 {
3472 return false;
3473 }
3474
3475 return true;
3476 }
3477
3478 return false;
3479 }
3480
3482 {
3483 return true;
3484 }
3485
3487 {
3488 return false;
3489 }
3490
3491
3493 {
3494 return false;
3495 }
3496
3498 {
3499 return false;
3500 }
3501
3502
3504 {
3505 return false;
3506 }
3507
3508
3509
3511 {
3512 return true;
3513 }
3514
3516 {
3517 return true;
3518 }
3519
3522 {
3523 return false;
3524 }
3525
3526
3528 {
3529 return true;
3530 }
3531
3532
3534 {
3535 return false;
3536 }
3537
3538
3540 {
3541 return true;
3542 }
3543
3544
3546 {
3547 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3548 {
3549 return false;
3550 }
3551
3552 return true;
3553 }
3554
3556 {
3559
3560 return item;
3561 }
3562
3563
3565 {
3567 {
3568
3570
3571
3574
3576 if ( MemoryPointExists( slot_name + "_min" ) )
3577 {
3578 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3579 }
3580 if ( MemoryPointExists( slot_name + "_max" ) )
3581 {
3582 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3583 }
3584
3585
3588
3589
3592 center = ModelToWorld( center );
3593
3594
3597
3598 areaDamage.SetExtents( extents[0], extents[1] );
3599 areaDamage.SetAreaPosition( center );
3600 areaDamage.SetAreaOrientation( orientation );
3603 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3604 areaDamage.SetAmmoName( "BarbedWireHit" );
3605 areaDamage.Spawn();
3606
3608 }
3609 }
3610
3612 {
3613 if ( angle_deg != 0 )
3614 {
3615
3616 orientation[0] = orientation[0] - angle_deg;
3617
3618
3620 if ( MemoryPointExists( "rotate_axis" ) )
3621 {
3622 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3623 }
3624 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];
3625 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];
3626 center[0] = r_center_x;
3627 center[2] = r_center_z;
3628 }
3629 }
3630
3632 {
3634 {
3637 {
3638 if (areaDamage)
3639 {
3640 areaDamage.Destroy();
3641 }
3642
3644 }
3645 }
3646 }
3647
3649 {
3650 return true;
3651 }
3652
3653
3654
3655
3657 {
3659 }
3660
3662 {
3664 }
3665
3667 {
3669 }
3670
3672 {
3674
3675 switch ( material_type )
3676 {
3682 }
3683
3684 return "";
3685 }
3686
3688 {
3690
3691 switch ( material_type )
3692 {
3698 }
3699
3700 return "";
3701 }
3702
3703
3705 {
3707 {
3708
3710 {
3711 SetHealth(slot_name,"Health",item.GetHealth());
3712 }
3713 }
3714 }
3715
3717 {
3718 return 111;
3719 }
3720
3722 {
3723 super.SetActions();
3724
3728 }
3729
3730
3731
3732
3734 {
3735 }
3736
3739 {
3740 return null;
3741 }
3742
3744 {
3746 }
3747
3749 {
3752
3753 Man p;
3754
3755 #ifdef SERVER
3758 if (players.Count())
3759 p = players[0];
3760 #else
3762 #endif
3763
3765 {
3766 bool excluded = false;
3768 if (excludes)
3769 {
3770 foreach (string exclude : excludes)
3771 {
3773 {
3774 excluded = true;
3775 break;
3776 }
3777 }
3778 }
3779
3780 if (!excluded)
3781 {
3783 }
3784 }
3785
3787 }
3788}
3789
3791{
3792#ifdef BSB_DEBUG
3794#else
3795
3796#endif
3797}
3799{
3800#ifdef BSB_DEBUG_SPAM
3802#else
3803
3804#endif
3805}
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.