1373{
1375
1377
1379
1386
1387
1388
1394
1400
1402
1406
1407
1409 {
1411
1412
1413 RegisterNetSyncVariableInt( "m_SyncParts01" );
1414 RegisterNetSyncVariableInt( "m_SyncParts02" );
1415 RegisterNetSyncVariableInt( "m_SyncParts03" );
1416 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1417 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1418 RegisterNetSyncVariableBool( "m_HasBase" );
1419
1420
1421 ConstructionInit();
1422
1423 if (ConfigIsExisting("hybridAttachments"))
1424 {
1427 }
1428 if (ConfigIsExisting("mountables"))
1429 {
1432 }
1433
1435 SetAllowDamage(true);
1436 }
1437
1439 {
1440 return "disableBaseDamage";
1441 }
1442
1444 {
1445 return true;
1446 }
1447
1449 {
1450 return EInventoryIconVisibility.HIDE_VICINITY;
1451 }
1452
1454 {
1455 super.InitItemSounds();
1456
1460
1465 }
1466
1468 {
1469 return "putDown_FenceKit_SoundSet";
1470 }
1471
1473 {
1474 return "Shelter_Site_Build_Loop_SoundSet";
1475 }
1476
1477
1479 {
1481 {
1482 SetSynchDirty();
1483 }
1484 }
1485
1487 {
1489 super.OnVariablesSynchronized();
1490
1492 }
1493
1495 {
1496
1498
1499
1501
1502
1504 }
1505
1506
1508 {
1509
1510 int offset;
1511 int mask;
1512
1513 if ( part_id >= 1 && part_id <= 31 )
1514 {
1515 offset = part_id - 1;
1516 mask = 1 << offset;
1517
1519 }
1520 else if ( part_id >= 32 && part_id <= 62 )
1521 {
1522 offset = ( part_id % 32 );
1523 mask = 1 << offset;
1524
1526 }
1527 else if ( part_id >= 63 && part_id <= 93 )
1528 {
1529 offset = ( part_id % 63 );
1530 mask = 1 << offset;
1531
1533 }
1534 }
1535
1537 {
1538
1539 int offset;
1540 int mask;
1541
1542 if ( part_id >= 1 && part_id <= 31 )
1543 {
1544 offset = part_id - 1;
1545 mask = 1 << offset;
1546
1548 }
1549 else if ( part_id >= 32 && part_id <= 62 )
1550 {
1551 offset = ( part_id % 32 );
1552 mask = 1 << offset;
1553
1555 }
1556 else if ( part_id >= 63 && part_id <= 93 )
1557 {
1558 offset = ( part_id % 63 );
1559 mask = 1 << offset;
1560
1562 }
1563 }
1564
1566 {
1567
1568 int offset;
1569 int mask;
1570
1571 if ( part_id >= 1 && part_id <= 31 )
1572 {
1573 offset = part_id - 1;
1574 mask = 1 << offset;
1575
1577 {
1578 return true;
1579 }
1580 }
1581 else if ( part_id >= 32 && part_id <= 62 )
1582 {
1583 offset = ( part_id % 32 );
1584 mask = 1 << offset;
1585
1587 {
1588 return true;
1589 }
1590 }
1591 else if ( part_id >= 63 && part_id <= 93 )
1592 {
1593 offset = ( part_id % 63 );
1594 mask = 1 << offset;
1595
1597 {
1598 return true;
1599 }
1600 }
1601
1602 return false;
1603 }
1604
1606 {
1609 }
1610
1612 {
1613
1616 }
1617
1619 {
1621 {
1624
1625 switch( build_action_id )
1626 {
1630 }
1631 }
1632 }
1633
1634
1636 {
1638 bool is_base = part.
IsBase();
1641 if ( is_part_built_sync )
1642 {
1644 {
1648
1649 if (is_base)
1650 {
1653 }
1654 }
1655 }
1656 else
1657 {
1659 {
1663
1664 if (is_base)
1665 {
1668 }
1669 }
1670 }
1671
1672
1674 }
1675
1676
1678 {
1681
1682 for ( int i = 0; i < construction_parts.Count(); ++i )
1683 {
1684 string key = construction_parts.GetKey( i );
1687 }
1688
1689
1691 }
1692
1694 {
1697
1698 for ( int i = 0; i < construction_parts.Count(); ++i )
1699 {
1700 string key = construction_parts.GetKey( i );
1702
1703 if ( value.
GetId() ==
id )
1704 {
1705 return value;
1706 }
1707 }
1708
1709 return NULL;
1710 }
1711
1712
1713
1715 {
1717 }
1718
1720 {
1722 }
1723
1725 {
1726 return true;
1727 }
1728
1730 {
1731 return false;
1732 }
1733
1734
1736 {
1739 {
1741 }
1742
1743 return construction_kit;
1744 }
1745
1747 {
1750 {
1752 }
1753 }
1754
1756 {
1758 }
1759
1761 {
1762 return "";
1763 }
1764
1766 {
1768 g_Game.ObjectDelete( construction_kit );
1769 }
1770
1771
1773 {
1775 g_Game.ObjectDelete(
this );
1776 }
1777
1778
1780 {
1781 super.EEDelete(parent);
1782
1784 {
1785 areaDamage.Destroy();
1786 }
1787
1788 }
1789
1791 {
1792 super.OnStoreSave( ctx );
1793
1794
1798
1800 }
1801
1803 {
1804 if ( !super.OnStoreLoad( ctx, version ) )
1805 return false;
1806
1807
1808
1810 {
1812 return false;
1813 }
1815 {
1817 return false;
1818 }
1820 {
1822 return false;
1823 }
1824
1825
1827 {
1829 return false;
1830 }
1831
1832
1833 return true;
1834 }
1835
1837 {
1838 super.AfterStoreLoad();
1839
1841 {
1843 }
1844 }
1845
1847 {
1848
1850
1851
1854
1855
1857 }
1858
1860 {
1861 super.OnCreatePhysics();
1862
1863 ConstructionInit();
1865 }
1866
1868 {
1870 return;
1871
1872 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
1873 }
1874
1876 {
1878 {
1880 }
1881
1882 super.EEOnAfterLoad();
1883 }
1884
1886 {
1887 super.EEItemAttached( item, slot_name );
1888
1892 }
1893
1895 {
1896 super.EEItemDetached( item, slot_name );
1897
1900 }
1901
1902 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
1903 {
1906
1909 }
1910
1911
1913 {
1914 return true;
1915 }
1916
1917
1918
1920 {
1922
1923
1924 if (construtionPart.
IsBase())
1925 {
1927
1928
1930 }
1931
1932
1934
1935
1937
1938
1940
1942
1944
1945
1947
1948
1950 }
1951
1953 {
1954
1956 }
1957
1958
1960 {
1963
1964
1966
1967
1969
1970
1972
1973
1975
1977
1978
1980
1981
1983
1984
1985 if (construtionPart.
IsBase())
1986 {
1987
1989 }
1990 }
1991
1993 {
1994
1996 }
1997
1998
1999 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2000 {
2003
2004
2006
2007
2009
2010
2012
2013
2015
2017
2018
2020
2021
2023
2024
2025 if (construtionPart.
IsBase())
2026 {
2027
2029 }
2030 }
2031
2033 {
2034
2036 }
2037
2038
2040 {
2042
2045 }
2046
2048 {
2050
2052 {
2054 }
2055 else
2056 {
2058 }
2059
2061 }
2062
2064 {
2066
2068 foreach (
string slotName : attachmentSlots)
2069 {
2071 }
2072
2073
2076 else
2078
2080 }
2081
2083 {
2084 string slotNameMounted = slot_name + "_Mounted";
2085 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2086
2087 if (attachment)
2088 {
2089 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2090 if (barbedWire && barbedWire.IsMounted())
2092 else
2094
2095 if (is_locked)
2096 {
2097 SetAnimationPhase(slotNameMounted, 0);
2098 SetAnimationPhase(slot_name, 1);
2099 }
2100 else
2101 {
2102 SetAnimationPhase(slotNameMounted, 1);
2103 SetAnimationPhase(slot_name, 0);
2104 }
2105 }
2106 else
2107 {
2108 SetAnimationPhase(slotNameMounted, 1);
2109 SetAnimationPhase(slot_name, 1);
2110
2112 }
2113 }
2114
2115
2117 {
2120
2123
2126
2127 foreach (
string slotName : attachmentSlots)
2128 {
2130 }
2131
2132
2134 {
2137
2139 }
2140 else
2141 {
2144
2146 }
2147
2150 }
2151
2153 {
2154
2156 return;
2157
2158 string slot_name_mounted = slot_name + "_Mounted";
2159 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2160
2161
2163 RemoveProxyPhysics( slot_name_mounted );
2164 RemoveProxyPhysics( slot_name );
2165
2166 if ( attachment )
2167 {
2169 if ( is_locked )
2170 {
2172 AddProxyPhysics( slot_name_mounted );
2173 }
2174 else
2175 {
2177 AddProxyPhysics( slot_name );
2178 }
2179 }
2180 }
2181
2183 {
2184 SetAffectPathgraph( true, false );
2186 }
2187
2189 {
2190 return true;
2191 }
2192
2194 {
2195 return true;
2196 }
2197
2199 {
2200 if ( attachment )
2201 {
2203 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2204
2205 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2206 }
2207
2208 return false;
2209 }
2210
2212 {
2214 }
2215
2216
2218 {
2219 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2220 if (
g_Game.ConfigIsExisting( config_path ) )
2221 {
2222 g_Game.ConfigGetTextArray( config_path, attachment_slots );
2223 }
2224 }
2225
2227 {
2228 return true;
2229 }
2230
2232 {
2233 return true;
2234 }
2235
2237 {
2238 return true;
2239 }
2240
2241
2243 {
2246 }
2247
2249 {
2251 }
2252
2254 {
2256 }
2257
2259 {
2260 int attachment_count = GetInventory().AttachmentCount();
2261 if ( attachment_count > 0 )
2262 {
2263 if (
HasBase() && attachment_count == 1 )
2264 {
2265 return false;
2266 }
2267
2268 return true;
2269 }
2270
2271 return false;
2272 }
2273
2275 {
2276 return true;
2277 }
2278
2280 {
2281 return false;
2282 }
2283
2284
2286 {
2287 return false;
2288 }
2289
2291 {
2292 return false;
2293 }
2294
2295
2297 {
2298 return false;
2299 }
2300
2301
2302
2304 {
2305 return true;
2306 }
2307
2309 {
2310 return true;
2311 }
2312
2315 {
2316 return false;
2317 }
2318
2319
2321 {
2322 return false;
2323 }
2324
2325
2327 {
2328 return true;
2329 }
2330
2331
2333 {
2334 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2335 {
2336 return false;
2337 }
2338
2339 return true;
2340 }
2341
2343 {
2346
2347 return item;
2348 }
2349
2350
2352 {
2354 {
2355
2357
2358
2361
2363 if ( MemoryPointExists( slot_name + "_min" ) )
2364 {
2365 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2366 }
2367 if ( MemoryPointExists( slot_name + "_max" ) )
2368 {
2369 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2370 }
2371
2372
2375
2376
2379 center = ModelToWorld( center );
2380
2381
2384
2385 areaDamage.SetExtents( extents[0], extents[1] );
2386 areaDamage.SetAreaPosition( center );
2390 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2391 areaDamage.SetAmmoName( "BarbedWireHit" );
2392 areaDamage.Spawn();
2393
2395 }
2396 }
2397
2399 {
2400 if ( angle_deg != 0 )
2401 {
2402
2404
2405
2407 if ( MemoryPointExists( "rotate_axis" ) )
2408 {
2409 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2410 }
2411 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];
2412 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];
2413 center[0] = r_center_x;
2414 center[2] = r_center_z;
2415 }
2416 }
2417
2419 {
2421 {
2424 {
2425 if (areaDamage)
2426 {
2427 areaDamage.Destroy();
2428 }
2429
2431 }
2432 }
2433 }
2434
2436 {
2437 return true;
2438 }
2439
2440
2441
2442
2444 {
2446 }
2447
2449 {
2451 }
2452
2454 {
2456 }
2457
2459 {
2461
2462 switch ( material_type )
2463 {
2469 }
2470
2471 return "";
2472 }
2473
2475 {
2477
2478 switch ( material_type )
2479 {
2485 }
2486
2487 return "";
2488 }
2489
2490
2492 {
2494 {
2495
2497 {
2498 SetHealth(slot_name,"Health",item.GetHealth());
2499 }
2500 }
2501 }
2502
2504 {
2505 return 111;
2506 }
2507
2509 {
2510 super.SetActions();
2511
2515 }
2516
2518 {
2520 if (!construction)
2521 return;
2522
2524 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2525 {
2528 {
2530 }
2531 }
2532 }
2533
2535 {
2537 if (!construction)
2538 return;
2539
2541 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2542 {
2545 {
2546 construction.HandleEntityFalling(part.
GetPartName());
2547 }
2548 }
2549 }
2550
2553 {
2555 return;
2556
2559
2560 if (DestroyOnFall())
2561 {
2563 {
2565 }
2566 else
2567 {
2569 {
2571 }
2573 }
2574 }
2575 }
2576
2578 {
2579 if (HasAnyAttachmentsOrCargo())
2580 {
2583 }
2584 }
2585
2586
2587
2588
2589
2592 {
2593 return null;
2594 }
2595
2597 {
2599 }
2600
2602 {
2605
2606 Man p;
2607
2608 #ifdef SERVER
2610 g_Game.GetWorld().GetPlayerList(players);
2611 if (players.Count())
2612 p = players[0];
2613 #else
2615 #endif
2616
2618 {
2619 bool excluded = false;
2621 if (excludes)
2622 {
2623 foreach (string exclude : excludes)
2624 {
2626 {
2627 excluded = true;
2628 break;
2629 }
2630 }
2631 }
2632
2633 if (!excluded)
2634 {
2636 }
2637 }
2638
2640 }
2641
2643
2645 [
Obsolete(
"handled in the Construction component directly")]
2647 {
2648 }
2649
2650 [
Obsolete(
"handled in the Construction component directly")]
2652 {
2653 }
2654
2655 [
Obsolete(
"obsolete debug method")]
2657 {
2658 }
2659}
2660
2662{
2663#ifdef BSB_DEBUG
2665#else
2666
2667#endif
2668}
2670{
2671#ifdef BSB_DEBUG_SPAM
2673#else
2674
2675#endif
2676}
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.