1639{
1641
1643
1645
1652
1653
1654
1660
1666
1668
1672
1673
1675 {
1677
1678
1679 RegisterNetSyncVariableInt( "m_SyncParts01" );
1680 RegisterNetSyncVariableInt( "m_SyncParts02" );
1681 RegisterNetSyncVariableInt( "m_SyncParts03" );
1682 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1683 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1684 RegisterNetSyncVariableBool( "m_HasBase" );
1685
1686
1687 ConstructionInit();
1688
1689 if (ConfigIsExisting("hybridAttachments"))
1690 {
1693 }
1694 if (ConfigIsExisting("mountables"))
1695 {
1698 }
1699
1701 SetAllowDamage(true);
1702 }
1703
1705 {
1706 return "disableBaseDamage";
1707 }
1708
1710 {
1711 return true;
1712 }
1713
1715 {
1716 return EInventoryIconVisibility.HIDE_VICINITY;
1717 }
1718
1720 {
1721 super.InitItemSounds();
1722
1726
1731 }
1732
1734 {
1735 return "putDown_FenceKit_SoundSet";
1736 }
1737
1739 {
1740 return "Shelter_Site_Build_Loop_SoundSet";
1741 }
1742
1743
1745 {
1747 {
1748 SetSynchDirty();
1749 }
1750 }
1751
1753 {
1755 super.OnVariablesSynchronized();
1756
1758 }
1759
1761 {
1762
1764
1765
1767
1768
1770 }
1771
1772
1774 {
1775
1776 int offset;
1777 int mask;
1778
1779 if ( part_id >= 1 && part_id <= 31 )
1780 {
1781 offset = part_id - 1;
1782 mask = 1 << offset;
1783
1785 }
1786 else if ( part_id >= 32 && part_id <= 62 )
1787 {
1788 offset = ( part_id % 32 );
1789 mask = 1 << offset;
1790
1792 }
1793 else if ( part_id >= 63 && part_id <= 93 )
1794 {
1795 offset = ( part_id % 63 );
1796 mask = 1 << offset;
1797
1799 }
1800 }
1801
1803 {
1804
1805 int offset;
1806 int mask;
1807
1808 if ( part_id >= 1 && part_id <= 31 )
1809 {
1810 offset = part_id - 1;
1811 mask = 1 << offset;
1812
1814 }
1815 else if ( part_id >= 32 && part_id <= 62 )
1816 {
1817 offset = ( part_id % 32 );
1818 mask = 1 << offset;
1819
1821 }
1822 else if ( part_id >= 63 && part_id <= 93 )
1823 {
1824 offset = ( part_id % 63 );
1825 mask = 1 << offset;
1826
1828 }
1829 }
1830
1832 {
1833
1834 int offset;
1835 int mask;
1836
1837 if ( part_id >= 1 && part_id <= 31 )
1838 {
1839 offset = part_id - 1;
1840 mask = 1 << offset;
1841
1843 {
1844 return true;
1845 }
1846 }
1847 else if ( part_id >= 32 && part_id <= 62 )
1848 {
1849 offset = ( part_id % 32 );
1850 mask = 1 << offset;
1851
1853 {
1854 return true;
1855 }
1856 }
1857 else if ( part_id >= 63 && part_id <= 93 )
1858 {
1859 offset = ( part_id % 63 );
1860 mask = 1 << offset;
1861
1863 {
1864 return true;
1865 }
1866 }
1867
1868 return false;
1869 }
1870
1872 {
1875 }
1876
1878 {
1879
1882 }
1883
1885 {
1887 {
1890
1891 switch( build_action_id )
1892 {
1896 }
1897 }
1898 }
1899
1900
1902 {
1904 bool is_base = part.
IsBase();
1907 if ( is_part_built_sync )
1908 {
1910 {
1914
1915 if (is_base)
1916 {
1919 }
1920 }
1921 }
1922 else
1923 {
1925 {
1929
1930 if (is_base)
1931 {
1934 }
1935 }
1936 }
1937
1938
1940 }
1941
1942
1944 {
1947
1948 for ( int i = 0; i < construction_parts.Count(); ++i )
1949 {
1950 string key = construction_parts.GetKey( i );
1953 }
1954
1955
1957 }
1958
1960 {
1963
1964 for ( int i = 0; i < construction_parts.Count(); ++i )
1965 {
1966 string key = construction_parts.GetKey( i );
1968
1969 if ( value.
GetId() ==
id )
1970 {
1971 return value;
1972 }
1973 }
1974
1975 return NULL;
1976 }
1977
1978
1979
1981 {
1983 }
1984
1986 {
1988 }
1989
1991 {
1992 return true;
1993 }
1994
1996 {
1997 return false;
1998 }
1999
2000
2002 {
2005 {
2007 }
2008
2009 return construction_kit;
2010 }
2011
2013 {
2016 {
2018 }
2019 }
2020
2022 {
2024 }
2025
2027 {
2028 return "";
2029 }
2030
2032 {
2034 g_Game.ObjectDelete( construction_kit );
2035 }
2036
2037
2039 {
2041 g_Game.ObjectDelete(
this );
2042 }
2043
2044
2046 {
2047 super.EEDelete(parent);
2048
2050 {
2051 areaDamage.Destroy();
2052 }
2053
2054 }
2055
2057 {
2058 super.OnStoreSave( ctx );
2059
2060
2064
2066 }
2067
2069 {
2070 if ( !super.OnStoreLoad( ctx, version ) )
2071 return false;
2072
2073
2074
2076 {
2078 return false;
2079 }
2081 {
2083 return false;
2084 }
2086 {
2088 return false;
2089 }
2090
2091
2093 {
2095 return false;
2096 }
2097
2098
2099 return true;
2100 }
2101
2103 {
2104 super.AfterStoreLoad();
2105
2107 {
2109 }
2110 }
2111
2113 {
2114
2116
2117
2120
2121
2123 }
2124
2126 {
2127 super.OnCreatePhysics();
2128
2129 ConstructionInit();
2131 }
2132
2134 {
2136 return;
2137
2138 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2139 }
2140
2142 {
2144 {
2146 }
2147
2148 super.EEOnAfterLoad();
2149 }
2150
2152 {
2153 super.EEItemAttached( item, slot_name );
2154
2158 }
2159
2161 {
2162 super.EEItemDetached( item, slot_name );
2163
2166 }
2167
2168 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2169 {
2172
2175 }
2176
2177
2179 {
2180 return true;
2181 }
2182
2183
2184
2186 {
2188
2189
2190 if (construtionPart.
IsBase())
2191 {
2193
2194
2196 }
2197
2198
2200
2201
2203
2204
2206
2208
2210
2211
2213
2214
2216 }
2217
2219 {
2220
2222 }
2223
2224
2226 {
2229
2230
2232
2233
2235
2236
2238
2239
2241
2243
2244
2246
2247
2249
2250
2251 if (construtionPart.
IsBase())
2252 {
2253
2255 }
2256 }
2257
2259 {
2260
2262 }
2263
2264
2265 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2266 {
2269
2270
2272
2273
2275
2276
2278
2279
2281
2283
2284
2286
2287
2289
2290
2291 if (construtionPart.
IsBase())
2292 {
2293
2295 }
2296 }
2297
2299 {
2300
2302 }
2303
2304
2306 {
2308
2311 }
2312
2314 {
2316
2318 {
2320 }
2321 else
2322 {
2324 }
2325
2327 }
2328
2330 {
2332
2334 foreach (
string slotName : attachmentSlots)
2335 {
2337 }
2338
2339
2342 else
2344
2346 }
2347
2349 {
2350 string slotNameMounted = slot_name + "_Mounted";
2351 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2352
2353 if (attachment)
2354 {
2355 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2356 if (barbedWire && barbedWire.IsMounted())
2358 else
2360
2361 if (is_locked)
2362 {
2363 SetAnimationPhase(slotNameMounted, 0);
2364 SetAnimationPhase(slot_name, 1);
2365 }
2366 else
2367 {
2368 SetAnimationPhase(slotNameMounted, 1);
2369 SetAnimationPhase(slot_name, 0);
2370 }
2371 }
2372 else
2373 {
2374 SetAnimationPhase(slotNameMounted, 1);
2375 SetAnimationPhase(slot_name, 1);
2376
2378 }
2379 }
2380
2381
2383 {
2386
2389
2392
2393 foreach (
string slotName : attachmentSlots)
2394 {
2396 }
2397
2398
2400 {
2403
2405 }
2406 else
2407 {
2410
2412 }
2413
2416 }
2417
2419 {
2420
2422 return;
2423
2424 string slot_name_mounted = slot_name + "_Mounted";
2425 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2426
2427
2429 RemoveProxyPhysics( slot_name_mounted );
2430 RemoveProxyPhysics( slot_name );
2431
2432 if ( attachment )
2433 {
2435 if ( is_locked )
2436 {
2438 AddProxyPhysics( slot_name_mounted );
2439 }
2440 else
2441 {
2443 AddProxyPhysics( slot_name );
2444 }
2445 }
2446 }
2447
2449 {
2450 SetAffectPathgraph( true, false );
2452 }
2453
2455 {
2456 return true;
2457 }
2458
2460 {
2461 return true;
2462 }
2463
2465 {
2466 if ( attachment )
2467 {
2469 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2470
2471 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2472 }
2473
2474 return false;
2475 }
2476
2478 {
2480 }
2481
2482
2484 {
2485 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2486 if (
g_Game.ConfigIsExisting( config_path ) )
2487 {
2488 g_Game.ConfigGetTextArray( config_path, attachment_slots );
2489 }
2490 }
2491
2493 {
2494 return true;
2495 }
2496
2498 {
2499 return true;
2500 }
2501
2503 {
2504 return true;
2505 }
2506
2507
2509 {
2512 }
2513
2515 {
2517 }
2518
2520 {
2522 }
2523
2525 {
2526 int attachment_count = GetInventory().AttachmentCount();
2527 if ( attachment_count > 0 )
2528 {
2529 if (
HasBase() && attachment_count == 1 )
2530 {
2531 return false;
2532 }
2533
2534 return true;
2535 }
2536
2537 return false;
2538 }
2539
2541 {
2542 return true;
2543 }
2544
2546 {
2547 return false;
2548 }
2549
2550
2552 {
2553 return false;
2554 }
2555
2557 {
2558 return false;
2559 }
2560
2561
2563 {
2564 return false;
2565 }
2566
2567
2568
2570 {
2571 return true;
2572 }
2573
2575 {
2576 return true;
2577 }
2578
2581 {
2582 return false;
2583 }
2584
2585
2587 {
2588 return false;
2589 }
2590
2591
2593 {
2594 return true;
2595 }
2596
2597
2599 {
2600 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2601 {
2602 return false;
2603 }
2604
2605 return true;
2606 }
2607
2609 {
2612
2613 return item;
2614 }
2615
2616
2618 {
2620 {
2621
2623
2624
2627
2629 if ( MemoryPointExists( slot_name + "_min" ) )
2630 {
2631 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2632 }
2633 if ( MemoryPointExists( slot_name + "_max" ) )
2634 {
2635 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2636 }
2637
2638
2641
2642
2645 center = ModelToWorld( center );
2646
2647
2650
2651 areaDamage.SetExtents( extents[0], extents[1] );
2652 areaDamage.SetAreaPosition( center );
2656 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2657 areaDamage.SetAmmoName( "BarbedWireHit" );
2658 areaDamage.Spawn();
2659
2661 }
2662 }
2663
2665 {
2666 if ( angle_deg != 0 )
2667 {
2668
2670
2671
2673 if ( MemoryPointExists( "rotate_axis" ) )
2674 {
2675 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2676 }
2677 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];
2678 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];
2679 center[0] = r_center_x;
2680 center[2] = r_center_z;
2681 }
2682 }
2683
2685 {
2687 {
2690 {
2691 if (areaDamage)
2692 {
2693 areaDamage.Destroy();
2694 }
2695
2697 }
2698 }
2699 }
2700
2702 {
2703 return true;
2704 }
2705
2706
2707
2708
2710 {
2712 }
2713
2715 {
2717 }
2718
2720 {
2722 }
2723
2725 {
2727
2728 switch ( material_type )
2729 {
2735 }
2736
2737 return "";
2738 }
2739
2741 {
2743
2744 switch ( material_type )
2745 {
2751 }
2752
2753 return "";
2754 }
2755
2756
2758 {
2760 {
2761
2763 {
2764 SetHealth(slot_name,"Health",item.GetHealth());
2765 }
2766 }
2767 }
2768
2770 {
2771 return 111;
2772 }
2773
2775 {
2776 super.SetActions();
2777
2781 }
2782
2784 {
2786 if (!construction)
2787 return;
2788
2790 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2791 {
2794 {
2796 }
2797 }
2798 }
2799
2801 {
2803 if (!construction)
2804 return;
2805
2807 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2808 {
2811 {
2812 construction.HandleEntityFalling(part.
GetPartName());
2813 }
2814 }
2815 }
2816
2819 {
2821 return;
2822
2825
2826 if (DestroyOnFall())
2827 {
2829 {
2831 }
2832 else
2833 {
2835 {
2837 }
2839 }
2840 }
2841 }
2842
2844 {
2845 if (HasAnyAttachmentsOrCargo())
2846 {
2849 }
2850 }
2851
2852
2853
2854
2855
2858 {
2859 return null;
2860 }
2861
2863 {
2865 }
2866
2868 {
2871
2872 Man p;
2873
2874 #ifdef SERVER
2876 g_Game.GetWorld().GetPlayerList(players);
2877 if (players.Count())
2878 p = players[0];
2879 #else
2881 #endif
2882
2884 {
2885 bool excluded = false;
2887 if (excludes)
2888 {
2889 foreach (string exclude : excludes)
2890 {
2892 {
2893 excluded = true;
2894 break;
2895 }
2896 }
2897 }
2898
2899 if (!excluded)
2900 {
2902 }
2903 }
2904
2906 }
2907
2909
2911 [
Obsolete(
"handled in the Construction component directly")]
2913 {
2914 }
2915
2916 [
Obsolete(
"handled in the Construction component directly")]
2918 {
2919 }
2920
2921 [
Obsolete(
"obsolete debug method")]
2923 {
2924 }
2925}
2926
2928{
2929#ifdef BSB_DEBUG
2931#else
2932
2933#endif
2934}
2936{
2937#ifdef BSB_DEBUG_SPAM
2939#else
2940
2941#endif
2942}
const int AT_DISMANTLE_PART
const int AT_DESTROY_PART
ref ConstructionBasic m_Construction
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 DropAttachmentAndCargoItems()
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)
ConstructionBasic CreateConstructionComponent()
const string SOUND_DISMANTLE_METAL
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()
override void OnItemFallRebuilding()
@Note for modders: This method and is subject to change!
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 ConstructionBasic GetConstructionBasic()
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)
void HandleFallingForConstructedParts()
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)
void DestroyConstructionKit(ItemBase construction_kit)
void CreateConstructionKitInHands(notnull PlayerBase player)
void ItemFall(vector min, vector max)
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)
void DestroyConstructedParts()
const string SOUND_DISMANTLE_WOOD_STAIRS
const int ECE_PLACE_ON_SURFACE
PlayerSpawnPreset slotName
ConstructionMaterialType
used to guide action sound selection, mostly. Could be also used for particles and stuff,...
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)
static bool GetDisableRefundMaterialsOnFall()
static bool GetDisableDropAttachmentsOnFall()
static bool GetDisableItemFalling()
override void DestroyPartServer(Man player, string part_name, int action_id, bool destroyed_by_connected_part=false)
just declared for module 3 use
Instanced construction part data classes for dynamic data, statics now stored on EntityType level in ...
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
static bool IsBaseBuildingLogEnable()
proto bool Write(void value_out)
proto bool Read(void value_in)
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
override string GetDebugName()
Serializer ParamsReadContext
Serializer ParamsWriteContext
proto void PrintToRPT(void var)
Prints content of variable to RPT file (performance warning - each write means fflush!...
void Obsolete(string msg="")
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
vector GetPosition()
Get the world position of the Effect.
bool Contains(string sample)
Returns true if sample is substring of string.