1328{
1330
1332
1334
1341
1342
1343
1349
1355
1357
1361
1362
1364 {
1366
1367
1368 RegisterNetSyncVariableInt( "m_SyncParts01" );
1369 RegisterNetSyncVariableInt( "m_SyncParts02" );
1370 RegisterNetSyncVariableInt( "m_SyncParts03" );
1371 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1372 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1373 RegisterNetSyncVariableBool( "m_HasBase" );
1374
1375
1376 ConstructionInit();
1377
1378 if (ConfigIsExisting("hybridAttachments"))
1379 {
1382 }
1383 if (ConfigIsExisting("mountables"))
1384 {
1387 }
1388
1390 SetAllowDamage(true);
1391 }
1392
1394 {
1395 return "disableBaseDamage";
1396 }
1397
1399 {
1400 return true;
1401 }
1402
1404 {
1405 return EInventoryIconVisibility.HIDE_VICINITY;
1406 }
1407
1409 {
1410 super.InitItemSounds();
1411
1415
1420 }
1421
1423 {
1424 return "putDown_FenceKit_SoundSet";
1425 }
1426
1428 {
1429 return "Shelter_Site_Build_Loop_SoundSet";
1430 }
1431
1432
1434 {
1436 {
1437 SetSynchDirty();
1438 }
1439 }
1440
1442 {
1444 super.OnVariablesSynchronized();
1445
1447 }
1448
1450 {
1451
1453
1454
1456
1457
1459 }
1460
1461
1463 {
1464
1465 int offset;
1466 int mask;
1467
1468 if ( part_id >= 1 && part_id <= 31 )
1469 {
1470 offset = part_id - 1;
1471 mask = 1 << offset;
1472
1474 }
1475 else if ( part_id >= 32 && part_id <= 62 )
1476 {
1477 offset = ( part_id % 32 );
1478 mask = 1 << offset;
1479
1481 }
1482 else if ( part_id >= 63 && part_id <= 93 )
1483 {
1484 offset = ( part_id % 63 );
1485 mask = 1 << offset;
1486
1488 }
1489 }
1490
1492 {
1493
1494 int offset;
1495 int mask;
1496
1497 if ( part_id >= 1 && part_id <= 31 )
1498 {
1499 offset = part_id - 1;
1500 mask = 1 << offset;
1501
1503 }
1504 else if ( part_id >= 32 && part_id <= 62 )
1505 {
1506 offset = ( part_id % 32 );
1507 mask = 1 << offset;
1508
1510 }
1511 else if ( part_id >= 63 && part_id <= 93 )
1512 {
1513 offset = ( part_id % 63 );
1514 mask = 1 << offset;
1515
1517 }
1518 }
1519
1521 {
1522
1523 int offset;
1524 int mask;
1525
1526 if ( part_id >= 1 && part_id <= 31 )
1527 {
1528 offset = part_id - 1;
1529 mask = 1 << offset;
1530
1532 {
1533 return true;
1534 }
1535 }
1536 else if ( part_id >= 32 && part_id <= 62 )
1537 {
1538 offset = ( part_id % 32 );
1539 mask = 1 << offset;
1540
1542 {
1543 return true;
1544 }
1545 }
1546 else if ( part_id >= 63 && part_id <= 93 )
1547 {
1548 offset = ( part_id % 63 );
1549 mask = 1 << offset;
1550
1552 {
1553 return true;
1554 }
1555 }
1556
1557 return false;
1558 }
1559
1561 {
1564 }
1565
1567 {
1568
1571 }
1572
1574 {
1576 {
1579
1580 switch( build_action_id )
1581 {
1585 }
1586 }
1587 }
1588
1589
1591 {
1593 bool is_base = part.
IsBase();
1596 if ( is_part_built_sync )
1597 {
1599 {
1603
1604 if (is_base)
1605 {
1608 }
1609 }
1610 }
1611 else
1612 {
1614 {
1618
1619 if (is_base)
1620 {
1623 }
1624 }
1625 }
1626
1627
1629 }
1630
1631
1633 {
1636
1637 for ( int i = 0; i < construction_parts.Count(); ++i )
1638 {
1639 string key = construction_parts.GetKey( i );
1642 }
1643
1644
1646 }
1647
1649 {
1652
1653 for ( int i = 0; i < construction_parts.Count(); ++i )
1654 {
1655 string key = construction_parts.GetKey( i );
1657
1658 if ( value.
GetId() ==
id )
1659 {
1660 return value;
1661 }
1662 }
1663
1664 return NULL;
1665 }
1666
1667
1668
1670 {
1672 }
1673
1675 {
1677 }
1678
1680 {
1681 return true;
1682 }
1683
1685 {
1686 return false;
1687 }
1688
1689
1691 {
1694 {
1696 }
1697
1698 return construction_kit;
1699 }
1700
1702 {
1705 {
1707 }
1708 }
1709
1711 {
1713 }
1714
1716 {
1717 return "";
1718 }
1719
1721 {
1723 g_Game.ObjectDelete( construction_kit );
1724 }
1725
1726
1728 {
1730 g_Game.ObjectDelete(
this );
1731 }
1732
1733
1735 {
1736 super.EEDelete(parent);
1737
1739 {
1740 areaDamage.Destroy();
1741 }
1742
1743 }
1744
1746 {
1747 super.OnStoreSave( ctx );
1748
1749
1753
1755 }
1756
1758 {
1759 if ( !super.OnStoreLoad( ctx, version ) )
1760 return false;
1761
1762
1763
1765 {
1767 return false;
1768 }
1770 {
1772 return false;
1773 }
1775 {
1777 return false;
1778 }
1779
1780
1782 {
1784 return false;
1785 }
1786
1787
1788 return true;
1789 }
1790
1792 {
1793 super.AfterStoreLoad();
1794
1796 {
1798 }
1799 }
1800
1802 {
1803
1805
1806
1809
1810
1812 }
1813
1815 {
1816 super.OnCreatePhysics();
1817
1818 ConstructionInit();
1820 }
1821
1823 {
1825 return;
1826
1827 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
1828 }
1829
1831 {
1833 {
1835 }
1836
1837 super.EEOnAfterLoad();
1838 }
1839
1841 {
1842 super.EEItemAttached( item, slot_name );
1843
1847 }
1848
1850 {
1851 super.EEItemDetached( item, slot_name );
1852
1855 }
1856
1857 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
1858 {
1861
1864 }
1865
1866
1868 {
1869 return true;
1870 }
1871
1872
1873
1875 {
1877
1878
1879 if (construtionPart.
IsBase())
1880 {
1882
1883
1885 }
1886
1887
1889
1890
1892
1893
1895
1897
1899
1900
1902
1903
1905 }
1906
1908 {
1909
1911 }
1912
1913
1915 {
1918
1919
1921
1922
1924
1925
1927
1928
1930
1932
1933
1935
1936
1938
1939
1940 if (construtionPart.
IsBase())
1941 {
1942
1944 }
1945 }
1946
1948 {
1949
1951 }
1952
1953
1954 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
1955 {
1958
1959
1961
1962
1964
1965
1967
1968
1970
1972
1973
1975
1976
1978
1979
1980 if (construtionPart.
IsBase())
1981 {
1982
1984 }
1985 }
1986
1988 {
1989
1991 }
1992
1993
1995 {
1997
2000 }
2001
2003 {
2005
2007 {
2009 }
2010 else
2011 {
2013 }
2014
2016 }
2017
2019 {
2021
2023 foreach (
string slotName : attachmentSlots)
2024 {
2026 }
2027
2028
2031 else
2033
2035 }
2036
2038 {
2039 string slotNameMounted = slot_name + "_Mounted";
2040 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2041
2042 if (attachment)
2043 {
2044 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2045 if (barbedWire && barbedWire.IsMounted())
2047 else
2049
2050 if (is_locked)
2051 {
2052 SetAnimationPhase(slotNameMounted, 0);
2053 SetAnimationPhase(slot_name, 1);
2054 }
2055 else
2056 {
2057 SetAnimationPhase(slotNameMounted, 1);
2058 SetAnimationPhase(slot_name, 0);
2059 }
2060 }
2061 else
2062 {
2063 SetAnimationPhase(slotNameMounted, 1);
2064 SetAnimationPhase(slot_name, 1);
2065
2067 }
2068 }
2069
2070
2072 {
2075
2078
2081
2082 foreach (
string slotName : attachmentSlots)
2083 {
2085 }
2086
2087
2089 {
2092
2094 }
2095 else
2096 {
2099
2101 }
2102
2105 }
2106
2108 {
2109
2111 return;
2112
2113 string slot_name_mounted = slot_name + "_Mounted";
2114 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2115
2116
2118 RemoveProxyPhysics( slot_name_mounted );
2119 RemoveProxyPhysics( slot_name );
2120
2121 if ( attachment )
2122 {
2124 if ( is_locked )
2125 {
2127 AddProxyPhysics( slot_name_mounted );
2128 }
2129 else
2130 {
2132 AddProxyPhysics( slot_name );
2133 }
2134 }
2135 }
2136
2138 {
2139 SetAffectPathgraph( true, false );
2141 }
2142
2144 {
2145 return true;
2146 }
2147
2149 {
2150 return true;
2151 }
2152
2154 {
2155 if ( attachment )
2156 {
2158 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2159
2160 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2161 }
2162
2163 return false;
2164 }
2165
2167 {
2169 }
2170
2171
2173 {
2174 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2175 if (
g_Game.ConfigIsExisting( config_path ) )
2176 {
2177 g_Game.ConfigGetTextArray( config_path, attachment_slots );
2178 }
2179 }
2180
2182 {
2183 return true;
2184 }
2185
2187 {
2188 return true;
2189 }
2190
2192 {
2193 return true;
2194 }
2195
2196
2198 {
2201 }
2202
2204 {
2206 }
2207
2209 {
2211 }
2212
2214 {
2215 int attachment_count = GetInventory().AttachmentCount();
2216 if ( attachment_count > 0 )
2217 {
2218 if (
HasBase() && attachment_count == 1 )
2219 {
2220 return false;
2221 }
2222
2223 return true;
2224 }
2225
2226 return false;
2227 }
2228
2230 {
2231 return true;
2232 }
2233
2235 {
2236 return false;
2237 }
2238
2239
2241 {
2242 return false;
2243 }
2244
2246 {
2247 return false;
2248 }
2249
2250
2252 {
2253 return false;
2254 }
2255
2256
2257
2259 {
2260 return true;
2261 }
2262
2264 {
2265 return true;
2266 }
2267
2270 {
2271 return false;
2272 }
2273
2274
2276 {
2277 return false;
2278 }
2279
2280
2282 {
2283 return true;
2284 }
2285
2286
2288 {
2289 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2290 {
2291 return false;
2292 }
2293
2294 return true;
2295 }
2296
2298 {
2301
2302 return item;
2303 }
2304
2305
2307 {
2309 {
2310
2312
2313
2316
2318 if ( MemoryPointExists( slot_name + "_min" ) )
2319 {
2320 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2321 }
2322 if ( MemoryPointExists( slot_name + "_max" ) )
2323 {
2324 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2325 }
2326
2327
2330
2331
2334 center = ModelToWorld( center );
2335
2336
2339
2340 areaDamage.SetExtents( extents[0], extents[1] );
2341 areaDamage.SetAreaPosition( center );
2345 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2346 areaDamage.SetAmmoName( "BarbedWireHit" );
2347 areaDamage.Spawn();
2348
2350 }
2351 }
2352
2354 {
2355 if ( angle_deg != 0 )
2356 {
2357
2359
2360
2362 if ( MemoryPointExists( "rotate_axis" ) )
2363 {
2364 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2365 }
2366 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];
2367 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];
2368 center[0] = r_center_x;
2369 center[2] = r_center_z;
2370 }
2371 }
2372
2374 {
2376 {
2379 {
2380 if (areaDamage)
2381 {
2382 areaDamage.Destroy();
2383 }
2384
2386 }
2387 }
2388 }
2389
2391 {
2392 return true;
2393 }
2394
2395
2396
2397
2399 {
2401 }
2402
2404 {
2406 }
2407
2409 {
2411 }
2412
2414 {
2416
2417 switch ( material_type )
2418 {
2424 }
2425
2426 return "";
2427 }
2428
2430 {
2432
2433 switch ( material_type )
2434 {
2440 }
2441
2442 return "";
2443 }
2444
2445
2447 {
2449 {
2450
2452 {
2453 SetHealth(slot_name,"Health",item.GetHealth());
2454 }
2455 }
2456 }
2457
2459 {
2460 return 111;
2461 }
2462
2464 {
2465 super.SetActions();
2466
2470 }
2471
2473 {
2475 if (!construction)
2476 return;
2477
2479 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2480 {
2483 {
2485 }
2486 }
2487 }
2488
2490 {
2492 if (!construction)
2493 return;
2494
2496 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
2497 {
2500 {
2501 construction.HandleEntityFalling(part.
GetPartName());
2502 }
2503 }
2504 }
2505
2508 {
2510 return;
2511
2514
2515 if (DestroyOnFall())
2516 {
2518 {
2520 }
2521 else
2522 {
2524 {
2526 }
2528 }
2529 }
2530 }
2531
2533 {
2534 if (HasAnyAttachmentsOrCargo())
2535 {
2538 }
2539 }
2540
2541
2542
2543
2544
2547 {
2548 return null;
2549 }
2550
2552 {
2554 }
2555
2557 {
2560
2561 Man p;
2562
2563 #ifdef SERVER
2565 g_Game.GetWorld().GetPlayerList(players);
2566 if (players.Count())
2567 p = players[0];
2568 #else
2570 #endif
2571
2573 {
2574 bool excluded = false;
2576 if (excludes)
2577 {
2578 foreach (string exclude : excludes)
2579 {
2581 {
2582 excluded = true;
2583 break;
2584 }
2585 }
2586 }
2587
2588 if (!excluded)
2589 {
2591 }
2592 }
2593
2595 }
2596
2598
2600 [
Obsolete(
"handled in the Construction component directly")]
2602 {
2603 }
2604
2605 [
Obsolete(
"handled in the Construction component directly")]
2607 {
2608 }
2609
2610 [
Obsolete(
"obsolete debug method")]
2612 {
2613 }
2614}
2615
2617{
2618#ifdef BSB_DEBUG
2620#else
2621
2622#endif
2623}
2625{
2626#ifdef BSB_DEBUG_SPAM
2628#else
2629
2630#endif
2631}
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.