1879{
1881
1883
1885
1892
1893
1894
1900
1906
1908
1912
1913
1915 {
1917
1918
1919 RegisterNetSyncVariableInt( "m_SyncParts01" );
1920 RegisterNetSyncVariableInt( "m_SyncParts02" );
1921 RegisterNetSyncVariableInt( "m_SyncParts03" );
1922 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1923 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1924 RegisterNetSyncVariableBool( "m_HasBase" );
1925
1926
1927 ConstructionInit();
1928
1929 if (ConfigIsExisting("hybridAttachments"))
1930 {
1933 }
1934 if (ConfigIsExisting("mountables"))
1935 {
1938 }
1939
1941 SetAllowDamage(true);
1942 }
1943
1945 {
1946 return "disableBaseDamage";
1947 }
1948
1950 {
1951 return true;
1952 }
1953
1955 {
1956 return EInventoryIconVisibility.HIDE_VICINITY;
1957 }
1958
1960 {
1961 super.InitItemSounds();
1962
1966
1971 }
1972
1974 {
1975 return "putDown_FenceKit_SoundSet";
1976 }
1977
1979 {
1980 return "Shelter_Site_Build_Loop_SoundSet";
1981 }
1982
1983
1985 {
1987 {
1988 SetSynchDirty();
1989 }
1990 }
1991
1993 {
1995 super.OnVariablesSynchronized();
1996
1998 }
1999
2001 {
2002
2004
2005
2007
2008
2010 }
2011
2012
2014 {
2015
2016 int offset;
2017 int mask;
2018
2019 if ( part_id >= 1 && part_id <= 31 )
2020 {
2021 offset = part_id - 1;
2022 mask = 1 << offset;
2023
2025 }
2026 else if ( part_id >= 32 && part_id <= 62 )
2027 {
2028 offset = ( part_id % 32 );
2029 mask = 1 << offset;
2030
2032 }
2033 else if ( part_id >= 63 && part_id <= 93 )
2034 {
2035 offset = ( part_id % 63 );
2036 mask = 1 << offset;
2037
2039 }
2040 }
2041
2043 {
2044
2045 int offset;
2046 int mask;
2047
2048 if ( part_id >= 1 && part_id <= 31 )
2049 {
2050 offset = part_id - 1;
2051 mask = 1 << offset;
2052
2054 }
2055 else if ( part_id >= 32 && part_id <= 62 )
2056 {
2057 offset = ( part_id % 32 );
2058 mask = 1 << offset;
2059
2061 }
2062 else if ( part_id >= 63 && part_id <= 93 )
2063 {
2064 offset = ( part_id % 63 );
2065 mask = 1 << offset;
2066
2068 }
2069 }
2070
2072 {
2073
2074 int offset;
2075 int mask;
2076
2077 if ( part_id >= 1 && part_id <= 31 )
2078 {
2079 offset = part_id - 1;
2080 mask = 1 << offset;
2081
2083 {
2084 return true;
2085 }
2086 }
2087 else if ( part_id >= 32 && part_id <= 62 )
2088 {
2089 offset = ( part_id % 32 );
2090 mask = 1 << offset;
2091
2093 {
2094 return true;
2095 }
2096 }
2097 else if ( part_id >= 63 && part_id <= 93 )
2098 {
2099 offset = ( part_id % 63 );
2100 mask = 1 << offset;
2101
2103 {
2104 return true;
2105 }
2106 }
2107
2108 return false;
2109 }
2110
2112 {
2115 }
2116
2118 {
2119
2122 }
2123
2125 {
2127 {
2130
2131 switch( build_action_id )
2132 {
2136 }
2137 }
2138 }
2139
2140
2142 {
2144 bool is_base = part.
IsBase();
2147 if ( is_part_built_sync )
2148 {
2150 {
2154
2155 if (is_base)
2156 {
2159 }
2160 }
2161 }
2162 else
2163 {
2165 {
2169
2170 if (is_base)
2171 {
2174 }
2175 }
2176 }
2177
2178
2180 }
2181
2182
2184 {
2187
2188 for ( int i = 0; i < construction_parts.Count(); ++i )
2189 {
2190 string key = construction_parts.GetKey( i );
2193 }
2194
2195
2197 }
2198
2200 {
2203
2204 for ( int i = 0; i < construction_parts.Count(); ++i )
2205 {
2206 string key = construction_parts.GetKey( i );
2208
2209 if ( value.
GetId() ==
id )
2210 {
2211 return value;
2212 }
2213 }
2214
2215 return NULL;
2216 }
2217
2218
2219
2221 {
2223 }
2224
2226 {
2228 }
2229
2231 {
2232 return true;
2233 }
2234
2236 {
2237 return false;
2238 }
2239
2240
2242 {
2245 {
2247 }
2248
2249 return construction_kit;
2250 }
2251
2253 {
2256 {
2258 }
2259 }
2260
2262 {
2264 }
2265
2267 {
2268 return "";
2269 }
2270
2272 {
2274 g_Game.ObjectDelete( construction_kit );
2275 }
2276
2277
2279 {
2281 g_Game.ObjectDelete(
this );
2282 }
2283
2284
2286 {
2287 super.EEDelete(parent);
2288
2290 {
2291 areaDamage.Destroy();
2292 }
2293
2294 }
2295
2297 {
2298 super.OnStoreSave( ctx );
2299
2300
2304
2306 }
2307
2309 {
2310 if ( !super.OnStoreLoad( ctx, version ) )
2311 return false;
2312
2313
2314
2316 {
2318 return false;
2319 }
2321 {
2323 return false;
2324 }
2326 {
2328 return false;
2329 }
2330
2331
2333 {
2335 return false;
2336 }
2337
2338
2339 return true;
2340 }
2341
2343 {
2344 super.AfterStoreLoad();
2345
2347 {
2349 }
2350 }
2351
2353 {
2354
2356
2357
2360
2361
2363 }
2364
2366 {
2367 super.OnCreatePhysics();
2368
2369 ConstructionInit();
2371 }
2372
2374 {
2376 return;
2377
2378 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2379 }
2380
2382 {
2384 {
2386 }
2387
2388 super.EEOnAfterLoad();
2389 }
2390
2392 {
2393 super.EEItemAttached( item, slot_name );
2394
2398 }
2399
2401 {
2402 super.EEItemDetached( item, slot_name );
2403
2406 }
2407
2408 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2409 {
2412
2415 }
2416
2417
2419 {
2420 return true;
2421 }
2422
2423
2424
2426 {
2428
2429
2430 if (construtionPart.
IsBase())
2431 {
2433
2434
2436 }
2437
2438
2440
2441
2443
2444
2446
2448
2450
2451
2453
2454
2456 }
2457
2459 {
2460
2462 }
2463
2464
2466 {
2469
2470
2472
2473
2475
2476
2478
2479
2481
2483
2484
2486
2487
2489
2490
2491 if (construtionPart.
IsBase())
2492 {
2493
2495 }
2496 }
2497
2499 {
2500
2502 }
2503
2504
2505 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2506 {
2509
2510
2512
2513
2515
2516
2518
2519
2521
2523
2524
2526
2527
2529
2530
2531 if (construtionPart.
IsBase())
2532 {
2533
2535 }
2536 }
2537
2539 {
2540
2542 }
2543
2544
2546 {
2548
2551 }
2552
2554 {
2556
2558 {
2560 }
2561 else
2562 {
2564 }
2565
2567 }
2568
2570 {
2572
2574 foreach (
string slotName : attachmentSlots)
2575 {
2577 }
2578
2579
2582 else
2584
2586 }
2587
2589 {
2590 string slotNameMounted = slot_name + "_Mounted";
2591 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2592
2593 if (attachment)
2594 {
2595 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2596 if (barbedWire && barbedWire.IsMounted())
2598 else
2600
2601 if (is_locked)
2602 {
2603 SetAnimationPhase(slotNameMounted, 0);
2604 SetAnimationPhase(slot_name, 1);
2605 }
2606 else
2607 {
2608 SetAnimationPhase(slotNameMounted, 1);
2609 SetAnimationPhase(slot_name, 0);
2610 }
2611 }
2612 else
2613 {
2614 SetAnimationPhase(slotNameMounted, 1);
2615 SetAnimationPhase(slot_name, 1);
2616
2618 }
2619 }
2620
2621
2623 {
2626
2629
2632
2633 foreach (
string slotName : attachmentSlots)
2634 {
2636 }
2637
2638
2640 {
2643
2645 }
2646 else
2647 {
2650
2652 }
2653
2656 }
2657
2659 {
2660
2662 return;
2663
2664 string slot_name_mounted = slot_name + "_Mounted";
2665 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2666
2667
2669 RemoveProxyPhysics( slot_name_mounted );
2670 RemoveProxyPhysics( slot_name );
2671
2672 if ( attachment )
2673 {
2675 if ( is_locked )
2676 {
2678 AddProxyPhysics( slot_name_mounted );
2679 }
2680 else
2681 {
2683 AddProxyPhysics( slot_name );
2684 }
2685 }
2686 }
2687
2689 {
2690 SetAffectPathgraph( true, false );
2692 }
2693
2695 {
2696 return true;
2697 }
2698
2700 {
2701 return true;
2702 }
2703
2705 {
2706 if ( attachment )
2707 {
2709 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2710
2711 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2712 }
2713
2714 return false;
2715 }
2716
2718 {
2720 }
2721
2722
2724 {
2725 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2726 if (
g_Game.ConfigIsExisting( config_path ) )
2727 {
2728 g_Game.ConfigGetTextArray( config_path, attachment_slots );
2729 }
2730 }
2731
2733 {
2734 return true;
2735 }
2736
2738 {
2739 return true;
2740 }
2741
2743 {
2744 return true;
2745 }
2746
2747
2749 {
2752 }
2753
2755 {
2757 }
2758
2760 {
2762 }
2763
2765 {
2766 int attachment_count = GetInventory().AttachmentCount();
2767 if ( attachment_count > 0 )
2768 {
2769 if (
HasBase() && attachment_count == 1 )
2770 {
2771 return false;
2772 }
2773
2774 return true;
2775 }
2776
2777 return false;
2778 }
2779
2781 {
2782 return true;
2783 }
2784
2786 {
2787 return false;
2788 }
2789
2790
2792 {
2793 return false;
2794 }
2795
2797 {
2798 return false;
2799 }
2800
2801
2803 {
2804 return false;
2805 }
2806
2807
2808
2810 {
2811 return true;
2812 }
2813
2815 {
2816 return true;
2817 }
2818
2821 {
2822 return false;
2823 }
2824
2825
2827 {
2828 return false;
2829 }
2830
2831
2833 {
2834 return true;
2835 }
2836
2837
2839 {
2840 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2841 {
2842 return false;
2843 }
2844
2845 return true;
2846 }
2847
2849 {
2852
2853 return item;
2854 }
2855
2856
2858 {
2860 {
2861
2863
2864
2867
2869 if ( MemoryPointExists( slot_name + "_min" ) )
2870 {
2871 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2872 }
2873 if ( MemoryPointExists( slot_name + "_max" ) )
2874 {
2875 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2876 }
2877
2878
2881
2882
2885 center = ModelToWorld( center );
2886
2887
2890
2891 areaDamage.SetExtents( extents[0], extents[1] );
2892 areaDamage.SetAreaPosition( center );
2896 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2897 areaDamage.SetAmmoName( "BarbedWireHit" );
2898 areaDamage.Spawn();
2899
2901 }
2902 }
2903
2905 {
2906 if ( angle_deg != 0 )
2907 {
2908
2910
2911
2913 if ( MemoryPointExists( "rotate_axis" ) )
2914 {
2915 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2916 }
2917 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];
2918 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];
2919 center[0] = r_center_x;
2920 center[2] = r_center_z;
2921 }
2922 }
2923
2925 {
2927 {
2930 {
2931 if (areaDamage)
2932 {
2933 areaDamage.Destroy();
2934 }
2935
2937 }
2938 }
2939 }
2940
2942 {
2943 return true;
2944 }
2945
2946
2947
2948
2950 {
2952 }
2953
2955 {
2957 }
2958
2960 {
2962 }
2963
2965 {
2967
2968 switch ( material_type )
2969 {
2975 }
2976
2977 return "";
2978 }
2979
2981 {
2983
2984 switch ( material_type )
2985 {
2991 }
2992
2993 return "";
2994 }
2995
2996
2998 {
3000 {
3001
3003 {
3004 SetHealth(slot_name,"Health",item.GetHealth());
3005 }
3006 }
3007 }
3008
3010 {
3011 return 111;
3012 }
3013
3015 {
3016 super.SetActions();
3017
3021 }
3022
3024 {
3026 if (!construction)
3027 return;
3028
3030 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3031 {
3034 {
3036 }
3037 }
3038 }
3039
3041 {
3043 if (!construction)
3044 return;
3045
3047 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3048 {
3051 {
3052 construction.HandleEntityFalling(part.
GetPartName());
3053 }
3054 }
3055 }
3056
3059 {
3061 return;
3062
3065
3066 if (DestroyOnFall())
3067 {
3069 {
3071 }
3072 else
3073 {
3075 {
3077 }
3079 }
3080 }
3081 }
3082
3084 {
3085 if (HasAnyAttachmentsOrCargo())
3086 {
3089 }
3090 }
3091
3092
3093
3094
3095
3098 {
3099 return null;
3100 }
3101
3103 {
3105 }
3106
3108 {
3111
3112 Man p;
3113
3114 #ifdef SERVER
3116 g_Game.GetWorld().GetPlayerList(players);
3117 if (players.Count())
3118 p = players[0];
3119 #else
3121 #endif
3122
3124 {
3125 bool excluded = false;
3127 if (excludes)
3128 {
3129 foreach (string exclude : excludes)
3130 {
3132 {
3133 excluded = true;
3134 break;
3135 }
3136 }
3137 }
3138
3139 if (!excluded)
3140 {
3142 }
3143 }
3144
3146 }
3147
3149
3151 [
Obsolete(
"handled in the Construction component directly")]
3153 {
3154 }
3155
3156 [
Obsolete(
"handled in the Construction component directly")]
3158 {
3159 }
3160
3161 [
Obsolete(
"obsolete debug method")]
3163 {
3164 }
3165}
3166
3168{
3169#ifdef BSB_DEBUG
3171#else
3172
3173#endif
3174}
3176{
3177#ifdef BSB_DEBUG_SPAM
3179#else
3180
3181#endif
3182}
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.