2348{
2350
2352
2354
2356
2362
2363
2364
2370
2376
2378
2382
2383
2385 {
2387
2388
2389 RegisterNetSyncVariableInt( "m_SyncParts01" );
2390 RegisterNetSyncVariableInt( "m_SyncParts02" );
2391 RegisterNetSyncVariableInt( "m_SyncParts03" );
2392 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2393 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2394 RegisterNetSyncVariableBool( "m_HasBase" );
2395
2396
2398
2399 if (ConfigIsExisting("hybridAttachments"))
2400 {
2403 }
2404 if (ConfigIsExisting("mountables"))
2405 {
2408 }
2409
2411 }
2412
2414 {
2415 super.EEDelete(parent);
2416
2418 {
2419 areaDamage.Destroy();
2420 }
2421
2422 }
2423
2425 {
2426 return "disableBaseDamage";
2427 }
2428
2430 {
2431 return true;
2432 }
2433
2435 {
2436 return EInventoryIconVisibility.HIDE_VICINITY;
2437 }
2438
2440 {
2441 super.InitItemSounds();
2442
2446
2451 }
2452
2454 {
2455 return "putDown_FenceKit_SoundSet";
2456 }
2457
2459 {
2460 return "Shelter_Site_Build_Loop_SoundSet";
2461 }
2462
2463
2465 {
2467 {
2468 SetSynchDirty();
2469 }
2470 }
2471
2473 {
2475 super.OnVariablesSynchronized();
2476
2478 }
2479
2481 {
2482
2484
2485
2487
2488
2490 }
2491
2492
2494 {
2495
2496 int offset;
2497 int mask;
2498
2499 if ( part_id >= 1 && part_id <= 31 )
2500 {
2501 offset = part_id - 1;
2502 mask = 1 << offset;
2503
2505 }
2506 else if ( part_id >= 32 && part_id <= 62 )
2507 {
2508 offset = ( part_id % 32 );
2509 mask = 1 << offset;
2510
2512 }
2513 else if ( part_id >= 63 && part_id <= 93 )
2514 {
2515 offset = ( part_id % 63 );
2516 mask = 1 << offset;
2517
2519 }
2520 }
2521
2523 {
2524
2525 int offset;
2526 int mask;
2527
2528 if ( part_id >= 1 && part_id <= 31 )
2529 {
2530 offset = part_id - 1;
2531 mask = 1 << offset;
2532
2534 }
2535 else if ( part_id >= 32 && part_id <= 62 )
2536 {
2537 offset = ( part_id % 32 );
2538 mask = 1 << offset;
2539
2541 }
2542 else if ( part_id >= 63 && part_id <= 93 )
2543 {
2544 offset = ( part_id % 63 );
2545 mask = 1 << offset;
2546
2548 }
2549 }
2550
2552 {
2553
2554 int offset;
2555 int mask;
2556
2557 if ( part_id >= 1 && part_id <= 31 )
2558 {
2559 offset = part_id - 1;
2560 mask = 1 << offset;
2561
2563 {
2564 return true;
2565 }
2566 }
2567 else if ( part_id >= 32 && part_id <= 62 )
2568 {
2569 offset = ( part_id % 32 );
2570 mask = 1 << offset;
2571
2573 {
2574 return true;
2575 }
2576 }
2577 else if ( part_id >= 63 && part_id <= 93 )
2578 {
2579 offset = ( part_id % 63 );
2580 mask = 1 << offset;
2581
2583 {
2584 return true;
2585 }
2586 }
2587
2588 return false;
2589 }
2590
2592 {
2595 }
2596
2598 {
2599
2602 }
2603
2605 {
2607 {
2610
2611 switch( build_action_id )
2612 {
2616 }
2617 }
2618 }
2619
2620
2622 {
2624 bool is_base = part.
IsBase();
2627 if ( is_part_built_sync )
2628 {
2630 {
2634
2635 if (is_base)
2636 {
2639 }
2640 }
2641 }
2642 else
2643 {
2645 {
2649
2650 if (is_base)
2651 {
2654 }
2655 }
2656 }
2657
2658
2660 }
2661
2662
2664 {
2667
2668 for ( int i = 0; i < construction_parts.Count(); ++i )
2669 {
2670 string key = construction_parts.GetKey( i );
2673 }
2674
2675
2677 }
2678
2680 {
2683
2684 for ( int i = 0; i < construction_parts.Count(); ++i )
2685 {
2686 string key = construction_parts.GetKey( i );
2688
2689 if ( value.
GetId() ==
id )
2690 {
2691 return value;
2692 }
2693 }
2694
2695 return NULL;
2696 }
2697
2698
2699
2701 {
2703 }
2704
2706 {
2708 }
2709
2711 {
2712 return true;
2713 }
2714
2716 {
2717 return false;
2718 }
2719
2720
2722 {
2725 {
2727 }
2728
2729 return construction_kit;
2730 }
2731
2733 {
2736 {
2738 }
2739 }
2740
2742 {
2744 }
2745
2747 {
2748 return "";
2749 }
2750
2752 {
2755 }
2756
2757
2759 {
2762 }
2763
2764
2766 {
2767 super.OnStoreSave( ctx );
2768
2769
2773
2775 }
2776
2778 {
2779 if ( !super.OnStoreLoad( ctx, version ) )
2780 return false;
2781
2782
2783
2785 {
2787 return false;
2788 }
2790 {
2792 return false;
2793 }
2795 {
2797 return false;
2798 }
2799
2800
2802 {
2804 return false;
2805 }
2806
2807
2808 return true;
2809 }
2810
2812 {
2813 super.AfterStoreLoad();
2814
2816 {
2818 }
2819 }
2820
2822 {
2823
2825
2826
2829
2830
2832 }
2833
2835 {
2836 super.OnCreatePhysics();
2839 }
2840
2842 {
2844 return;
2845
2846 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2847
2849 return;
2850
2852 string part_name = zone;
2854
2856 {
2857 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2858
2859 if ( construction_part && construction.IsPartConstructed( part_name ) )
2860 {
2862 construction.DestroyConnectedParts(part_name);
2863 }
2864
2865
2866 if ( part_name.
Contains(
"barbed") )
2867 {
2868 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2869 if (barbed_wire)
2870 barbed_wire.SetMountedState( false );
2871 }
2872 }
2873 }
2874
2876 {
2878 {
2880 }
2881
2882 super.EEOnAfterLoad();
2883 }
2884
2886 {
2887 super.EEInit();
2888
2889
2891
2892
2893 #ifdef DEVELOPER
2895 #endif
2896 }
2897
2899 {
2900 super.EEItemAttached( item, slot_name );
2901
2905 }
2906
2908 {
2909 super.EEItemDetached( item, slot_name );
2910
2913 }
2914
2915 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2916 {
2919
2922 }
2923
2924
2926 {
2927 return true;
2928 }
2929
2930
2931
2933 {
2935
2936
2937 if (construtionPart.
IsBase())
2938 {
2940
2941
2943 }
2944
2945
2947
2948
2950
2951
2953
2955
2957
2958
2960
2961
2963 }
2964
2966 {
2967
2969 }
2970
2971
2973 {
2976
2977
2979
2980
2982
2983
2985
2986
2988
2990
2991
2993
2994
2996
2997
2998 if (construtionPart.
IsBase())
2999 {
3000
3002 }
3003 }
3004
3006 {
3007
3009 }
3010
3011
3012 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3013 {
3016
3017
3019
3020
3022
3023
3025
3026
3028
3030
3031
3033
3034
3036
3037
3038 if (construtionPart.
IsBase())
3039 {
3040
3042 }
3043 }
3044
3046 {
3047
3049 }
3050
3053 {
3054 bool process = false;
3055
3056
3060
3061 if (process)
3062 {
3063 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
3064 {
3066 return;
3067 }
3068
3070 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
3071 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
3072
3073
3075 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
3076 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
3077 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
3078 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
3079 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
3080 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
3081 mins = minTmp;
3082 maxs = maxTmp;
3083
3084 maxs[1] = maxs[1] + 0.35;
3085
3087 }
3088 }
3089
3092 {
3095
3096
3098 foreach (
EntityAI entity : foundEntities)
3099 {
3102 }
3103 }
3104
3105
3107 {
3109
3113 }
3114
3116 {
3118
3120 {
3122 }
3123 else
3124 {
3126 }
3127
3129 }
3130
3132 {
3134
3136 foreach (
string slotName : attachmentSlots)
3137 {
3139 }
3140
3141
3144 else
3146
3148 }
3149
3151 {
3152 string slotNameMounted = slot_name + "_Mounted";
3153 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3154
3155 if (attachment)
3156 {
3157 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3158 if (barbedWire && barbedWire.IsMounted())
3160 else
3162
3163 if (is_locked)
3164 {
3165 SetAnimationPhase(slotNameMounted, 0);
3166 SetAnimationPhase(slot_name, 1);
3167 }
3168 else
3169 {
3170 SetAnimationPhase(slotNameMounted, 1);
3171 SetAnimationPhase(slot_name, 0);
3172 }
3173 }
3174 else
3175 {
3176 SetAnimationPhase(slotNameMounted, 1);
3177 SetAnimationPhase(slot_name, 1);
3178
3180 }
3181 }
3182
3183
3185 {
3188
3191
3194
3195 foreach (
string slotName : attachmentSlots)
3196 {
3198 }
3199
3200
3202 {
3205
3207 }
3208 else
3209 {
3212
3214 }
3215
3218 }
3219
3221 {
3222
3224 return;
3225
3226 string slot_name_mounted = slot_name + "_Mounted";
3227 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3228
3229
3231 RemoveProxyPhysics( slot_name_mounted );
3232 RemoveProxyPhysics( slot_name );
3233
3234 if ( attachment )
3235 {
3237 if ( is_locked )
3238 {
3240 AddProxyPhysics( slot_name_mounted );
3241 }
3242 else
3243 {
3245 AddProxyPhysics( slot_name );
3246 }
3247 }
3248 }
3249
3251 {
3252 SetAffectPathgraph( true, false );
3254 }
3255
3257 {
3258 return true;
3259 }
3260
3262 {
3263 return true;
3264 }
3265
3267 {
3268 if ( attachment )
3269 {
3271 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3272
3273 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3274 }
3275
3276 return false;
3277 }
3278
3280 {
3282 }
3283
3284
3286 {
3287 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3288 if (
GetGame().ConfigIsExisting( config_path ) )
3289 {
3291 }
3292 }
3293
3295 {
3296 return true;
3297 }
3298
3300 {
3301 return true;
3302 }
3303
3305 {
3306 return true;
3307 }
3308
3309
3311 {
3313 {
3315 }
3316
3318 }
3319
3321 {
3323 }
3324
3325
3326
3328 {
3329 return super.CanReceiveAttachment(attachment, slotId);
3330 }
3331
3333 {
3334 int attachment_count = GetInventory().AttachmentCount();
3335 if ( attachment_count > 0 )
3336 {
3337 if (
HasBase() && attachment_count == 1 )
3338 {
3339 return false;
3340 }
3341
3342 return true;
3343 }
3344
3345 return false;
3346 }
3347
3349 {
3350 return true;
3351 }
3352
3354 {
3355 return false;
3356 }
3357
3358
3360 {
3361 return false;
3362 }
3363
3365 {
3366 return false;
3367 }
3368
3369
3371 {
3372 return false;
3373 }
3374
3375
3376
3378 {
3379 return true;
3380 }
3381
3383 {
3384 return true;
3385 }
3386
3389 {
3390 return false;
3391 }
3392
3393
3395 {
3396 return true;
3397 }
3398
3399
3401 {
3402 return false;
3403 }
3404
3405
3407 {
3408 return true;
3409 }
3410
3411
3413 {
3414 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3415 {
3416 return false;
3417 }
3418
3419 return true;
3420 }
3421
3423 {
3426
3427 return item;
3428 }
3429
3430
3432 {
3434 {
3435
3437
3438
3441
3443 if ( MemoryPointExists( slot_name + "_min" ) )
3444 {
3445 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3446 }
3447 if ( MemoryPointExists( slot_name + "_max" ) )
3448 {
3449 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3450 }
3451
3452
3455
3456
3459 center = ModelToWorld( center );
3460
3461
3464
3465 areaDamage.SetExtents( extents[0], extents[1] );
3466 areaDamage.SetAreaPosition( center );
3467 areaDamage.SetAreaOrientation( orientation );
3470 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3471 areaDamage.SetAmmoName( "BarbedWireHit" );
3472 areaDamage.Spawn();
3473
3475 }
3476 }
3477
3479 {
3480 if ( angle_deg != 0 )
3481 {
3482
3483 orientation[0] = orientation[0] - angle_deg;
3484
3485
3487 if ( MemoryPointExists( "rotate_axis" ) )
3488 {
3489 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3490 }
3491 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];
3492 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];
3493 center[0] = r_center_x;
3494 center[2] = r_center_z;
3495 }
3496 }
3497
3499 {
3501 {
3504 {
3505 if (areaDamage)
3506 {
3507 areaDamage.Destroy();
3508 }
3509
3511 }
3512 }
3513 }
3514
3516 {
3517 return true;
3518 }
3519
3520
3521
3522
3524 {
3526 }
3527
3529 {
3531 }
3532
3534 {
3536 }
3537
3539 {
3541
3542 switch ( material_type )
3543 {
3549 }
3550
3551 return "";
3552 }
3553
3555 {
3557
3558 switch ( material_type )
3559 {
3565 }
3566
3567 return "";
3568 }
3569
3570
3572 {
3574 {
3575
3577 {
3578 SetHealth(slot_name,"Health",item.GetHealth());
3579 }
3580 }
3581 }
3582
3584 {
3585 return 111;
3586 }
3587
3589 {
3590 super.SetActions();
3591
3595 }
3596
3597
3598
3599
3601 {
3602 }
3603
3606 {
3607 return null;
3608 }
3609
3611 {
3613 }
3614
3616 {
3619
3620 Man p;
3621
3622 #ifdef SERVER
3625 if (players.Count())
3626 p = players[0];
3627 #else
3629 #endif
3630
3632 {
3633 bool excluded = false;
3635 if (excludes)
3636 {
3637 foreach (string exclude : excludes)
3638 {
3640 {
3641 excluded = true;
3642 break;
3643 }
3644 }
3645 }
3646
3647 if (!excluded)
3648 {
3650 }
3651 }
3652
3654 }
3655}
3656
3658{
3659#ifdef BSB_DEBUG
3661#else
3662
3663#endif
3664}
3666{
3667#ifdef BSB_DEBUG_SPAM
3669#else
3670
3671#endif
3672}
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.