1699{
1701
1703
1705
1712
1713
1714
1720
1726
1728
1732
1733
1735 {
1737
1738
1739 RegisterNetSyncVariableInt( "m_SyncParts01" );
1740 RegisterNetSyncVariableInt( "m_SyncParts02" );
1741 RegisterNetSyncVariableInt( "m_SyncParts03" );
1742 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1743 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1744 RegisterNetSyncVariableBool( "m_HasBase" );
1745
1746
1747 ConstructionInit();
1748
1749 if (ConfigIsExisting("hybridAttachments"))
1750 {
1753 }
1754 if (ConfigIsExisting("mountables"))
1755 {
1758 }
1759
1761 SetAllowDamage(true);
1762 }
1763
1765 {
1766 return "disableBaseDamage";
1767 }
1768
1770 {
1771 return true;
1772 }
1773
1775 {
1776 return EInventoryIconVisibility.HIDE_VICINITY;
1777 }
1778
1780 {
1781 super.InitItemSounds();
1782
1786
1791 }
1792
1794 {
1795 return "putDown_FenceKit_SoundSet";
1796 }
1797
1799 {
1800 return "Shelter_Site_Build_Loop_SoundSet";
1801 }
1802
1803
1805 {
1807 {
1808 SetSynchDirty();
1809 }
1810 }
1811
1813 {
1815 super.OnVariablesSynchronized();
1816
1818 }
1819
1821 {
1822
1824
1825
1827
1828
1830 }
1831
1832
1834 {
1835
1836 int offset;
1837 int mask;
1838
1839 if ( part_id >= 1 && part_id <= 31 )
1840 {
1841 offset = part_id - 1;
1842 mask = 1 << offset;
1843
1845 }
1846 else if ( part_id >= 32 && part_id <= 62 )
1847 {
1848 offset = ( part_id % 32 );
1849 mask = 1 << offset;
1850
1852 }
1853 else if ( part_id >= 63 && part_id <= 93 )
1854 {
1855 offset = ( part_id % 63 );
1856 mask = 1 << offset;
1857
1859 }
1860 }
1861
1863 {
1864
1865 int offset;
1866 int mask;
1867
1868 if ( part_id >= 1 && part_id <= 31 )
1869 {
1870 offset = part_id - 1;
1871 mask = 1 << offset;
1872
1874 }
1875 else if ( part_id >= 32 && part_id <= 62 )
1876 {
1877 offset = ( part_id % 32 );
1878 mask = 1 << offset;
1879
1881 }
1882 else if ( part_id >= 63 && part_id <= 93 )
1883 {
1884 offset = ( part_id % 63 );
1885 mask = 1 << offset;
1886
1888 }
1889 }
1890
1892 {
1893
1894 int offset;
1895 int mask;
1896
1897 if ( part_id >= 1 && part_id <= 31 )
1898 {
1899 offset = part_id - 1;
1900 mask = 1 << offset;
1901
1903 {
1904 return true;
1905 }
1906 }
1907 else if ( part_id >= 32 && part_id <= 62 )
1908 {
1909 offset = ( part_id % 32 );
1910 mask = 1 << offset;
1911
1913 {
1914 return true;
1915 }
1916 }
1917 else if ( part_id >= 63 && part_id <= 93 )
1918 {
1919 offset = ( part_id % 63 );
1920 mask = 1 << offset;
1921
1923 {
1924 return true;
1925 }
1926 }
1927
1928 return false;
1929 }
1930
1932 {
1935 }
1936
1938 {
1939
1942 }
1943
1945 {
1947 {
1950
1951 switch( build_action_id )
1952 {
1956 }
1957 }
1958 }
1959
1960
1962 {
1964 bool is_base = part.
IsBase();
1967 if ( is_part_built_sync )
1968 {
1970 {
1974
1975 if (is_base)
1976 {
1979 }
1980 }
1981 }
1982 else
1983 {
1985 {
1989
1990 if (is_base)
1991 {
1994 }
1995 }
1996 }
1997
1998
2000 }
2001
2002
2004 {
2007
2008 for ( int i = 0; i < construction_parts.Count(); ++i )
2009 {
2010 string key = construction_parts.GetKey( i );
2013 }
2014
2015
2017 }
2018
2020 {
2023
2024 for ( int i = 0; i < construction_parts.Count(); ++i )
2025 {
2026 string key = construction_parts.GetKey( i );
2028
2029 if ( value.
GetId() ==
id )
2030 {
2031 return value;
2032 }
2033 }
2034
2035 return NULL;
2036 }
2037
2038
2039
2041 {
2043 }
2044
2046 {
2048 }
2049
2051 {
2052 return true;
2053 }
2054
2056 {
2057 return false;
2058 }
2059
2060
2062 {
2065 {
2067 }
2068
2069 return construction_kit;
2070 }
2071
2073 {
2076 {
2078 }
2079 }
2080
2082 {
2084 }
2085
2087 {
2088 return "";
2089 }
2090
2092 {
2094 g_Game.ObjectDelete( construction_kit );
2095 }
2096
2097
2099 {
2101 g_Game.ObjectDelete(
this );
2102 }
2103
2104
2106 {
2107 super.EEDelete(parent);
2108
2110 {
2111 areaDamage.Destroy();
2112 }
2113
2114 }
2115
2117 {
2118 super.OnStoreSave( ctx );
2119
2120
2124
2126 }
2127
2129 {
2130 if ( !super.OnStoreLoad( ctx, version ) )
2131 return false;
2132
2133
2134
2136 {
2138 return false;
2139 }
2141 {
2143 return false;
2144 }
2146 {
2148 return false;
2149 }
2150
2151
2153 {
2155 return false;
2156 }
2157
2158
2159 return true;
2160 }
2161
2163 {
2164 super.AfterStoreLoad();
2165
2167 {
2169 }
2170 }
2171
2173 {
2174
2176
2177
2180
2181
2183 }
2184
2186 {
2187 super.OnCreatePhysics();
2188
2189 ConstructionInit();
2191 }
2192
2194 {
2196 return;
2197
2198 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2199 }
2200
2202 {
2204 {
2206 }
2207
2208 super.EEOnAfterLoad();
2209 }
2210
2212 {
2213 super.EEItemAttached( item, slot_name );
2214
2218 }
2219
2221 {
2222 super.EEItemDetached( item, slot_name );
2223
2226 }
2227
2228 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2229 {
2232
2235 }
2236
2237
2239 {
2240 return true;
2241 }
2242
2243
2244
2246 {
2248
2249
2250 if (construtionPart.
IsBase())
2251 {
2253
2254
2256 }
2257
2258
2260
2261
2263
2264
2266
2268
2270
2271
2273
2274
2276 }
2277
2279 {
2280
2282 }
2283
2284
2286 {
2289
2290
2292
2293
2295
2296
2298
2299
2301
2303
2304
2306
2307
2309
2310
2311 if (construtionPart.
IsBase())
2312 {
2313
2315 }
2316 }
2317
2319 {
2320
2322 }
2323
2324
2325 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2326 {
2329
2330
2332
2333
2335
2336
2338
2339
2341
2343
2344
2346
2347
2349
2350
2351 if (construtionPart.
IsBase())
2352 {
2353
2355 }
2356 }
2357
2359 {
2360
2362 }
2363
2364
2366 {
2368
2371 }
2372
2374 {
2376
2378 {
2380 }
2381 else
2382 {
2384 }
2385
2387 }
2388
2390 {
2392
2394 foreach (
string slotName : attachmentSlots)
2395 {
2397 }
2398
2399
2402 else
2404
2406 }
2407
2409 {
2410 string slotNameMounted = slot_name + "_Mounted";
2411 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2412
2413 if (attachment)
2414 {
2415 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2416 if (barbedWire && barbedWire.IsMounted())
2418 else
2420
2421 if (is_locked)
2422 {
2423 SetAnimationPhase(slotNameMounted, 0);
2424 SetAnimationPhase(slot_name, 1);
2425 }
2426 else
2427 {
2428 SetAnimationPhase(slotNameMounted, 1);
2429 SetAnimationPhase(slot_name, 0);
2430 }
2431 }
2432 else
2433 {
2434 SetAnimationPhase(slotNameMounted, 1);
2435 SetAnimationPhase(slot_name, 1);
2436
2438 }
2439 }
2440
2441
2443 {
2446
2449
2452
2453 foreach (
string slotName : attachmentSlots)
2454 {
2456 }
2457
2458
2460 {
2463
2465 }
2466 else
2467 {
2470
2472 }
2473
2476 }
2477
2479 {
2480
2482 return;
2483
2484 string slot_name_mounted = slot_name + "_Mounted";
2485 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2486
2487
2489 RemoveProxyPhysics( slot_name_mounted );
2490 RemoveProxyPhysics( slot_name );
2491
2492 if ( attachment )
2493 {
2495 if ( is_locked )
2496 {
2498 AddProxyPhysics( slot_name_mounted );
2499 }
2500 else
2501 {
2503 AddProxyPhysics( slot_name );
2504 }
2505 }
2506 }
2507
2509 {
2510 SetAffectPathgraph( true, false );
2512 }
2513
2515 {
2516 return true;
2517 }
2518
2520 {
2521 return true;
2522 }
2523
2525 {
2526 if ( attachment )
2527 {
2529 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2530
2531 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2532 }
2533
2534 return false;
2535 }
2536
2538 {
2540 }
2541
2542
2544 {
2545 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2546 if (
g_Game.ConfigIsExisting( config_path ) )
2547 {
2548 g_Game.ConfigGetTextArray( config_path, attachment_slots );
2549 }
2550 }
2551
2553 {
2554 return true;
2555 }
2556
2558 {
2559 return true;
2560 }
2561
2563 {
2564 return true;
2565 }
2566
2567
2569 {
2572 }
2573
2575 {
2577 }
2578
2580 {
2582 }
2583
2585 {
2586 int attachment_count = GetInventory().AttachmentCount();
2587 if ( attachment_count > 0 )
2588 {
2589 if (
HasBase() && attachment_count == 1 )
2590 {
2591 return false;
2592 }
2593
2594 return true;
2595 }
2596
2597 return false;
2598 }
2599
2601 {
2602 return true;
2603 }
2604
2606 {
2607 return false;
2608 }
2609
2610
2612 {
2613 return false;
2614 }
2615
2617 {
2618 return false;
2619 }
2620
2621
2623 {
2624 return false;
2625 }
2626
2627
2628
2630 {
2631 return true;
2632 }
2633
2635 {
2636 return true;
2637 }
2638
2641 {
2642 return false;
2643 }
2644
2645
2647 {
2648 return false;
2649 }
2650
2651
2653 {
2654 return true;
2655 }
2656
2657
2659 {
2660 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2661 {
2662 return false;
2663 }
2664
2665 return true;
2666 }
2667
2669 {
2672
2673 return item;
2674 }
2675
2676
2678 {
2680 {
2681
2683
2684
2687
2689 if ( MemoryPointExists( slot_name + "_min" ) )
2690 {
2691 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2692 }
2693 if ( MemoryPointExists( slot_name + "_max" ) )
2694 {
2695 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2696 }
2697
2698
2701
2702
2705 center = ModelToWorld( center );
2706
2707
2710
2711 areaDamage.SetExtents( extents[0], extents[1] );
2712 areaDamage.SetAreaPosition( center );
2716 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2717 areaDamage.SetAmmoName( "BarbedWireHit" );
2718 areaDamage.Spawn();
2719
2721 }
2722 }
2723
2725 {
2726 if ( angle_deg != 0 )
2727 {
2728
2730
2731
2733 if ( MemoryPointExists( "rotate_axis" ) )
2734 {
2735 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2736 }
2737 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];
2738 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];
2739 center[0] = r_center_x;
2740 center[2] = r_center_z;
2741 }
2742 }
2743
2745 {
2747 {
2750 {
2751 if (areaDamage)
2752 {
2753 areaDamage.Destroy();
2754 }
2755
2757 }
2758 }
2759 }
2760
2762 {
2763 return true;
2764 }
2765
2766
2767
2768
2770 {
2772 }
2773
2775 {
2777 }
2778
2780 {
2782 }
2783
2785 {
2787
2788 switch ( material_type )
2789 {
2795 }
2796
2797 return "";
2798 }
2799
2801 {
2803
2804 switch ( material_type )
2805 {
2811 }
2812
2813 return "";
2814 }
2815
2816
2818 {
2820 {
2821
2823 {
2824 SetHealth(slot_name,"Health",item.GetHealth());
2825 }
2826 }
2827 }
2828
2830 {
2831 return 111;
2832 }
2833
2835 {
2836 super.SetActions();
2837
2841 }
2842
2844 {
2846 if (!construction)
2847 return;
2848
2850 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2851 {
2854 {
2856 }
2857 }
2858 }
2859
2861 {
2863 if (!construction)
2864 return;
2865
2867 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2868 {
2871 {
2872 construction.HandleEntityFalling(part.
GetPartName());
2873 }
2874 }
2875 }
2876
2879 {
2881 return;
2882
2885
2886 if (DestroyOnFall())
2887 {
2889 {
2891 }
2892 else
2893 {
2895 {
2897 }
2899 }
2900 }
2901 }
2902
2904 {
2905 if (HasAnyAttachmentsOrCargo())
2906 {
2909 }
2910 }
2911
2912
2913
2914
2915
2918 {
2919 return null;
2920 }
2921
2923 {
2925 }
2926
2928 {
2931
2932 Man p;
2933
2934 #ifdef SERVER
2936 g_Game.GetWorld().GetPlayerList(players);
2937 if (players.Count())
2938 p = players[0];
2939 #else
2941 #endif
2942
2944 {
2945 bool excluded = false;
2947 if (excludes)
2948 {
2949 foreach (string exclude : excludes)
2950 {
2952 {
2953 excluded = true;
2954 break;
2955 }
2956 }
2957 }
2958
2959 if (!excluded)
2960 {
2962 }
2963 }
2964
2966 }
2967
2969
2971 [
Obsolete(
"handled in the Construction component directly")]
2973 {
2974 }
2975
2976 [
Obsolete(
"handled in the Construction component directly")]
2978 {
2979 }
2980
2981 [
Obsolete(
"obsolete debug method")]
2983 {
2984 }
2985}
2986
2988{
2989#ifdef BSB_DEBUG
2991#else
2992
2993#endif
2994}
2996{
2997#ifdef BSB_DEBUG_SPAM
2999#else
3000
3001#endif
3002}
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.