1666{
1668
1670
1672
1679
1680
1681
1687
1693
1695
1699
1700
1702 {
1704
1705
1706 RegisterNetSyncVariableInt( "m_SyncParts01" );
1707 RegisterNetSyncVariableInt( "m_SyncParts02" );
1708 RegisterNetSyncVariableInt( "m_SyncParts03" );
1709 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1710 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1711 RegisterNetSyncVariableBool( "m_HasBase" );
1712
1713
1714 ConstructionInit();
1715
1716 if (ConfigIsExisting("hybridAttachments"))
1717 {
1720 }
1721 if (ConfigIsExisting("mountables"))
1722 {
1725 }
1726
1728 SetAllowDamage(true);
1729 }
1730
1732 {
1733 return "disableBaseDamage";
1734 }
1735
1737 {
1738 return true;
1739 }
1740
1742 {
1743 return EInventoryIconVisibility.HIDE_VICINITY;
1744 }
1745
1747 {
1748 super.InitItemSounds();
1749
1753
1758 }
1759
1761 {
1762 return "putDown_FenceKit_SoundSet";
1763 }
1764
1766 {
1767 return "Shelter_Site_Build_Loop_SoundSet";
1768 }
1769
1770
1772 {
1774 {
1775 SetSynchDirty();
1776 }
1777 }
1778
1780 {
1782 super.OnVariablesSynchronized();
1783
1785 }
1786
1788 {
1789
1791
1792
1794
1795
1797 }
1798
1799
1801 {
1802
1803 int offset;
1804 int mask;
1805
1806 if ( part_id >= 1 && part_id <= 31 )
1807 {
1808 offset = part_id - 1;
1809 mask = 1 << offset;
1810
1812 }
1813 else if ( part_id >= 32 && part_id <= 62 )
1814 {
1815 offset = ( part_id % 32 );
1816 mask = 1 << offset;
1817
1819 }
1820 else if ( part_id >= 63 && part_id <= 93 )
1821 {
1822 offset = ( part_id % 63 );
1823 mask = 1 << offset;
1824
1826 }
1827 }
1828
1830 {
1831
1832 int offset;
1833 int mask;
1834
1835 if ( part_id >= 1 && part_id <= 31 )
1836 {
1837 offset = part_id - 1;
1838 mask = 1 << offset;
1839
1841 }
1842 else if ( part_id >= 32 && part_id <= 62 )
1843 {
1844 offset = ( part_id % 32 );
1845 mask = 1 << offset;
1846
1848 }
1849 else if ( part_id >= 63 && part_id <= 93 )
1850 {
1851 offset = ( part_id % 63 );
1852 mask = 1 << offset;
1853
1855 }
1856 }
1857
1859 {
1860
1861 int offset;
1862 int mask;
1863
1864 if ( part_id >= 1 && part_id <= 31 )
1865 {
1866 offset = part_id - 1;
1867 mask = 1 << offset;
1868
1870 {
1871 return true;
1872 }
1873 }
1874 else if ( part_id >= 32 && part_id <= 62 )
1875 {
1876 offset = ( part_id % 32 );
1877 mask = 1 << offset;
1878
1880 {
1881 return true;
1882 }
1883 }
1884 else if ( part_id >= 63 && part_id <= 93 )
1885 {
1886 offset = ( part_id % 63 );
1887 mask = 1 << offset;
1888
1890 {
1891 return true;
1892 }
1893 }
1894
1895 return false;
1896 }
1897
1899 {
1902 }
1903
1905 {
1906
1909 }
1910
1912 {
1914 {
1917
1918 switch( build_action_id )
1919 {
1923 }
1924 }
1925 }
1926
1927
1929 {
1931 bool is_base = part.
IsBase();
1934 if ( is_part_built_sync )
1935 {
1937 {
1941
1942 if (is_base)
1943 {
1946 }
1947 }
1948 }
1949 else
1950 {
1952 {
1956
1957 if (is_base)
1958 {
1961 }
1962 }
1963 }
1964
1965
1967 }
1968
1969
1971 {
1974
1975 for ( int i = 0; i < construction_parts.Count(); ++i )
1976 {
1977 string key = construction_parts.GetKey( i );
1980 }
1981
1982
1984 }
1985
1987 {
1990
1991 for ( int i = 0; i < construction_parts.Count(); ++i )
1992 {
1993 string key = construction_parts.GetKey( i );
1995
1996 if ( value.
GetId() ==
id )
1997 {
1998 return value;
1999 }
2000 }
2001
2002 return NULL;
2003 }
2004
2005
2006
2008 {
2010 }
2011
2013 {
2015 }
2016
2018 {
2019 return true;
2020 }
2021
2023 {
2024 return false;
2025 }
2026
2027
2029 {
2032 {
2034 }
2035
2036 return construction_kit;
2037 }
2038
2040 {
2043 {
2045 }
2046 }
2047
2049 {
2051 }
2052
2054 {
2055 return "";
2056 }
2057
2059 {
2061 g_Game.ObjectDelete( construction_kit );
2062 }
2063
2064
2066 {
2068 g_Game.ObjectDelete(
this );
2069 }
2070
2071
2073 {
2074 super.EEDelete(parent);
2075
2077 {
2078 areaDamage.Destroy();
2079 }
2080
2081 }
2082
2084 {
2085 super.OnStoreSave( ctx );
2086
2087
2091
2093 }
2094
2096 {
2097 if ( !super.OnStoreLoad( ctx, version ) )
2098 return false;
2099
2100
2101
2103 {
2105 return false;
2106 }
2108 {
2110 return false;
2111 }
2113 {
2115 return false;
2116 }
2117
2118
2120 {
2122 return false;
2123 }
2124
2125
2126 return true;
2127 }
2128
2130 {
2131 super.AfterStoreLoad();
2132
2134 {
2136 }
2137 }
2138
2140 {
2141
2143
2144
2147
2148
2150 }
2151
2153 {
2154 super.OnCreatePhysics();
2155
2156 ConstructionInit();
2158 }
2159
2161 {
2163 return;
2164
2165 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2166 }
2167
2169 {
2171 {
2173 }
2174
2175 super.EEOnAfterLoad();
2176 }
2177
2179 {
2180 super.EEItemAttached( item, slot_name );
2181
2185 }
2186
2188 {
2189 super.EEItemDetached( item, slot_name );
2190
2193 }
2194
2195 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2196 {
2199
2202 }
2203
2204
2206 {
2207 return true;
2208 }
2209
2210
2211
2213 {
2215
2216
2217 if (construtionPart.
IsBase())
2218 {
2220
2221
2223 }
2224
2225
2227
2228
2230
2231
2233
2235
2237
2238
2240
2241
2243 }
2244
2246 {
2247
2249 }
2250
2251
2253 {
2256
2257
2259
2260
2262
2263
2265
2266
2268
2270
2271
2273
2274
2276
2277
2278 if (construtionPart.
IsBase())
2279 {
2280
2282 }
2283 }
2284
2286 {
2287
2289 }
2290
2291
2292 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2293 {
2296
2297
2299
2300
2302
2303
2305
2306
2308
2310
2311
2313
2314
2316
2317
2318 if (construtionPart.
IsBase())
2319 {
2320
2322 }
2323 }
2324
2326 {
2327
2329 }
2330
2331
2333 {
2335
2338 }
2339
2341 {
2343
2345 {
2347 }
2348 else
2349 {
2351 }
2352
2354 }
2355
2357 {
2359
2361 foreach (
string slotName : attachmentSlots)
2362 {
2364 }
2365
2366
2369 else
2371
2373 }
2374
2376 {
2377 string slotNameMounted = slot_name + "_Mounted";
2378 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2379
2380 if (attachment)
2381 {
2382 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2383 if (barbedWire && barbedWire.IsMounted())
2385 else
2387
2388 if (is_locked)
2389 {
2390 SetAnimationPhase(slotNameMounted, 0);
2391 SetAnimationPhase(slot_name, 1);
2392 }
2393 else
2394 {
2395 SetAnimationPhase(slotNameMounted, 1);
2396 SetAnimationPhase(slot_name, 0);
2397 }
2398 }
2399 else
2400 {
2401 SetAnimationPhase(slotNameMounted, 1);
2402 SetAnimationPhase(slot_name, 1);
2403
2405 }
2406 }
2407
2408
2410 {
2413
2416
2419
2420 foreach (
string slotName : attachmentSlots)
2421 {
2423 }
2424
2425
2427 {
2430
2432 }
2433 else
2434 {
2437
2439 }
2440
2443 }
2444
2446 {
2447
2449 return;
2450
2451 string slot_name_mounted = slot_name + "_Mounted";
2452 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2453
2454
2456 RemoveProxyPhysics( slot_name_mounted );
2457 RemoveProxyPhysics( slot_name );
2458
2459 if ( attachment )
2460 {
2462 if ( is_locked )
2463 {
2465 AddProxyPhysics( slot_name_mounted );
2466 }
2467 else
2468 {
2470 AddProxyPhysics( slot_name );
2471 }
2472 }
2473 }
2474
2476 {
2477 SetAffectPathgraph( true, false );
2479 }
2480
2482 {
2483 return true;
2484 }
2485
2487 {
2488 return true;
2489 }
2490
2492 {
2493 if ( attachment )
2494 {
2496 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2497
2498 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2499 }
2500
2501 return false;
2502 }
2503
2505 {
2507 }
2508
2509
2511 {
2512 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2513 if (
g_Game.ConfigIsExisting( config_path ) )
2514 {
2515 g_Game.ConfigGetTextArray( config_path, attachment_slots );
2516 }
2517 }
2518
2520 {
2521 return true;
2522 }
2523
2525 {
2526 return true;
2527 }
2528
2530 {
2531 return true;
2532 }
2533
2534
2536 {
2539 }
2540
2542 {
2544 }
2545
2547 {
2549 }
2550
2552 {
2553 int attachment_count = GetInventory().AttachmentCount();
2554 if ( attachment_count > 0 )
2555 {
2556 if (
HasBase() && attachment_count == 1 )
2557 {
2558 return false;
2559 }
2560
2561 return true;
2562 }
2563
2564 return false;
2565 }
2566
2568 {
2569 return true;
2570 }
2571
2573 {
2574 return false;
2575 }
2576
2577
2579 {
2580 return false;
2581 }
2582
2584 {
2585 return false;
2586 }
2587
2588
2590 {
2591 return false;
2592 }
2593
2594
2595
2597 {
2598 return true;
2599 }
2600
2602 {
2603 return true;
2604 }
2605
2608 {
2609 return false;
2610 }
2611
2612
2614 {
2615 return false;
2616 }
2617
2618
2620 {
2621 return true;
2622 }
2623
2624
2626 {
2627 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2628 {
2629 return false;
2630 }
2631
2632 return true;
2633 }
2634
2636 {
2639
2640 return item;
2641 }
2642
2643
2645 {
2647 {
2648
2650
2651
2654
2656 if ( MemoryPointExists( slot_name + "_min" ) )
2657 {
2658 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2659 }
2660 if ( MemoryPointExists( slot_name + "_max" ) )
2661 {
2662 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2663 }
2664
2665
2668
2669
2672 center = ModelToWorld( center );
2673
2674
2677
2678 areaDamage.SetExtents( extents[0], extents[1] );
2679 areaDamage.SetAreaPosition( center );
2683 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2684 areaDamage.SetAmmoName( "BarbedWireHit" );
2685 areaDamage.Spawn();
2686
2688 }
2689 }
2690
2692 {
2693 if ( angle_deg != 0 )
2694 {
2695
2697
2698
2700 if ( MemoryPointExists( "rotate_axis" ) )
2701 {
2702 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2703 }
2704 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];
2705 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];
2706 center[0] = r_center_x;
2707 center[2] = r_center_z;
2708 }
2709 }
2710
2712 {
2714 {
2717 {
2718 if (areaDamage)
2719 {
2720 areaDamage.Destroy();
2721 }
2722
2724 }
2725 }
2726 }
2727
2729 {
2730 return true;
2731 }
2732
2733
2734
2735
2737 {
2739 }
2740
2742 {
2744 }
2745
2747 {
2749 }
2750
2752 {
2754
2755 switch ( material_type )
2756 {
2762 }
2763
2764 return "";
2765 }
2766
2768 {
2770
2771 switch ( material_type )
2772 {
2778 }
2779
2780 return "";
2781 }
2782
2783
2785 {
2787 {
2788
2790 {
2791 SetHealth(slot_name,"Health",item.GetHealth());
2792 }
2793 }
2794 }
2795
2797 {
2798 return 111;
2799 }
2800
2802 {
2803 super.SetActions();
2804
2808 }
2809
2811 {
2813 if (!construction)
2814 return;
2815
2817 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2818 {
2821 {
2823 }
2824 }
2825 }
2826
2828 {
2830 if (!construction)
2831 return;
2832
2834 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2835 {
2838 {
2839 construction.HandleEntityFalling(part.
GetPartName());
2840 }
2841 }
2842 }
2843
2846 {
2848 return;
2849
2852
2853 if (DestroyOnFall())
2854 {
2856 {
2858 }
2859 else
2860 {
2862 {
2864 }
2866 }
2867 }
2868 }
2869
2871 {
2872 if (HasAnyAttachmentsOrCargo())
2873 {
2876 }
2877 }
2878
2879
2880
2881
2882
2885 {
2886 return null;
2887 }
2888
2890 {
2892 }
2893
2895 {
2898
2899 Man p;
2900
2901 #ifdef SERVER
2903 g_Game.GetWorld().GetPlayerList(players);
2904 if (players.Count())
2905 p = players[0];
2906 #else
2908 #endif
2909
2911 {
2912 bool excluded = false;
2914 if (excludes)
2915 {
2916 foreach (string exclude : excludes)
2917 {
2919 {
2920 excluded = true;
2921 break;
2922 }
2923 }
2924 }
2925
2926 if (!excluded)
2927 {
2929 }
2930 }
2931
2933 }
2934
2936
2938 [
Obsolete(
"handled in the Construction component directly")]
2940 {
2941 }
2942
2943 [
Obsolete(
"handled in the Construction component directly")]
2945 {
2946 }
2947
2948 [
Obsolete(
"obsolete debug method")]
2950 {
2951 }
2952}
2953
2955{
2956#ifdef BSB_DEBUG
2958#else
2959
2960#endif
2961}
2963{
2964#ifdef BSB_DEBUG_SPAM
2966#else
2967
2968#endif
2969}
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.