2397{
2399
2401
2403
2405
2411
2412
2413
2419
2425
2427
2431
2432
2434 {
2436
2437
2438 RegisterNetSyncVariableInt( "m_SyncParts01" );
2439 RegisterNetSyncVariableInt( "m_SyncParts02" );
2440 RegisterNetSyncVariableInt( "m_SyncParts03" );
2441 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2442 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2443 RegisterNetSyncVariableBool( "m_HasBase" );
2444
2445
2447
2448 if (ConfigIsExisting("hybridAttachments"))
2449 {
2452 }
2453 if (ConfigIsExisting("mountables"))
2454 {
2457 }
2458
2460 }
2461
2463 {
2464 super.EEDelete(parent);
2465
2467 {
2468 areaDamage.Destroy();
2469 }
2470
2471 }
2472
2474 {
2475 return "disableBaseDamage";
2476 }
2477
2479 {
2480 return true;
2481 }
2482
2484 {
2485 return EInventoryIconVisibility.HIDE_VICINITY;
2486 }
2487
2489 {
2490 super.InitItemSounds();
2491
2495
2500 }
2501
2503 {
2504 return "putDown_FenceKit_SoundSet";
2505 }
2506
2508 {
2509 return "Shelter_Site_Build_Loop_SoundSet";
2510 }
2511
2512
2514 {
2516 {
2517 SetSynchDirty();
2518 }
2519 }
2520
2522 {
2524 super.OnVariablesSynchronized();
2525
2527 }
2528
2530 {
2531
2533
2534
2536
2537
2539 }
2540
2541
2543 {
2544
2545 int offset;
2546 int mask;
2547
2548 if ( part_id >= 1 && part_id <= 31 )
2549 {
2550 offset = part_id - 1;
2551 mask = 1 << offset;
2552
2554 }
2555 else if ( part_id >= 32 && part_id <= 62 )
2556 {
2557 offset = ( part_id % 32 );
2558 mask = 1 << offset;
2559
2561 }
2562 else if ( part_id >= 63 && part_id <= 93 )
2563 {
2564 offset = ( part_id % 63 );
2565 mask = 1 << offset;
2566
2568 }
2569 }
2570
2572 {
2573
2574 int offset;
2575 int mask;
2576
2577 if ( part_id >= 1 && part_id <= 31 )
2578 {
2579 offset = part_id - 1;
2580 mask = 1 << offset;
2581
2583 }
2584 else if ( part_id >= 32 && part_id <= 62 )
2585 {
2586 offset = ( part_id % 32 );
2587 mask = 1 << offset;
2588
2590 }
2591 else if ( part_id >= 63 && part_id <= 93 )
2592 {
2593 offset = ( part_id % 63 );
2594 mask = 1 << offset;
2595
2597 }
2598 }
2599
2601 {
2602
2603 int offset;
2604 int mask;
2605
2606 if ( part_id >= 1 && part_id <= 31 )
2607 {
2608 offset = part_id - 1;
2609 mask = 1 << offset;
2610
2612 {
2613 return true;
2614 }
2615 }
2616 else if ( part_id >= 32 && part_id <= 62 )
2617 {
2618 offset = ( part_id % 32 );
2619 mask = 1 << offset;
2620
2622 {
2623 return true;
2624 }
2625 }
2626 else if ( part_id >= 63 && part_id <= 93 )
2627 {
2628 offset = ( part_id % 63 );
2629 mask = 1 << offset;
2630
2632 {
2633 return true;
2634 }
2635 }
2636
2637 return false;
2638 }
2639
2641 {
2644 }
2645
2647 {
2648
2651 }
2652
2654 {
2656 {
2659
2660 switch( build_action_id )
2661 {
2665 }
2666 }
2667 }
2668
2669
2671 {
2673 bool is_base = part.
IsBase();
2676 if ( is_part_built_sync )
2677 {
2679 {
2683
2684 if (is_base)
2685 {
2688 }
2689 }
2690 }
2691 else
2692 {
2694 {
2698
2699 if (is_base)
2700 {
2703 }
2704 }
2705 }
2706
2707
2709 }
2710
2711
2713 {
2716
2717 for ( int i = 0; i < construction_parts.Count(); ++i )
2718 {
2719 string key = construction_parts.GetKey( i );
2722 }
2723
2724
2726 }
2727
2729 {
2732
2733 for ( int i = 0; i < construction_parts.Count(); ++i )
2734 {
2735 string key = construction_parts.GetKey( i );
2737
2738 if ( value.
GetId() ==
id )
2739 {
2740 return value;
2741 }
2742 }
2743
2744 return NULL;
2745 }
2746
2747
2748
2750 {
2752 }
2753
2755 {
2757 }
2758
2760 {
2761 return true;
2762 }
2763
2765 {
2766 return false;
2767 }
2768
2769
2771 {
2774 {
2776 }
2777
2778 return construction_kit;
2779 }
2780
2782 {
2785 {
2787 }
2788 }
2789
2791 {
2793 }
2794
2796 {
2797 return "";
2798 }
2799
2801 {
2804 }
2805
2806
2808 {
2811 }
2812
2813
2815 {
2816 super.OnStoreSave( ctx );
2817
2818
2822
2824 }
2825
2827 {
2828 if ( !super.OnStoreLoad( ctx, version ) )
2829 return false;
2830
2831
2832
2834 {
2836 return false;
2837 }
2839 {
2841 return false;
2842 }
2844 {
2846 return false;
2847 }
2848
2849
2851 {
2853 return false;
2854 }
2855
2856
2857 return true;
2858 }
2859
2861 {
2862 super.AfterStoreLoad();
2863
2865 {
2867 }
2868 }
2869
2871 {
2872
2874
2875
2878
2879
2881 }
2882
2884 {
2885 super.OnCreatePhysics();
2888 }
2889
2891 {
2893 return;
2894
2895 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2896
2898 return;
2899
2901 string part_name = zone;
2903
2905 {
2906 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2907
2908 if ( construction_part && construction.IsPartConstructed( part_name ) )
2909 {
2911 construction.DestroyConnectedParts(part_name);
2912 }
2913
2914
2915 if ( part_name.
Contains(
"barbed") )
2916 {
2917 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2918 if (barbed_wire)
2919 barbed_wire.SetMountedState( false );
2920 }
2921 }
2922 }
2923
2925 {
2927 {
2929 }
2930
2931 super.EEOnAfterLoad();
2932 }
2933
2935 {
2936 super.EEInit();
2937
2938
2940
2941
2942 #ifdef DEVELOPER
2944 #endif
2945 }
2946
2948 {
2949 super.EEItemAttached( item, slot_name );
2950
2954 }
2955
2957 {
2958 super.EEItemDetached( item, slot_name );
2959
2962 }
2963
2964 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2965 {
2968
2971 }
2972
2973
2975 {
2976 return true;
2977 }
2978
2979
2980
2982 {
2984
2985
2986 if (construtionPart.
IsBase())
2987 {
2989
2990
2992 }
2993
2994
2996
2997
2999
3000
3002
3004
3006
3007
3009
3010
3012 }
3013
3015 {
3016
3018 }
3019
3020
3022 {
3025
3026
3028
3029
3031
3032
3034
3035
3037
3039
3040
3042
3043
3045
3046
3047 if (construtionPart.
IsBase())
3048 {
3049
3051 }
3052 }
3053
3055 {
3056
3058 }
3059
3060
3061 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3062 {
3065
3066
3068
3069
3071
3072
3074
3075
3077
3079
3080
3082
3083
3085
3086
3087 if (construtionPart.
IsBase())
3088 {
3089
3091 }
3092 }
3093
3095 {
3096
3098 }
3099
3102 {
3103 bool process = false;
3104
3105
3109
3110 if (process)
3111 {
3112 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3113 {
3115 return;
3116 }
3117
3119 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3120 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3121
3122
3124 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3125 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3126 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3127 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3128 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3129 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3130 mins = minTmp;
3131 maxs = maxTmp;
3132
3133 maxs[1] = maxs[1] + 0.35;
3134
3136 }
3137 }
3138
3141 {
3144
3145
3147 foreach (
EntityAI entity : foundEntities)
3148 {
3151 }
3152 }
3153
3154
3156 {
3158
3162 }
3163
3165 {
3167
3169 {
3171 }
3172 else
3173 {
3175 }
3176
3178 }
3179
3181 {
3183
3185 foreach (
string slotName : attachmentSlots)
3186 {
3188 }
3189
3190
3193 else
3195
3197 }
3198
3200 {
3201 string slotNameMounted = slot_name + "_Mounted";
3202 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3203
3204 if (attachment)
3205 {
3206 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3207 if (barbedWire && barbedWire.IsMounted())
3209 else
3211
3212 if (is_locked)
3213 {
3214 SetAnimationPhase(slotNameMounted, 0);
3215 SetAnimationPhase(slot_name, 1);
3216 }
3217 else
3218 {
3219 SetAnimationPhase(slotNameMounted, 1);
3220 SetAnimationPhase(slot_name, 0);
3221 }
3222 }
3223 else
3224 {
3225 SetAnimationPhase(slotNameMounted, 1);
3226 SetAnimationPhase(slot_name, 1);
3227
3229 }
3230 }
3231
3232
3234 {
3237
3240
3243
3244 foreach (
string slotName : attachmentSlots)
3245 {
3247 }
3248
3249
3251 {
3254
3256 }
3257 else
3258 {
3261
3263 }
3264
3267 }
3268
3270 {
3271
3273 return;
3274
3275 string slot_name_mounted = slot_name + "_Mounted";
3276 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3277
3278
3280 RemoveProxyPhysics( slot_name_mounted );
3281 RemoveProxyPhysics( slot_name );
3282
3283 if ( attachment )
3284 {
3286 if ( is_locked )
3287 {
3289 AddProxyPhysics( slot_name_mounted );
3290 }
3291 else
3292 {
3294 AddProxyPhysics( slot_name );
3295 }
3296 }
3297 }
3298
3300 {
3301 SetAffectPathgraph( true, false );
3303 }
3304
3306 {
3307 return true;
3308 }
3309
3311 {
3312 return true;
3313 }
3314
3316 {
3317 if ( attachment )
3318 {
3320 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3321
3322 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3323 }
3324
3325 return false;
3326 }
3327
3329 {
3331 }
3332
3333
3335 {
3336 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3337 if (
GetGame().ConfigIsExisting( config_path ) )
3338 {
3340 }
3341 }
3342
3344 {
3345 return true;
3346 }
3347
3349 {
3350 return true;
3351 }
3352
3354 {
3355 return true;
3356 }
3357
3358
3360 {
3362 {
3364 }
3365
3367 }
3368
3370 {
3372 }
3373
3374
3375
3377 {
3378 return super.CanReceiveAttachment(attachment, slotId);
3379 }
3380
3382 {
3383 int attachment_count = GetInventory().AttachmentCount();
3384 if ( attachment_count > 0 )
3385 {
3386 if (
HasBase() && attachment_count == 1 )
3387 {
3388 return false;
3389 }
3390
3391 return true;
3392 }
3393
3394 return false;
3395 }
3396
3398 {
3399 return true;
3400 }
3401
3403 {
3404 return false;
3405 }
3406
3407
3409 {
3410 return false;
3411 }
3412
3414 {
3415 return false;
3416 }
3417
3418
3420 {
3421 return false;
3422 }
3423
3424
3425
3427 {
3428 return true;
3429 }
3430
3432 {
3433 return true;
3434 }
3435
3438 {
3439 return false;
3440 }
3441
3442
3444 {
3445 return true;
3446 }
3447
3448
3450 {
3451 return false;
3452 }
3453
3454
3456 {
3457 return true;
3458 }
3459
3460
3462 {
3463 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3464 {
3465 return false;
3466 }
3467
3468 return true;
3469 }
3470
3472 {
3475
3476 return item;
3477 }
3478
3479
3481 {
3483 {
3484
3486
3487
3490
3492 if ( MemoryPointExists( slot_name + "_min" ) )
3493 {
3494 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3495 }
3496 if ( MemoryPointExists( slot_name + "_max" ) )
3497 {
3498 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3499 }
3500
3501
3504
3505
3508 center = ModelToWorld( center );
3509
3510
3513
3514 areaDamage.SetExtents( extents[0], extents[1] );
3515 areaDamage.SetAreaPosition( center );
3516 areaDamage.SetAreaOrientation( orientation );
3519 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3520 areaDamage.SetAmmoName( "BarbedWireHit" );
3521 areaDamage.Spawn();
3522
3524 }
3525 }
3526
3528 {
3529 if ( angle_deg != 0 )
3530 {
3531
3532 orientation[0] = orientation[0] - angle_deg;
3533
3534
3536 if ( MemoryPointExists( "rotate_axis" ) )
3537 {
3538 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3539 }
3540 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];
3541 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];
3542 center[0] = r_center_x;
3543 center[2] = r_center_z;
3544 }
3545 }
3546
3548 {
3550 {
3553 {
3554 if (areaDamage)
3555 {
3556 areaDamage.Destroy();
3557 }
3558
3560 }
3561 }
3562 }
3563
3565 {
3566 return true;
3567 }
3568
3569
3570
3571
3573 {
3575 }
3576
3578 {
3580 }
3581
3583 {
3585 }
3586
3588 {
3590
3591 switch ( material_type )
3592 {
3598 }
3599
3600 return "";
3601 }
3602
3604 {
3606
3607 switch ( material_type )
3608 {
3614 }
3615
3616 return "";
3617 }
3618
3619
3621 {
3623 {
3624
3626 {
3627 SetHealth(slot_name,"Health",item.GetHealth());
3628 }
3629 }
3630 }
3631
3633 {
3634 return 111;
3635 }
3636
3638 {
3639 super.SetActions();
3640
3644 }
3645
3646
3647
3648
3650 {
3651 }
3652
3655 {
3656 return null;
3657 }
3658
3660 {
3662 }
3663
3665 {
3668
3669 Man p;
3670
3671 #ifdef SERVER
3674 if (players.Count())
3675 p = players[0];
3676 #else
3678 #endif
3679
3681 {
3682 bool excluded = false;
3684 if (excludes)
3685 {
3686 foreach (string exclude : excludes)
3687 {
3689 {
3690 excluded = true;
3691 break;
3692 }
3693 }
3694 }
3695
3696 if (!excluded)
3697 {
3699 }
3700 }
3701
3703 }
3704}
3705
3707{
3708#ifdef BSB_DEBUG
3710#else
3711
3712#endif
3713}
3715{
3716#ifdef BSB_DEBUG_SPAM
3718#else
3719
3720#endif
3721}
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.