2464{
2466
2468
2470
2472
2478
2479
2480
2486
2492
2494
2498
2499
2501 {
2503
2504
2505 RegisterNetSyncVariableInt( "m_SyncParts01" );
2506 RegisterNetSyncVariableInt( "m_SyncParts02" );
2507 RegisterNetSyncVariableInt( "m_SyncParts03" );
2508 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2509 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2510 RegisterNetSyncVariableBool( "m_HasBase" );
2511
2512
2514
2515 if (ConfigIsExisting("hybridAttachments"))
2516 {
2519 }
2520 if (ConfigIsExisting("mountables"))
2521 {
2524 }
2525
2527 }
2528
2530 {
2531 super.EEDelete(parent);
2532
2534 {
2535 areaDamage.Destroy();
2536 }
2537
2538 }
2539
2541 {
2542 return "disableBaseDamage";
2543 }
2544
2546 {
2547 return true;
2548 }
2549
2551 {
2552 return EInventoryIconVisibility.HIDE_VICINITY;
2553 }
2554
2556 {
2557 super.InitItemSounds();
2558
2562
2567 }
2568
2570 {
2571 return "putDown_FenceKit_SoundSet";
2572 }
2573
2575 {
2576 return "Shelter_Site_Build_Loop_SoundSet";
2577 }
2578
2579
2581 {
2583 {
2584 SetSynchDirty();
2585 }
2586 }
2587
2589 {
2591 super.OnVariablesSynchronized();
2592
2594 }
2595
2597 {
2598
2600
2601
2603
2604
2606 }
2607
2608
2610 {
2611
2612 int offset;
2613 int mask;
2614
2615 if ( part_id >= 1 && part_id <= 31 )
2616 {
2617 offset = part_id - 1;
2618 mask = 1 << offset;
2619
2621 }
2622 else if ( part_id >= 32 && part_id <= 62 )
2623 {
2624 offset = ( part_id % 32 );
2625 mask = 1 << offset;
2626
2628 }
2629 else if ( part_id >= 63 && part_id <= 93 )
2630 {
2631 offset = ( part_id % 63 );
2632 mask = 1 << offset;
2633
2635 }
2636 }
2637
2639 {
2640
2641 int offset;
2642 int mask;
2643
2644 if ( part_id >= 1 && part_id <= 31 )
2645 {
2646 offset = part_id - 1;
2647 mask = 1 << offset;
2648
2650 }
2651 else if ( part_id >= 32 && part_id <= 62 )
2652 {
2653 offset = ( part_id % 32 );
2654 mask = 1 << offset;
2655
2657 }
2658 else if ( part_id >= 63 && part_id <= 93 )
2659 {
2660 offset = ( part_id % 63 );
2661 mask = 1 << offset;
2662
2664 }
2665 }
2666
2668 {
2669
2670 int offset;
2671 int mask;
2672
2673 if ( part_id >= 1 && part_id <= 31 )
2674 {
2675 offset = part_id - 1;
2676 mask = 1 << offset;
2677
2679 {
2680 return true;
2681 }
2682 }
2683 else if ( part_id >= 32 && part_id <= 62 )
2684 {
2685 offset = ( part_id % 32 );
2686 mask = 1 << offset;
2687
2689 {
2690 return true;
2691 }
2692 }
2693 else if ( part_id >= 63 && part_id <= 93 )
2694 {
2695 offset = ( part_id % 63 );
2696 mask = 1 << offset;
2697
2699 {
2700 return true;
2701 }
2702 }
2703
2704 return false;
2705 }
2706
2708 {
2711 }
2712
2714 {
2715
2718 }
2719
2721 {
2723 {
2726
2727 switch( build_action_id )
2728 {
2732 }
2733 }
2734 }
2735
2736
2738 {
2740 bool is_base = part.
IsBase();
2743 if ( is_part_built_sync )
2744 {
2746 {
2750
2751 if (is_base)
2752 {
2755 }
2756 }
2757 }
2758 else
2759 {
2761 {
2765
2766 if (is_base)
2767 {
2770 }
2771 }
2772 }
2773
2774
2776 }
2777
2778
2780 {
2783
2784 for ( int i = 0; i < construction_parts.Count(); ++i )
2785 {
2786 string key = construction_parts.GetKey( i );
2789 }
2790
2791
2793 }
2794
2796 {
2799
2800 for ( int i = 0; i < construction_parts.Count(); ++i )
2801 {
2802 string key = construction_parts.GetKey( i );
2804
2805 if ( value.
GetId() ==
id )
2806 {
2807 return value;
2808 }
2809 }
2810
2811 return NULL;
2812 }
2813
2814
2815
2817 {
2819 }
2820
2822 {
2824 }
2825
2827 {
2828 return true;
2829 }
2830
2832 {
2833 return false;
2834 }
2835
2836
2838 {
2841 {
2843 }
2844
2845 return construction_kit;
2846 }
2847
2849 {
2852 {
2854 }
2855 }
2856
2858 {
2860 }
2861
2863 {
2864 return "";
2865 }
2866
2868 {
2871 }
2872
2873
2875 {
2878 }
2879
2880
2882 {
2883 super.OnStoreSave( ctx );
2884
2885
2889
2891 }
2892
2894 {
2895 if ( !super.OnStoreLoad( ctx, version ) )
2896 return false;
2897
2898
2899
2901 {
2903 return false;
2904 }
2906 {
2908 return false;
2909 }
2911 {
2913 return false;
2914 }
2915
2916
2918 {
2920 return false;
2921 }
2922
2923
2924 return true;
2925 }
2926
2928 {
2929 super.AfterStoreLoad();
2930
2932 {
2934 }
2935 }
2936
2938 {
2939
2941
2942
2945
2946
2948 }
2949
2951 {
2952 super.OnCreatePhysics();
2955 }
2956
2958 {
2960 return;
2961
2962 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2963
2965 return;
2966
2968 string part_name = zone;
2970
2972 {
2973 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2974
2975 if ( construction_part && construction.IsPartConstructed( part_name ) )
2976 {
2978 construction.DestroyConnectedParts(part_name);
2979 }
2980
2981
2982 if ( part_name.
Contains(
"barbed") )
2983 {
2984 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2985 if (barbed_wire)
2986 barbed_wire.SetMountedState( false );
2987 }
2988 }
2989 }
2990
2992 {
2994 {
2996 }
2997
2998 super.EEOnAfterLoad();
2999 }
3000
3002 {
3003 super.EEInit();
3004
3005
3007
3008
3009 #ifdef DEVELOPER
3011 #endif
3012 }
3013
3015 {
3016 super.EEItemAttached( item, slot_name );
3017
3021 }
3022
3024 {
3025 super.EEItemDetached( item, slot_name );
3026
3029 }
3030
3031 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
3032 {
3035
3038 }
3039
3040
3042 {
3043 return true;
3044 }
3045
3046
3047
3049 {
3051
3052
3053 if (construtionPart.
IsBase())
3054 {
3056
3057
3059 }
3060
3061
3063
3064
3066
3067
3069
3071
3073
3074
3076
3077
3079 }
3080
3082 {
3083
3085 }
3086
3087
3089 {
3092
3093
3095
3096
3098
3099
3101
3102
3104
3106
3107
3109
3110
3112
3113
3114 if (construtionPart.
IsBase())
3115 {
3116
3118 }
3119 }
3120
3122 {
3123
3125 }
3126
3127
3128 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3129 {
3132
3133
3135
3136
3138
3139
3141
3142
3144
3146
3147
3149
3150
3152
3153
3154 if (construtionPart.
IsBase())
3155 {
3156
3158 }
3159 }
3160
3162 {
3163
3165 }
3166
3169 {
3170 bool process = false;
3171
3172
3176
3177 if (process)
3178 {
3179 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3180 {
3182 return;
3183 }
3184
3186 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3187 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3188
3189
3191 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3192 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3193 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3194 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3195 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3196 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3197 mins = minTmp;
3198 maxs = maxTmp;
3199
3200 maxs[1] = maxs[1] + 0.35;
3201
3203 }
3204 }
3205
3208 {
3211
3212
3214 foreach (
EntityAI entity : foundEntities)
3215 {
3218 }
3219 }
3220
3221
3223 {
3225
3229 }
3230
3232 {
3234
3236 {
3238 }
3239 else
3240 {
3242 }
3243
3245 }
3246
3248 {
3250
3252 foreach (
string slotName : attachmentSlots)
3253 {
3255 }
3256
3257
3260 else
3262
3264 }
3265
3267 {
3268 string slotNameMounted = slot_name + "_Mounted";
3269 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3270
3271 if (attachment)
3272 {
3273 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3274 if (barbedWire && barbedWire.IsMounted())
3276 else
3278
3279 if (is_locked)
3280 {
3281 SetAnimationPhase(slotNameMounted, 0);
3282 SetAnimationPhase(slot_name, 1);
3283 }
3284 else
3285 {
3286 SetAnimationPhase(slotNameMounted, 1);
3287 SetAnimationPhase(slot_name, 0);
3288 }
3289 }
3290 else
3291 {
3292 SetAnimationPhase(slotNameMounted, 1);
3293 SetAnimationPhase(slot_name, 1);
3294
3296 }
3297 }
3298
3299
3301 {
3304
3307
3310
3311 foreach (
string slotName : attachmentSlots)
3312 {
3314 }
3315
3316
3318 {
3321
3323 }
3324 else
3325 {
3328
3330 }
3331
3334 }
3335
3337 {
3338
3340 return;
3341
3342 string slot_name_mounted = slot_name + "_Mounted";
3343 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3344
3345
3347 RemoveProxyPhysics( slot_name_mounted );
3348 RemoveProxyPhysics( slot_name );
3349
3350 if ( attachment )
3351 {
3353 if ( is_locked )
3354 {
3356 AddProxyPhysics( slot_name_mounted );
3357 }
3358 else
3359 {
3361 AddProxyPhysics( slot_name );
3362 }
3363 }
3364 }
3365
3367 {
3368 SetAffectPathgraph( true, false );
3370 }
3371
3373 {
3374 return true;
3375 }
3376
3378 {
3379 return true;
3380 }
3381
3383 {
3384 if ( attachment )
3385 {
3387 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3388
3389 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3390 }
3391
3392 return false;
3393 }
3394
3396 {
3398 }
3399
3400
3402 {
3403 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3404 if (
GetGame().ConfigIsExisting( config_path ) )
3405 {
3407 }
3408 }
3409
3411 {
3412 return true;
3413 }
3414
3416 {
3417 return true;
3418 }
3419
3421 {
3422 return true;
3423 }
3424
3425
3427 {
3429 {
3431 }
3432
3434 }
3435
3437 {
3439 }
3440
3441
3442
3444 {
3445 return super.CanReceiveAttachment(attachment, slotId);
3446 }
3447
3449 {
3450 int attachment_count = GetInventory().AttachmentCount();
3451 if ( attachment_count > 0 )
3452 {
3453 if (
HasBase() && attachment_count == 1 )
3454 {
3455 return false;
3456 }
3457
3458 return true;
3459 }
3460
3461 return false;
3462 }
3463
3465 {
3466 return true;
3467 }
3468
3470 {
3471 return false;
3472 }
3473
3474
3476 {
3477 return false;
3478 }
3479
3481 {
3482 return false;
3483 }
3484
3485
3487 {
3488 return false;
3489 }
3490
3491
3492
3494 {
3495 return true;
3496 }
3497
3499 {
3500 return true;
3501 }
3502
3505 {
3506 return false;
3507 }
3508
3509
3511 {
3512 return true;
3513 }
3514
3515
3517 {
3518 return false;
3519 }
3520
3521
3523 {
3524 return true;
3525 }
3526
3527
3529 {
3530 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3531 {
3532 return false;
3533 }
3534
3535 return true;
3536 }
3537
3539 {
3542
3543 return item;
3544 }
3545
3546
3548 {
3550 {
3551
3553
3554
3557
3559 if ( MemoryPointExists( slot_name + "_min" ) )
3560 {
3561 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3562 }
3563 if ( MemoryPointExists( slot_name + "_max" ) )
3564 {
3565 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3566 }
3567
3568
3571
3572
3575 center = ModelToWorld( center );
3576
3577
3580
3581 areaDamage.SetExtents( extents[0], extents[1] );
3582 areaDamage.SetAreaPosition( center );
3583 areaDamage.SetAreaOrientation( orientation );
3586 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3587 areaDamage.SetAmmoName( "BarbedWireHit" );
3588 areaDamage.Spawn();
3589
3591 }
3592 }
3593
3595 {
3596 if ( angle_deg != 0 )
3597 {
3598
3599 orientation[0] = orientation[0] - angle_deg;
3600
3601
3603 if ( MemoryPointExists( "rotate_axis" ) )
3604 {
3605 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3606 }
3607 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];
3608 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];
3609 center[0] = r_center_x;
3610 center[2] = r_center_z;
3611 }
3612 }
3613
3615 {
3617 {
3620 {
3621 if (areaDamage)
3622 {
3623 areaDamage.Destroy();
3624 }
3625
3627 }
3628 }
3629 }
3630
3632 {
3633 return true;
3634 }
3635
3636
3637
3638
3640 {
3642 }
3643
3645 {
3647 }
3648
3650 {
3652 }
3653
3655 {
3657
3658 switch ( material_type )
3659 {
3665 }
3666
3667 return "";
3668 }
3669
3671 {
3673
3674 switch ( material_type )
3675 {
3681 }
3682
3683 return "";
3684 }
3685
3686
3688 {
3690 {
3691
3693 {
3694 SetHealth(slot_name,"Health",item.GetHealth());
3695 }
3696 }
3697 }
3698
3700 {
3701 return 111;
3702 }
3703
3705 {
3706 super.SetActions();
3707
3711 }
3712
3713
3714
3715
3717 {
3718 }
3719
3722 {
3723 return null;
3724 }
3725
3727 {
3729 }
3730
3732 {
3735
3736 Man p;
3737
3738 #ifdef SERVER
3741 if (players.Count())
3742 p = players[0];
3743 #else
3745 #endif
3746
3748 {
3749 bool excluded = false;
3751 if (excludes)
3752 {
3753 foreach (string exclude : excludes)
3754 {
3756 {
3757 excluded = true;
3758 break;
3759 }
3760 }
3761 }
3762
3763 if (!excluded)
3764 {
3766 }
3767 }
3768
3770 }
3771}
3772
3774{
3775#ifdef BSB_DEBUG
3777#else
3778
3779#endif
3780}
3782{
3783#ifdef BSB_DEBUG_SPAM
3785#else
3786
3787#endif
3788}
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.