2081{
2083
2085
2087
2089
2095
2096
2097
2103
2109
2111
2115
2116
2118 {
2120
2121
2122 RegisterNetSyncVariableInt( "m_SyncParts01" );
2123 RegisterNetSyncVariableInt( "m_SyncParts02" );
2124 RegisterNetSyncVariableInt( "m_SyncParts03" );
2125 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2126 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2127 RegisterNetSyncVariableBool( "m_HasBase" );
2128
2129
2131
2132 if (ConfigIsExisting("hybridAttachments"))
2133 {
2136 }
2137 if (ConfigIsExisting("mountables"))
2138 {
2141 }
2142
2144 }
2145
2147 {
2148 super.EEDelete(parent);
2149
2151 {
2152 areaDamage.Destroy();
2153 }
2154
2155 }
2156
2158 {
2159 return "disableBaseDamage";
2160 }
2161
2163 {
2164 return true;
2165 }
2166
2168 {
2169 return EInventoryIconVisibility.HIDE_VICINITY;
2170 }
2171
2173 {
2174 super.InitItemSounds();
2175
2179
2184 }
2185
2187 {
2188 return "putDown_FenceKit_SoundSet";
2189 }
2190
2192 {
2193 return "Shelter_Site_Build_Loop_SoundSet";
2194 }
2195
2196
2198 {
2200 {
2201 SetSynchDirty();
2202 }
2203 }
2204
2206 {
2208 super.OnVariablesSynchronized();
2209
2211 }
2212
2214 {
2215
2217
2218
2220
2221
2223 }
2224
2225
2227 {
2228
2229 int offset;
2230 int mask;
2231
2232 if ( part_id >= 1 && part_id <= 31 )
2233 {
2234 offset = part_id - 1;
2235 mask = 1 << offset;
2236
2238 }
2239 else if ( part_id >= 32 && part_id <= 62 )
2240 {
2241 offset = ( part_id % 32 );
2242 mask = 1 << offset;
2243
2245 }
2246 else if ( part_id >= 63 && part_id <= 93 )
2247 {
2248 offset = ( part_id % 63 );
2249 mask = 1 << offset;
2250
2252 }
2253 }
2254
2256 {
2257
2258 int offset;
2259 int mask;
2260
2261 if ( part_id >= 1 && part_id <= 31 )
2262 {
2263 offset = part_id - 1;
2264 mask = 1 << offset;
2265
2267 }
2268 else if ( part_id >= 32 && part_id <= 62 )
2269 {
2270 offset = ( part_id % 32 );
2271 mask = 1 << offset;
2272
2274 }
2275 else if ( part_id >= 63 && part_id <= 93 )
2276 {
2277 offset = ( part_id % 63 );
2278 mask = 1 << offset;
2279
2281 }
2282 }
2283
2285 {
2286
2287 int offset;
2288 int mask;
2289
2290 if ( part_id >= 1 && part_id <= 31 )
2291 {
2292 offset = part_id - 1;
2293 mask = 1 << offset;
2294
2296 {
2297 return true;
2298 }
2299 }
2300 else if ( part_id >= 32 && part_id <= 62 )
2301 {
2302 offset = ( part_id % 32 );
2303 mask = 1 << offset;
2304
2306 {
2307 return true;
2308 }
2309 }
2310 else if ( part_id >= 63 && part_id <= 93 )
2311 {
2312 offset = ( part_id % 63 );
2313 mask = 1 << offset;
2314
2316 {
2317 return true;
2318 }
2319 }
2320
2321 return false;
2322 }
2323
2325 {
2328 }
2329
2331 {
2332
2335 }
2336
2338 {
2340 {
2343
2344 switch( build_action_id )
2345 {
2349 }
2350 }
2351 }
2352
2353
2355 {
2357 bool is_base = part.
IsBase();
2360 if ( is_part_built_sync )
2361 {
2363 {
2367
2368 if (is_base)
2369 {
2372 }
2373 }
2374 }
2375 else
2376 {
2378 {
2382
2383 if (is_base)
2384 {
2387 }
2388 }
2389 }
2390
2391
2393 }
2394
2395
2397 {
2400
2401 for ( int i = 0; i < construction_parts.Count(); ++i )
2402 {
2403 string key = construction_parts.GetKey( i );
2406 }
2407
2408
2410 }
2411
2413 {
2416
2417 for ( int i = 0; i < construction_parts.Count(); ++i )
2418 {
2419 string key = construction_parts.GetKey( i );
2421
2422 if ( value.
GetId() ==
id )
2423 {
2424 return value;
2425 }
2426 }
2427
2428 return NULL;
2429 }
2430
2431
2432
2434 {
2436 }
2437
2439 {
2441 }
2442
2444 {
2445 return true;
2446 }
2447
2449 {
2450 return false;
2451 }
2452
2453
2455 {
2458 {
2460 }
2461
2462 return construction_kit;
2463 }
2464
2466 {
2469 {
2471 }
2472 }
2473
2475 {
2477 }
2478
2480 {
2481 return "";
2482 }
2483
2485 {
2488 }
2489
2490
2492 {
2495 }
2496
2497
2499 {
2500 super.OnStoreSave( ctx );
2501
2502
2506
2508 }
2509
2511 {
2512 if ( !super.OnStoreLoad( ctx, version ) )
2513 return false;
2514
2515
2516
2518 {
2520 return false;
2521 }
2523 {
2525 return false;
2526 }
2528 {
2530 return false;
2531 }
2532
2533
2535 {
2537 return false;
2538 }
2539
2540
2541 return true;
2542 }
2543
2545 {
2546 super.AfterStoreLoad();
2547
2549 {
2551 }
2552 }
2553
2555 {
2556
2558
2559
2562
2563
2565 }
2566
2568 {
2569 super.OnCreatePhysics();
2572 }
2573
2575 {
2577 return;
2578
2579 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2580
2582 return;
2583
2585 string part_name = zone;
2587
2589 {
2590 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2591
2592 if ( construction_part && construction.IsPartConstructed( part_name ) )
2593 {
2595 construction.DestroyConnectedParts(part_name);
2596 }
2597
2598
2599 if ( part_name.
Contains(
"barbed") )
2600 {
2601 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2602 if (barbed_wire)
2603 barbed_wire.SetMountedState( false );
2604 }
2605 }
2606 }
2607
2609 {
2611 {
2613 }
2614
2615 super.EEOnAfterLoad();
2616 }
2617
2619 {
2620 super.EEInit();
2621
2622
2624
2625
2626 #ifdef DEVELOPER
2628 #endif
2629 }
2630
2632 {
2633 super.EEItemAttached( item, slot_name );
2634
2638 }
2639
2641 {
2642 super.EEItemDetached( item, slot_name );
2643
2646 }
2647
2648 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2649 {
2652
2655 }
2656
2657
2659 {
2660 return true;
2661 }
2662
2663
2664
2666 {
2668
2669
2670 if (construtionPart.
IsBase())
2671 {
2673
2674
2676 }
2677
2678
2680
2681
2683
2684
2686
2688
2690
2691
2693
2694
2696 }
2697
2699 {
2700
2702 }
2703
2704
2706 {
2709
2710
2712
2713
2715
2716
2718
2719
2721
2723
2724
2726
2727
2729
2730
2731 if (construtionPart.
IsBase())
2732 {
2733
2735 }
2736 }
2737
2739 {
2740
2742 }
2743
2744
2745 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2746 {
2749
2750
2752
2753
2755
2756
2758
2759
2761
2763
2764
2766
2767
2769
2770
2771 if (construtionPart.
IsBase())
2772 {
2773
2775 }
2776 }
2777
2779 {
2780
2782 }
2783
2786 {
2787 bool process = false;
2788
2789
2793
2794 if (process)
2795 {
2796 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2797 {
2799 return;
2800 }
2801
2803 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2804 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2805
2806
2808 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2809 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2810 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2811 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2812 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2813 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2814 mins = minTmp;
2815 maxs = maxTmp;
2816
2817 maxs[1] = maxs[1] + 0.35;
2818
2820 }
2821 }
2822
2825 {
2828
2829
2831 foreach (
EntityAI entity : foundEntities)
2832 {
2835 }
2836 }
2837
2838
2840 {
2842
2846 }
2847
2849 {
2851
2853 {
2855 }
2856 else
2857 {
2859 }
2860
2862 }
2863
2865 {
2867
2869 foreach (
string slotName : attachmentSlots)
2870 {
2872 }
2873
2874
2877 else
2879
2881 }
2882
2884 {
2885 string slotNameMounted = slot_name + "_Mounted";
2886 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2887
2888 if (attachment)
2889 {
2890 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2891 if (barbedWire && barbedWire.IsMounted())
2893 else
2895
2896 if (is_locked)
2897 {
2898 SetAnimationPhase(slotNameMounted, 0);
2899 SetAnimationPhase(slot_name, 1);
2900 }
2901 else
2902 {
2903 SetAnimationPhase(slotNameMounted, 1);
2904 SetAnimationPhase(slot_name, 0);
2905 }
2906 }
2907 else
2908 {
2909 SetAnimationPhase(slotNameMounted, 1);
2910 SetAnimationPhase(slot_name, 1);
2911
2913 }
2914 }
2915
2916
2918 {
2921
2924
2927
2928 foreach (
string slotName : attachmentSlots)
2929 {
2931 }
2932
2933
2935 {
2938
2940 }
2941 else
2942 {
2945
2947 }
2948
2951 }
2952
2954 {
2955
2957 return;
2958
2959 string slot_name_mounted = slot_name + "_Mounted";
2960 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2961
2962
2964 RemoveProxyPhysics( slot_name_mounted );
2965 RemoveProxyPhysics( slot_name );
2966
2967 if ( attachment )
2968 {
2970 if ( is_locked )
2971 {
2973 AddProxyPhysics( slot_name_mounted );
2974 }
2975 else
2976 {
2978 AddProxyPhysics( slot_name );
2979 }
2980 }
2981 }
2982
2984 {
2985 SetAffectPathgraph( true, false );
2987 }
2988
2990 {
2991 return true;
2992 }
2993
2995 {
2996 return true;
2997 }
2998
3000 {
3001 if ( attachment )
3002 {
3004 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3005
3006 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3007 }
3008
3009 return false;
3010 }
3011
3013 {
3015 }
3016
3017
3019 {
3020 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3021 if (
GetGame().ConfigIsExisting( config_path ) )
3022 {
3024 }
3025 }
3026
3028 {
3029 return true;
3030 }
3031
3033 {
3034 return true;
3035 }
3036
3038 {
3039 return true;
3040 }
3041
3042
3044 {
3046 {
3048 }
3049
3051 }
3052
3054 {
3056 }
3057
3058
3059
3061 {
3062 return super.CanReceiveAttachment(attachment, slotId);
3063 }
3064
3066 {
3067 int attachment_count = GetInventory().AttachmentCount();
3068 if ( attachment_count > 0 )
3069 {
3070 if (
HasBase() && attachment_count == 1 )
3071 {
3072 return false;
3073 }
3074
3075 return true;
3076 }
3077
3078 return false;
3079 }
3080
3082 {
3083 return true;
3084 }
3085
3087 {
3088 return false;
3089 }
3090
3091
3093 {
3094 return false;
3095 }
3096
3098 {
3099 return false;
3100 }
3101
3102
3104 {
3105 return false;
3106 }
3107
3108
3109
3111 {
3112 return true;
3113 }
3114
3116 {
3117 return true;
3118 }
3119
3122 {
3123 return false;
3124 }
3125
3126
3128 {
3129 return true;
3130 }
3131
3132
3134 {
3135 return false;
3136 }
3137
3138
3140 {
3141 return true;
3142 }
3143
3144
3146 {
3147 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3148 {
3149 return false;
3150 }
3151
3152 return true;
3153 }
3154
3156 {
3159
3160 return item;
3161 }
3162
3163
3165 {
3167 {
3168
3170
3171
3174
3176 if ( MemoryPointExists( slot_name + "_min" ) )
3177 {
3178 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3179 }
3180 if ( MemoryPointExists( slot_name + "_max" ) )
3181 {
3182 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3183 }
3184
3185
3188
3189
3192 center = ModelToWorld( center );
3193
3194
3197
3198 areaDamage.SetExtents( extents[0], extents[1] );
3199 areaDamage.SetAreaPosition( center );
3200 areaDamage.SetAreaOrientation( orientation );
3203 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3204 areaDamage.SetAmmoName( "BarbedWireHit" );
3205 areaDamage.Spawn();
3206
3208 }
3209 }
3210
3212 {
3213 if ( angle_deg != 0 )
3214 {
3215
3216 orientation[0] = orientation[0] - angle_deg;
3217
3218
3220 if ( MemoryPointExists( "rotate_axis" ) )
3221 {
3222 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3223 }
3224 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];
3225 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];
3226 center[0] = r_center_x;
3227 center[2] = r_center_z;
3228 }
3229 }
3230
3232 {
3234 {
3237 {
3238 if (areaDamage)
3239 {
3240 areaDamage.Destroy();
3241 }
3242
3244 }
3245 }
3246 }
3247
3249 {
3250 return true;
3251 }
3252
3253
3254
3255
3257 {
3259 }
3260
3262 {
3264 }
3265
3267 {
3269 }
3270
3272 {
3274
3275 switch ( material_type )
3276 {
3282 }
3283
3284 return "";
3285 }
3286
3288 {
3290
3291 switch ( material_type )
3292 {
3298 }
3299
3300 return "";
3301 }
3302
3303
3305 {
3307 {
3308
3310 {
3311 SetHealth(slot_name,"Health",item.GetHealth());
3312 }
3313 }
3314 }
3315
3317 {
3318 return 111;
3319 }
3320
3322 {
3323 super.SetActions();
3324
3328 }
3329
3330
3331
3332
3334 {
3335 }
3336
3339 {
3340 return null;
3341 }
3342
3344 {
3346 }
3347
3349 {
3352
3353 Man p;
3354
3355 #ifdef SERVER
3358 if (players.Count())
3359 p = players[0];
3360 #else
3362 #endif
3363
3365 {
3366 bool excluded = false;
3368 if (excludes)
3369 {
3370 foreach (string exclude : excludes)
3371 {
3373 {
3374 excluded = true;
3375 break;
3376 }
3377 }
3378 }
3379
3380 if (!excluded)
3381 {
3383 }
3384 }
3385
3387 }
3388}
3389
3391{
3392#ifdef BSB_DEBUG
3394#else
3395
3396#endif
3397}
3399{
3400#ifdef BSB_DEBUG_SPAM
3402#else
3403
3404#endif
3405}
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.