2343{
2345
2347
2349
2351
2357
2358
2359
2365
2371
2373
2377
2378
2380 {
2382
2383
2384 RegisterNetSyncVariableInt( "m_SyncParts01" );
2385 RegisterNetSyncVariableInt( "m_SyncParts02" );
2386 RegisterNetSyncVariableInt( "m_SyncParts03" );
2387 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2388 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2389 RegisterNetSyncVariableBool( "m_HasBase" );
2390
2391
2393
2394 if (ConfigIsExisting("hybridAttachments"))
2395 {
2398 }
2399 if (ConfigIsExisting("mountables"))
2400 {
2403 }
2404
2406 }
2407
2409 {
2410 super.EEDelete(parent);
2411
2413 {
2414 areaDamage.Destroy();
2415 }
2416
2417 }
2418
2420 {
2421 return "disableBaseDamage";
2422 }
2423
2425 {
2426 return true;
2427 }
2428
2430 {
2431 return EInventoryIconVisibility.HIDE_VICINITY;
2432 }
2433
2435 {
2436 super.InitItemSounds();
2437
2441
2446 }
2447
2449 {
2450 return "putDown_FenceKit_SoundSet";
2451 }
2452
2454 {
2455 return "Shelter_Site_Build_Loop_SoundSet";
2456 }
2457
2458
2460 {
2462 {
2463 SetSynchDirty();
2464 }
2465 }
2466
2468 {
2470 super.OnVariablesSynchronized();
2471
2473 }
2474
2476 {
2477
2479
2480
2482
2483
2485 }
2486
2487
2489 {
2490
2491 int offset;
2492 int mask;
2493
2494 if ( part_id >= 1 && part_id <= 31 )
2495 {
2496 offset = part_id - 1;
2497 mask = 1 << offset;
2498
2500 }
2501 else if ( part_id >= 32 && part_id <= 62 )
2502 {
2503 offset = ( part_id % 32 );
2504 mask = 1 << offset;
2505
2507 }
2508 else if ( part_id >= 63 && part_id <= 93 )
2509 {
2510 offset = ( part_id % 63 );
2511 mask = 1 << offset;
2512
2514 }
2515 }
2516
2518 {
2519
2520 int offset;
2521 int mask;
2522
2523 if ( part_id >= 1 && part_id <= 31 )
2524 {
2525 offset = part_id - 1;
2526 mask = 1 << offset;
2527
2529 }
2530 else if ( part_id >= 32 && part_id <= 62 )
2531 {
2532 offset = ( part_id % 32 );
2533 mask = 1 << offset;
2534
2536 }
2537 else if ( part_id >= 63 && part_id <= 93 )
2538 {
2539 offset = ( part_id % 63 );
2540 mask = 1 << offset;
2541
2543 }
2544 }
2545
2547 {
2548
2549 int offset;
2550 int mask;
2551
2552 if ( part_id >= 1 && part_id <= 31 )
2553 {
2554 offset = part_id - 1;
2555 mask = 1 << offset;
2556
2558 {
2559 return true;
2560 }
2561 }
2562 else if ( part_id >= 32 && part_id <= 62 )
2563 {
2564 offset = ( part_id % 32 );
2565 mask = 1 << offset;
2566
2568 {
2569 return true;
2570 }
2571 }
2572 else if ( part_id >= 63 && part_id <= 93 )
2573 {
2574 offset = ( part_id % 63 );
2575 mask = 1 << offset;
2576
2578 {
2579 return true;
2580 }
2581 }
2582
2583 return false;
2584 }
2585
2587 {
2590 }
2591
2593 {
2594
2597 }
2598
2600 {
2602 {
2605
2606 switch( build_action_id )
2607 {
2611 }
2612 }
2613 }
2614
2615
2617 {
2619 bool is_base = part.
IsBase();
2622 if ( is_part_built_sync )
2623 {
2625 {
2629
2630 if (is_base)
2631 {
2634 }
2635 }
2636 }
2637 else
2638 {
2640 {
2644
2645 if (is_base)
2646 {
2649 }
2650 }
2651 }
2652
2653
2655 }
2656
2657
2659 {
2662
2663 for ( int i = 0; i < construction_parts.Count(); ++i )
2664 {
2665 string key = construction_parts.GetKey( i );
2668 }
2669
2670
2672 }
2673
2675 {
2678
2679 for ( int i = 0; i < construction_parts.Count(); ++i )
2680 {
2681 string key = construction_parts.GetKey( i );
2683
2684 if ( value.
GetId() ==
id )
2685 {
2686 return value;
2687 }
2688 }
2689
2690 return NULL;
2691 }
2692
2693
2694
2696 {
2698 }
2699
2701 {
2703 }
2704
2706 {
2707 return true;
2708 }
2709
2711 {
2712 return false;
2713 }
2714
2715
2717 {
2720 {
2722 }
2723
2724 return construction_kit;
2725 }
2726
2728 {
2731 {
2733 }
2734 }
2735
2737 {
2739 }
2740
2742 {
2743 return "";
2744 }
2745
2747 {
2750 }
2751
2752
2754 {
2757 }
2758
2759
2761 {
2762 super.OnStoreSave( ctx );
2763
2764
2768
2770 }
2771
2773 {
2774 if ( !super.OnStoreLoad( ctx, version ) )
2775 return false;
2776
2777
2778
2780 {
2782 return false;
2783 }
2785 {
2787 return false;
2788 }
2790 {
2792 return false;
2793 }
2794
2795
2797 {
2799 return false;
2800 }
2801
2802
2803 return true;
2804 }
2805
2807 {
2808 super.AfterStoreLoad();
2809
2811 {
2813 }
2814 }
2815
2817 {
2818
2820
2821
2824
2825
2827 }
2828
2830 {
2831 super.OnCreatePhysics();
2834 }
2835
2837 {
2839 return;
2840
2841 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2842
2844 return;
2845
2847 string part_name = zone;
2849
2851 {
2852 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2853
2854 if ( construction_part && construction.IsPartConstructed( part_name ) )
2855 {
2857 construction.DestroyConnectedParts(part_name);
2858 }
2859
2860
2861 if ( part_name.
Contains(
"barbed") )
2862 {
2863 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2864 if (barbed_wire)
2865 barbed_wire.SetMountedState( false );
2866 }
2867 }
2868 }
2869
2871 {
2873 {
2875 }
2876
2877 super.EEOnAfterLoad();
2878 }
2879
2881 {
2882 super.EEInit();
2883
2884
2886
2887
2888 #ifdef DEVELOPER
2890 #endif
2891 }
2892
2894 {
2895 super.EEItemAttached( item, slot_name );
2896
2900 }
2901
2903 {
2904 super.EEItemDetached( item, slot_name );
2905
2908 }
2909
2910 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2911 {
2914
2917 }
2918
2919
2921 {
2922 return true;
2923 }
2924
2925
2926
2928 {
2930
2931
2932 if (construtionPart.
IsBase())
2933 {
2935
2936
2938 }
2939
2940
2942
2943
2945
2946
2948
2950
2952
2953
2955
2956
2958 }
2959
2961 {
2962
2964 }
2965
2966
2968 {
2971
2972
2974
2975
2977
2978
2980
2981
2983
2985
2986
2988
2989
2991
2992
2993 if (construtionPart.
IsBase())
2994 {
2995
2997 }
2998 }
2999
3001 {
3002
3004 }
3005
3006
3007 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3008 {
3011
3012
3014
3015
3017
3018
3020
3021
3023
3025
3026
3028
3029
3031
3032
3033 if (construtionPart.
IsBase())
3034 {
3035
3037 }
3038 }
3039
3041 {
3042
3044 }
3045
3048 {
3049 bool process = false;
3050
3051
3055
3056 if (process)
3057 {
3058 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3059 {
3061 return;
3062 }
3063
3065 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3066 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3067
3068
3070 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3071 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3072 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3073 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3074 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3075 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3076 mins = minTmp;
3077 maxs = maxTmp;
3078
3079 maxs[1] = maxs[1] + 0.35;
3080
3082 }
3083 }
3084
3087 {
3090
3091
3093 foreach (
EntityAI entity : foundEntities)
3094 {
3097 }
3098 }
3099
3100
3102 {
3104
3108 }
3109
3111 {
3113
3115 {
3117 }
3118 else
3119 {
3121 }
3122
3124 }
3125
3127 {
3129
3131 foreach (
string slotName : attachmentSlots)
3132 {
3134 }
3135
3136
3139 else
3141
3143 }
3144
3146 {
3147 string slotNameMounted = slot_name + "_Mounted";
3148 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3149
3150 if (attachment)
3151 {
3152 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3153 if (barbedWire && barbedWire.IsMounted())
3155 else
3157
3158 if (is_locked)
3159 {
3160 SetAnimationPhase(slotNameMounted, 0);
3161 SetAnimationPhase(slot_name, 1);
3162 }
3163 else
3164 {
3165 SetAnimationPhase(slotNameMounted, 1);
3166 SetAnimationPhase(slot_name, 0);
3167 }
3168 }
3169 else
3170 {
3171 SetAnimationPhase(slotNameMounted, 1);
3172 SetAnimationPhase(slot_name, 1);
3173
3175 }
3176 }
3177
3178
3180 {
3183
3186
3189
3190 foreach (
string slotName : attachmentSlots)
3191 {
3193 }
3194
3195
3197 {
3200
3202 }
3203 else
3204 {
3207
3209 }
3210
3213 }
3214
3216 {
3217
3219 return;
3220
3221 string slot_name_mounted = slot_name + "_Mounted";
3222 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3223
3224
3226 RemoveProxyPhysics( slot_name_mounted );
3227 RemoveProxyPhysics( slot_name );
3228
3229 if ( attachment )
3230 {
3232 if ( is_locked )
3233 {
3235 AddProxyPhysics( slot_name_mounted );
3236 }
3237 else
3238 {
3240 AddProxyPhysics( slot_name );
3241 }
3242 }
3243 }
3244
3246 {
3247 SetAffectPathgraph( true, false );
3249 }
3250
3252 {
3253 return true;
3254 }
3255
3257 {
3258 return true;
3259 }
3260
3262 {
3263 if ( attachment )
3264 {
3266 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3267
3268 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3269 }
3270
3271 return false;
3272 }
3273
3275 {
3277 }
3278
3279
3281 {
3282 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3283 if (
GetGame().ConfigIsExisting( config_path ) )
3284 {
3286 }
3287 }
3288
3290 {
3291 return true;
3292 }
3293
3295 {
3296 return true;
3297 }
3298
3300 {
3301 return true;
3302 }
3303
3304
3306 {
3308 {
3310 }
3311
3313 }
3314
3316 {
3318 }
3319
3320
3321
3323 {
3324 return super.CanReceiveAttachment(attachment, slotId);
3325 }
3326
3328 {
3329 int attachment_count = GetInventory().AttachmentCount();
3330 if ( attachment_count > 0 )
3331 {
3332 if (
HasBase() && attachment_count == 1 )
3333 {
3334 return false;
3335 }
3336
3337 return true;
3338 }
3339
3340 return false;
3341 }
3342
3344 {
3345 return true;
3346 }
3347
3349 {
3350 return false;
3351 }
3352
3353
3355 {
3356 return false;
3357 }
3358
3360 {
3361 return false;
3362 }
3363
3364
3366 {
3367 return false;
3368 }
3369
3370
3371
3373 {
3374 return true;
3375 }
3376
3378 {
3379 return true;
3380 }
3381
3384 {
3385 return false;
3386 }
3387
3388
3390 {
3391 return true;
3392 }
3393
3394
3396 {
3397 return false;
3398 }
3399
3400
3402 {
3403 return true;
3404 }
3405
3406
3408 {
3409 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3410 {
3411 return false;
3412 }
3413
3414 return true;
3415 }
3416
3418 {
3421
3422 return item;
3423 }
3424
3425
3427 {
3429 {
3430
3432
3433
3436
3438 if ( MemoryPointExists( slot_name + "_min" ) )
3439 {
3440 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3441 }
3442 if ( MemoryPointExists( slot_name + "_max" ) )
3443 {
3444 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3445 }
3446
3447
3450
3451
3454 center = ModelToWorld( center );
3455
3456
3459
3460 areaDamage.SetExtents( extents[0], extents[1] );
3461 areaDamage.SetAreaPosition( center );
3462 areaDamage.SetAreaOrientation( orientation );
3465 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3466 areaDamage.SetAmmoName( "BarbedWireHit" );
3467 areaDamage.Spawn();
3468
3470 }
3471 }
3472
3474 {
3475 if ( angle_deg != 0 )
3476 {
3477
3478 orientation[0] = orientation[0] - angle_deg;
3479
3480
3482 if ( MemoryPointExists( "rotate_axis" ) )
3483 {
3484 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3485 }
3486 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];
3487 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];
3488 center[0] = r_center_x;
3489 center[2] = r_center_z;
3490 }
3491 }
3492
3494 {
3496 {
3499 {
3500 if (areaDamage)
3501 {
3502 areaDamage.Destroy();
3503 }
3504
3506 }
3507 }
3508 }
3509
3511 {
3512 return true;
3513 }
3514
3515
3516
3517
3519 {
3521 }
3522
3524 {
3526 }
3527
3529 {
3531 }
3532
3534 {
3536
3537 switch ( material_type )
3538 {
3544 }
3545
3546 return "";
3547 }
3548
3550 {
3552
3553 switch ( material_type )
3554 {
3560 }
3561
3562 return "";
3563 }
3564
3565
3567 {
3569 {
3570
3572 {
3573 SetHealth(slot_name,"Health",item.GetHealth());
3574 }
3575 }
3576 }
3577
3579 {
3580 return 111;
3581 }
3582
3584 {
3585 super.SetActions();
3586
3590 }
3591
3592
3593
3594
3596 {
3597 }
3598
3601 {
3602 return null;
3603 }
3604
3606 {
3608 }
3609
3611 {
3614
3615 Man p;
3616
3617 #ifdef SERVER
3620 if (players.Count())
3621 p = players[0];
3622 #else
3624 #endif
3625
3627 {
3628 bool excluded = false;
3630 if (excludes)
3631 {
3632 foreach (string exclude : excludes)
3633 {
3635 {
3636 excluded = true;
3637 break;
3638 }
3639 }
3640 }
3641
3642 if (!excluded)
3643 {
3645 }
3646 }
3647
3649 }
3650}
3651
3653{
3654#ifdef BSB_DEBUG
3656#else
3657
3658#endif
3659}
3661{
3662#ifdef BSB_DEBUG_SPAM
3664#else
3665
3666#endif
3667}
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.