1587{
1589
1591
1593
1595
1601
1602
1603
1609
1615
1617
1621
1622
1624 {
1626
1627
1628 RegisterNetSyncVariableInt( "m_SyncParts01" );
1629 RegisterNetSyncVariableInt( "m_SyncParts02" );
1630 RegisterNetSyncVariableInt( "m_SyncParts03" );
1631 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1632 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1633 RegisterNetSyncVariableBool( "m_HasBase" );
1634
1635
1637
1638 if (ConfigIsExisting("hybridAttachments"))
1639 {
1642 }
1643 if (ConfigIsExisting("mountables"))
1644 {
1647 }
1648
1650 }
1651
1653 {
1654 super.EEDelete(parent);
1655
1657 {
1658 areaDamage.Destroy();
1659 }
1660
1661 }
1662
1664 {
1665 return "disableBaseDamage";
1666 }
1667
1669 {
1670 return true;
1671 }
1672
1674 {
1675 return EInventoryIconVisibility.HIDE_VICINITY;
1676 }
1677
1679 {
1680 super.InitItemSounds();
1681
1685
1690 }
1691
1693 {
1694 return "putDown_FenceKit_SoundSet";
1695 }
1696
1698 {
1699 return "Shelter_Site_Build_Loop_SoundSet";
1700 }
1701
1702
1704 {
1706 {
1707 SetSynchDirty();
1708 }
1709 }
1710
1712 {
1714 super.OnVariablesSynchronized();
1715
1717 }
1718
1720 {
1721
1723
1724
1726
1727
1729 }
1730
1731
1733 {
1734
1735 int offset;
1736 int mask;
1737
1738 if ( part_id >= 1 && part_id <= 31 )
1739 {
1740 offset = part_id - 1;
1741 mask = 1 << offset;
1742
1744 }
1745 else if ( part_id >= 32 && part_id <= 62 )
1746 {
1747 offset = ( part_id % 32 );
1748 mask = 1 << offset;
1749
1751 }
1752 else if ( part_id >= 63 && part_id <= 93 )
1753 {
1754 offset = ( part_id % 63 );
1755 mask = 1 << offset;
1756
1758 }
1759 }
1760
1762 {
1763
1764 int offset;
1765 int mask;
1766
1767 if ( part_id >= 1 && part_id <= 31 )
1768 {
1769 offset = part_id - 1;
1770 mask = 1 << offset;
1771
1773 }
1774 else if ( part_id >= 32 && part_id <= 62 )
1775 {
1776 offset = ( part_id % 32 );
1777 mask = 1 << offset;
1778
1780 }
1781 else if ( part_id >= 63 && part_id <= 93 )
1782 {
1783 offset = ( part_id % 63 );
1784 mask = 1 << offset;
1785
1787 }
1788 }
1789
1791 {
1792
1793 int offset;
1794 int mask;
1795
1796 if ( part_id >= 1 && part_id <= 31 )
1797 {
1798 offset = part_id - 1;
1799 mask = 1 << offset;
1800
1802 {
1803 return true;
1804 }
1805 }
1806 else if ( part_id >= 32 && part_id <= 62 )
1807 {
1808 offset = ( part_id % 32 );
1809 mask = 1 << offset;
1810
1812 {
1813 return true;
1814 }
1815 }
1816 else if ( part_id >= 63 && part_id <= 93 )
1817 {
1818 offset = ( part_id % 63 );
1819 mask = 1 << offset;
1820
1822 {
1823 return true;
1824 }
1825 }
1826
1827 return false;
1828 }
1829
1831 {
1834 }
1835
1837 {
1838
1841 }
1842
1844 {
1846 {
1849
1850 switch( build_action_id )
1851 {
1855 }
1856 }
1857 }
1858
1859
1861 {
1863 bool is_base = part.
IsBase();
1866 if ( is_part_built_sync )
1867 {
1869 {
1873
1874 if (is_base)
1875 {
1878 }
1879 }
1880 }
1881 else
1882 {
1884 {
1888
1889 if (is_base)
1890 {
1893 }
1894 }
1895 }
1896
1897
1899 }
1900
1901
1903 {
1906
1907 for ( int i = 0; i < construction_parts.Count(); ++i )
1908 {
1909 string key = construction_parts.GetKey( i );
1912 }
1913
1914
1916 }
1917
1919 {
1922
1923 for ( int i = 0; i < construction_parts.Count(); ++i )
1924 {
1925 string key = construction_parts.GetKey( i );
1927
1928 if ( value.
GetId() ==
id )
1929 {
1930 return value;
1931 }
1932 }
1933
1934 return NULL;
1935 }
1936
1937
1938
1940 {
1942 }
1943
1945 {
1947 }
1948
1950 {
1951 return true;
1952 }
1953
1955 {
1956 return false;
1957 }
1958
1959
1961 {
1964 {
1966 }
1967
1968 return construction_kit;
1969 }
1970
1972 {
1975 {
1977 }
1978 }
1979
1981 {
1983 }
1984
1986 {
1987 return "";
1988 }
1989
1991 {
1994 }
1995
1996
1998 {
2001 }
2002
2003
2005 {
2006 super.OnStoreSave( ctx );
2007
2008
2012
2014 }
2015
2017 {
2018 if ( !super.OnStoreLoad( ctx, version ) )
2019 return false;
2020
2021
2022
2024 {
2026 return false;
2027 }
2029 {
2031 return false;
2032 }
2034 {
2036 return false;
2037 }
2038
2039
2041 {
2043 return false;
2044 }
2045
2046
2047 return true;
2048 }
2049
2051 {
2052 super.AfterStoreLoad();
2053
2055 {
2057 }
2058 }
2059
2061 {
2062
2064
2065
2068
2069
2071 }
2072
2074 {
2075 super.OnCreatePhysics();
2078 }
2079
2081 {
2083 return;
2084
2085 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2086
2088 return;
2089
2091 string part_name = zone;
2093
2095 {
2096 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
2097
2098 if ( construction_part && construction.IsPartConstructed( part_name ) )
2099 {
2101 construction.DestroyConnectedParts(part_name);
2102 }
2103
2104
2105 if ( part_name.
Contains(
"barbed") )
2106 {
2107 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
2108 if (barbed_wire)
2109 barbed_wire.SetMountedState( false );
2110 }
2111 }
2112 }
2113
2115 {
2117 {
2119 }
2120
2121 super.EEOnAfterLoad();
2122 }
2123
2125 {
2126 super.EEInit();
2127
2128
2130
2131
2132 #ifdef DEVELOPER
2134 #endif
2135 }
2136
2138 {
2139 super.EEItemAttached( item, slot_name );
2140
2144 }
2145
2147 {
2148 super.EEItemDetached( item, slot_name );
2149
2152 }
2153
2154 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2155 {
2158
2161 }
2162
2163
2165 {
2166 return true;
2167 }
2168
2169
2170
2172 {
2174
2175
2176 if (construtionPart.
IsBase())
2177 {
2179
2180
2182 }
2183
2184
2186
2187
2189
2190
2192
2194
2196
2197
2199
2200
2202 }
2203
2205 {
2206
2208 }
2209
2210
2212 {
2215
2216
2218
2219
2221
2222
2224
2225
2227
2229
2230
2232
2233
2235
2236
2237 if (construtionPart.
IsBase())
2238 {
2239
2241 }
2242 }
2243
2245 {
2246
2248 }
2249
2250
2251 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2252 {
2255
2256
2258
2259
2261
2262
2264
2265
2267
2269
2270
2272
2273
2275
2276
2277 if (construtionPart.
IsBase())
2278 {
2279
2281 }
2282 }
2283
2285 {
2286
2288 }
2289
2292 {
2293 bool process = false;
2294
2295
2299
2300 if (process)
2301 {
2302 if (!MemoryPointExists(part.
m_PartName +
"_min") || !MemoryPointExists(part.
m_PartName +
"_max"))
2303 {
2305 return;
2306 }
2307
2309 mins = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_min"));
2310 maxs = ModelToWorld(GetMemoryPointPos(part.
m_PartName +
"_max"));
2311
2312
2314 minTmp[0] =
Math.
Min(mins[0],maxs[0]);
2315 maxTmp[0] =
Math.
Max(mins[0],maxs[0]);
2316 minTmp[1] =
Math.
Min(mins[1],maxs[1]);
2317 maxTmp[1] =
Math.
Max(mins[1],maxs[1]);
2318 minTmp[2] =
Math.
Min(mins[2],maxs[2]);
2319 maxTmp[2] =
Math.
Max(mins[2],maxs[2]);
2320 mins = minTmp;
2321 maxs = maxTmp;
2322
2323 maxs[1] = maxs[1] + 0.35;
2324
2326 }
2327 }
2328
2331 {
2334
2335
2337 foreach (
EntityAI entity : foundEntities)
2338 {
2341 }
2342 }
2343
2344
2346 {
2348
2352 }
2353
2355 {
2357
2359 {
2361 }
2362 else
2363 {
2365 }
2366
2368 }
2369
2371 {
2373
2375 foreach (
string slotName : attachmentSlots)
2376 {
2378 }
2379
2380
2383 else
2385
2387 }
2388
2390 {
2391 string slotNameMounted = slot_name + "_Mounted";
2392 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2393
2394 if (attachment)
2395 {
2396 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2397 if (barbedWire && barbedWire.IsMounted())
2399 else
2401
2402 if (is_locked)
2403 {
2404 SetAnimationPhase(slotNameMounted, 0);
2405 SetAnimationPhase(slot_name, 1);
2406 }
2407 else
2408 {
2409 SetAnimationPhase(slotNameMounted, 1);
2410 SetAnimationPhase(slot_name, 0);
2411 }
2412 }
2413 else
2414 {
2415 SetAnimationPhase(slotNameMounted, 1);
2416 SetAnimationPhase(slot_name, 1);
2417
2419 }
2420 }
2421
2422
2424 {
2427
2430
2433
2434 foreach (
string slotName : attachmentSlots)
2435 {
2437 }
2438
2439
2441 {
2444
2446 }
2447 else
2448 {
2451
2453 }
2454
2457 }
2458
2460 {
2461
2463 return;
2464
2465 string slot_name_mounted = slot_name + "_Mounted";
2466 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2467
2468
2470 RemoveProxyPhysics( slot_name_mounted );
2471 RemoveProxyPhysics( slot_name );
2472
2473 if ( attachment )
2474 {
2476 if ( is_locked )
2477 {
2479 AddProxyPhysics( slot_name_mounted );
2480 }
2481 else
2482 {
2484 AddProxyPhysics( slot_name );
2485 }
2486 }
2487 }
2488
2490 {
2491 SetAffectPathgraph( true, false );
2493 }
2494
2496 {
2497 return true;
2498 }
2499
2501 {
2502 return true;
2503 }
2504
2506 {
2507 if ( attachment )
2508 {
2510 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2511
2512 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2513 }
2514
2515 return false;
2516 }
2517
2519 {
2521 }
2522
2523
2525 {
2526 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2527 if (
GetGame().ConfigIsExisting( config_path ) )
2528 {
2530 }
2531 }
2532
2534 {
2535 return true;
2536 }
2537
2539 {
2540 return true;
2541 }
2542
2544 {
2545 return true;
2546 }
2547
2548
2550 {
2552 {
2554 }
2555
2557 }
2558
2560 {
2562 }
2563
2564
2565
2567 {
2568 return super.CanReceiveAttachment(attachment, slotId);
2569 }
2570
2572 {
2573 int attachment_count = GetInventory().AttachmentCount();
2574 if ( attachment_count > 0 )
2575 {
2576 if (
HasBase() && attachment_count == 1 )
2577 {
2578 return false;
2579 }
2580
2581 return true;
2582 }
2583
2584 return false;
2585 }
2586
2588 {
2589 return true;
2590 }
2591
2593 {
2594 return false;
2595 }
2596
2597
2599 {
2600 return false;
2601 }
2602
2604 {
2605 return false;
2606 }
2607
2608
2610 {
2611 return false;
2612 }
2613
2614
2615
2617 {
2618 return true;
2619 }
2620
2622 {
2623 return true;
2624 }
2625
2628 {
2629 return false;
2630 }
2631
2632
2634 {
2635 return true;
2636 }
2637
2638
2640 {
2641 return false;
2642 }
2643
2644
2646 {
2647 return true;
2648 }
2649
2650
2652 {
2653 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2654 {
2655 return false;
2656 }
2657
2658 return true;
2659 }
2660
2662 {
2665
2666 return item;
2667 }
2668
2669
2671 {
2673 {
2674
2676
2677
2680
2682 if ( MemoryPointExists( slot_name + "_min" ) )
2683 {
2684 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2685 }
2686 if ( MemoryPointExists( slot_name + "_max" ) )
2687 {
2688 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2689 }
2690
2691
2694
2695
2698 center = ModelToWorld( center );
2699
2700
2703
2704 areaDamage.SetExtents( extents[0], extents[1] );
2705 areaDamage.SetAreaPosition( center );
2706 areaDamage.SetAreaOrientation( orientation );
2709 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2710 areaDamage.SetAmmoName( "BarbedWireHit" );
2711 areaDamage.Spawn();
2712
2714 }
2715 }
2716
2718 {
2719 if ( angle_deg != 0 )
2720 {
2721
2722 orientation[0] = orientation[0] - angle_deg;
2723
2724
2726 if ( MemoryPointExists( "rotate_axis" ) )
2727 {
2728 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2729 }
2730 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];
2731 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];
2732 center[0] = r_center_x;
2733 center[2] = r_center_z;
2734 }
2735 }
2736
2738 {
2740 {
2743 {
2744 if (areaDamage)
2745 {
2746 areaDamage.Destroy();
2747 }
2748
2750 }
2751 }
2752 }
2753
2755 {
2756 return true;
2757 }
2758
2759
2760
2761
2763 {
2765 }
2766
2768 {
2770 }
2771
2773 {
2775 }
2776
2778 {
2780
2781 switch ( material_type )
2782 {
2788 }
2789
2790 return "";
2791 }
2792
2794 {
2796
2797 switch ( material_type )
2798 {
2804 }
2805
2806 return "";
2807 }
2808
2809
2811 {
2813 {
2814
2816 {
2817 SetHealth(slot_name,"Health",item.GetHealth());
2818 }
2819 }
2820 }
2821
2823 {
2824 return 111;
2825 }
2826
2828 {
2829 super.SetActions();
2830
2834 }
2835
2836
2837
2838
2840 {
2841 }
2842
2845 {
2846 return null;
2847 }
2848
2850 {
2852 }
2853
2855 {
2858
2859 Man p;
2860
2861 #ifdef SERVER
2864 if (players.Count())
2865 p = players[0];
2866 #else
2868 #endif
2869
2871 {
2872 bool excluded = false;
2874 if (excludes)
2875 {
2876 foreach (string exclude : excludes)
2877 {
2879 {
2880 excluded = true;
2881 break;
2882 }
2883 }
2884 }
2885
2886 if (!excluded)
2887 {
2889 }
2890 }
2891
2893 }
2894}
2895
2897{
2898#ifdef BSB_DEBUG
2900#else
2901
2902#endif
2903}
2905{
2906#ifdef BSB_DEBUG_SPAM
2908#else
2909
2910#endif
2911}
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.