1629{
1631
1633
1635
1637
1643
1644
1645
1651
1657
1659
1663
1664
1666 {
1668
1669
1670 RegisterNetSyncVariableInt( "m_SyncParts01" );
1671 RegisterNetSyncVariableInt( "m_SyncParts02" );
1672 RegisterNetSyncVariableInt( "m_SyncParts03" );
1673 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1674 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1675 RegisterNetSyncVariableBool( "m_HasBase" );
1676
1677
1679
1680 if (ConfigIsExisting("hybridAttachments"))
1681 {
1684 }
1685 if (ConfigIsExisting("mountables"))
1686 {
1689 }
1690
1692 }
1693
1695 {
1696 super.EEDelete(parent);
1697
1699 {
1700 areaDamage.Destroy();
1701 }
1702
1703 }
1704
1706 {
1707 return "disableBaseDamage";
1708 }
1709
1711 {
1712 return true;
1713 }
1714
1716 {
1717 return EInventoryIconVisibility.HIDE_VICINITY;
1718 }
1719
1721 {
1722 super.InitItemSounds();
1723
1727
1732 }
1733
1735 {
1736 return "putDown_FenceKit_SoundSet";
1737 }
1738
1740 {
1741 return "Shelter_Site_Build_Loop_SoundSet";
1742 }
1743
1744
1746 {
1748 {
1749 SetSynchDirty();
1750 }
1751 }
1752
1754 {
1756 super.OnVariablesSynchronized();
1757
1759 }
1760
1762 {
1763
1765
1766
1768
1769
1771 }
1772
1773
1775 {
1776
1777 int offset;
1778 int mask;
1779
1780 if ( part_id >= 1 && part_id <= 31 )
1781 {
1782 offset = part_id - 1;
1783 mask = 1 << offset;
1784
1786 }
1787 else if ( part_id >= 32 && part_id <= 62 )
1788 {
1789 offset = ( part_id % 32 );
1790 mask = 1 << offset;
1791
1793 }
1794 else if ( part_id >= 63 && part_id <= 93 )
1795 {
1796 offset = ( part_id % 63 );
1797 mask = 1 << offset;
1798
1800 }
1801 }
1802
1804 {
1805
1806 int offset;
1807 int mask;
1808
1809 if ( part_id >= 1 && part_id <= 31 )
1810 {
1811 offset = part_id - 1;
1812 mask = 1 << offset;
1813
1815 }
1816 else if ( part_id >= 32 && part_id <= 62 )
1817 {
1818 offset = ( part_id % 32 );
1819 mask = 1 << offset;
1820
1822 }
1823 else if ( part_id >= 63 && part_id <= 93 )
1824 {
1825 offset = ( part_id % 63 );
1826 mask = 1 << offset;
1827
1829 }
1830 }
1831
1833 {
1834
1835 int offset;
1836 int mask;
1837
1838 if ( part_id >= 1 && part_id <= 31 )
1839 {
1840 offset = part_id - 1;
1841 mask = 1 << offset;
1842
1844 {
1845 return true;
1846 }
1847 }
1848 else if ( part_id >= 32 && part_id <= 62 )
1849 {
1850 offset = ( part_id % 32 );
1851 mask = 1 << offset;
1852
1854 {
1855 return true;
1856 }
1857 }
1858 else if ( part_id >= 63 && part_id <= 93 )
1859 {
1860 offset = ( part_id % 63 );
1861 mask = 1 << offset;
1862
1864 {
1865 return true;
1866 }
1867 }
1868
1869 return false;
1870 }
1871
1873 {
1876 }
1877
1879 {
1880
1883 }
1884
1886 {
1888 {
1891
1892 switch( build_action_id )
1893 {
1897 }
1898 }
1899 }
1900
1901
1903 {
1905 bool is_base = part.
IsBase();
1908 if ( is_part_built_sync )
1909 {
1911 {
1915
1916 if (is_base)
1917 {
1920 }
1921 }
1922 }
1923 else
1924 {
1926 {
1930
1931 if (is_base)
1932 {
1935 }
1936 }
1937 }
1938
1939
1941 }
1942
1943
1945 {
1948
1949 for ( int i = 0; i < construction_parts.Count(); ++i )
1950 {
1951 string key = construction_parts.GetKey( i );
1954 }
1955
1956
1958 }
1959
1961 {
1964
1965 for ( int i = 0; i < construction_parts.Count(); ++i )
1966 {
1967 string key = construction_parts.GetKey( i );
1969
1970 if ( value.
GetId() ==
id )
1971 {
1972 return value;
1973 }
1974 }
1975
1976 return NULL;
1977 }
1978
1979
1980
1982 {
1984 }
1985
1987 {
1989 }
1990
1992 {
1993 return true;
1994 }
1995
1997 {
1998 return false;
1999 }
2000
2001
2003 {
2006 {
2008 }
2009
2010 return construction_kit;
2011 }
2012
2014 {
2017 {
2019 }
2020 }
2021
2023 {
2025 }
2026
2028 {
2029 return "";
2030 }
2031
2033 {
2036 }
2037
2038
2040 {
2043 }
2044
2045
2047 {
2048 super.OnStoreSave( ctx );
2049
2050
2054
2056 }
2057
2059 {
2060 if ( !super.OnStoreLoad( ctx, version ) )
2061 return false;
2062
2063
2064
2066 {
2068 return false;
2069 }
2071 {
2073 return false;
2074 }
2076 {
2078 return false;
2079 }
2080
2081
2083 {
2085 return false;
2086 }
2087
2088
2089 return true;
2090 }
2091
2093 {
2094 super.AfterStoreLoad();
2095
2097 {
2099 }
2100 }
2101
2103 {
2104
2106
2107
2110
2111
2113 }
2114
2116 {
2117 super.OnCreatePhysics();
2120 }
2121
2123 {
2125 return;
2126
2127 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2128
2130 return;
2131
2133 string part_name = zone;
2135
2137 {
2138 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2139
2140 if ( construction_part && construction.IsPartConstructed( part_name ) )
2141 {
2143 construction.DestroyConnectedParts(part_name);
2144 }
2145
2146
2147 if ( part_name.
Contains(
"barbed") )
2148 {
2149 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2150 if (barbed_wire)
2151 barbed_wire.SetMountedState( false );
2152 }
2153 }
2154 }
2155
2157 {
2159 {
2161 }
2162
2163 super.EEOnAfterLoad();
2164 }
2165
2167 {
2168 super.EEInit();
2169
2170
2172
2173
2174 #ifdef DEVELOPER
2176 #endif
2177 }
2178
2180 {
2181 super.EEItemAttached( item, slot_name );
2182
2186 }
2187
2189 {
2190 super.EEItemDetached( item, slot_name );
2191
2194 }
2195
2196 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2197 {
2200
2203 }
2204
2205
2207 {
2208 return true;
2209 }
2210
2211
2212
2214 {
2216
2217
2218 if (construtionPart.
IsBase())
2219 {
2221
2222
2224 }
2225
2226
2228
2229
2231
2232
2234
2236
2238
2239
2241
2242
2244 }
2245
2247 {
2248
2250 }
2251
2252
2254 {
2257
2258
2260
2261
2263
2264
2266
2267
2269
2271
2272
2274
2275
2277
2278
2279 if (construtionPart.
IsBase())
2280 {
2281
2283 }
2284 }
2285
2287 {
2288
2290 }
2291
2292
2293 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2294 {
2297
2298
2300
2301
2303
2304
2306
2307
2309
2311
2312
2314
2315
2317
2318
2319 if (construtionPart.
IsBase())
2320 {
2321
2323 }
2324 }
2325
2327 {
2328
2330 }
2331
2334 {
2335 bool process = false;
2336
2337
2341
2342 if (process)
2343 {
2344 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2345 {
2347 return;
2348 }
2349
2351 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2352 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2353
2354
2356 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2357 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2358 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2359 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2360 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2361 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2362 mins = minTmp;
2363 maxs = maxTmp;
2364
2365 maxs[1] = maxs[1] + 0.35;
2366
2368 }
2369 }
2370
2373 {
2376
2377
2379 foreach (
EntityAI entity : foundEntities)
2380 {
2383 }
2384 }
2385
2386
2388 {
2390
2394 }
2395
2397 {
2399
2401 {
2403 }
2404 else
2405 {
2407 }
2408
2410 }
2411
2413 {
2415
2417 foreach (
string slotName : attachmentSlots)
2418 {
2420 }
2421
2422
2425 else
2427
2429 }
2430
2432 {
2433 string slotNameMounted = slot_name + "_Mounted";
2434 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2435
2436 if (attachment)
2437 {
2438 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2439 if (barbedWire && barbedWire.IsMounted())
2441 else
2443
2444 if (is_locked)
2445 {
2446 SetAnimationPhase(slotNameMounted, 0);
2447 SetAnimationPhase(slot_name, 1);
2448 }
2449 else
2450 {
2451 SetAnimationPhase(slotNameMounted, 1);
2452 SetAnimationPhase(slot_name, 0);
2453 }
2454 }
2455 else
2456 {
2457 SetAnimationPhase(slotNameMounted, 1);
2458 SetAnimationPhase(slot_name, 1);
2459
2461 }
2462 }
2463
2464
2466 {
2469
2472
2475
2476 foreach (
string slotName : attachmentSlots)
2477 {
2479 }
2480
2481
2483 {
2486
2488 }
2489 else
2490 {
2493
2495 }
2496
2499 }
2500
2502 {
2503
2505 return;
2506
2507 string slot_name_mounted = slot_name + "_Mounted";
2508 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2509
2510
2512 RemoveProxyPhysics( slot_name_mounted );
2513 RemoveProxyPhysics( slot_name );
2514
2515 if ( attachment )
2516 {
2518 if ( is_locked )
2519 {
2521 AddProxyPhysics( slot_name_mounted );
2522 }
2523 else
2524 {
2526 AddProxyPhysics( slot_name );
2527 }
2528 }
2529 }
2530
2532 {
2533 SetAffectPathgraph( true, false );
2535 }
2536
2538 {
2539 return true;
2540 }
2541
2543 {
2544 return true;
2545 }
2546
2548 {
2549 if ( attachment )
2550 {
2552 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2553
2554 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2555 }
2556
2557 return false;
2558 }
2559
2561 {
2563 }
2564
2565
2567 {
2568 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2569 if (
GetGame().ConfigIsExisting( config_path ) )
2570 {
2572 }
2573 }
2574
2576 {
2577 return true;
2578 }
2579
2581 {
2582 return true;
2583 }
2584
2586 {
2587 return true;
2588 }
2589
2590
2592 {
2594 {
2596 }
2597
2599 }
2600
2602 {
2604 }
2605
2606
2607
2609 {
2610 return super.CanReceiveAttachment(attachment, slotId);
2611 }
2612
2614 {
2615 int attachment_count = GetInventory().AttachmentCount();
2616 if ( attachment_count > 0 )
2617 {
2618 if (
HasBase() && attachment_count == 1 )
2619 {
2620 return false;
2621 }
2622
2623 return true;
2624 }
2625
2626 return false;
2627 }
2628
2630 {
2631 return true;
2632 }
2633
2635 {
2636 return false;
2637 }
2638
2639
2641 {
2642 return false;
2643 }
2644
2646 {
2647 return false;
2648 }
2649
2650
2652 {
2653 return false;
2654 }
2655
2656
2657
2659 {
2660 return true;
2661 }
2662
2664 {
2665 return true;
2666 }
2667
2670 {
2671 return false;
2672 }
2673
2674
2676 {
2677 return true;
2678 }
2679
2680
2682 {
2683 return false;
2684 }
2685
2686
2688 {
2689 return true;
2690 }
2691
2692
2694 {
2695 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2696 {
2697 return false;
2698 }
2699
2700 return true;
2701 }
2702
2704 {
2707
2708 return item;
2709 }
2710
2711
2713 {
2715 {
2716
2718
2719
2722
2724 if ( MemoryPointExists( slot_name + "_min" ) )
2725 {
2726 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2727 }
2728 if ( MemoryPointExists( slot_name + "_max" ) )
2729 {
2730 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2731 }
2732
2733
2736
2737
2740 center = ModelToWorld( center );
2741
2742
2745
2746 areaDamage.SetExtents( extents[0], extents[1] );
2747 areaDamage.SetAreaPosition( center );
2748 areaDamage.SetAreaOrientation( orientation );
2751 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2752 areaDamage.SetAmmoName( "BarbedWireHit" );
2753 areaDamage.Spawn();
2754
2756 }
2757 }
2758
2760 {
2761 if ( angle_deg != 0 )
2762 {
2763
2764 orientation[0] = orientation[0] - angle_deg;
2765
2766
2768 if ( MemoryPointExists( "rotate_axis" ) )
2769 {
2770 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2771 }
2772 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];
2773 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];
2774 center[0] = r_center_x;
2775 center[2] = r_center_z;
2776 }
2777 }
2778
2780 {
2782 {
2785 {
2786 if (areaDamage)
2787 {
2788 areaDamage.Destroy();
2789 }
2790
2792 }
2793 }
2794 }
2795
2797 {
2798 return true;
2799 }
2800
2801
2802
2803
2805 {
2807 }
2808
2810 {
2812 }
2813
2815 {
2817 }
2818
2820 {
2822
2823 switch ( material_type )
2824 {
2830 }
2831
2832 return "";
2833 }
2834
2836 {
2838
2839 switch ( material_type )
2840 {
2846 }
2847
2848 return "";
2849 }
2850
2851
2853 {
2855 {
2856
2858 {
2859 SetHealth(slot_name,"Health",item.GetHealth());
2860 }
2861 }
2862 }
2863
2865 {
2866 return 111;
2867 }
2868
2870 {
2871 super.SetActions();
2872
2876 }
2877
2878
2879
2880
2882 {
2883 }
2884
2887 {
2888 return null;
2889 }
2890
2892 {
2894 }
2895
2897 {
2900
2901 Man p;
2902
2903 #ifdef SERVER
2906 if (players.Count())
2907 p = players[0];
2908 #else
2910 #endif
2911
2913 {
2914 bool excluded = false;
2916 if (excludes)
2917 {
2918 foreach (string exclude : excludes)
2919 {
2921 {
2922 excluded = true;
2923 break;
2924 }
2925 }
2926 }
2927
2928 if (!excluded)
2929 {
2931 }
2932 }
2933
2935 }
2936}
2937
2939{
2940#ifdef BSB_DEBUG
2942#else
2943
2944#endif
2945}
2947{
2948#ifdef BSB_DEBUG_SPAM
2950#else
2951
2952#endif
2953}
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.