1919{
1921
1923
1925
1932
1933
1934
1940
1946
1948
1952
1953
1955 {
1957
1958
1959 RegisterNetSyncVariableInt( "m_SyncParts01" );
1960 RegisterNetSyncVariableInt( "m_SyncParts02" );
1961 RegisterNetSyncVariableInt( "m_SyncParts03" );
1962 RegisterNetSyncVariableInt( "m_InteractedPartId" );
1963 RegisterNetSyncVariableInt( "m_PerformedActionId" );
1964 RegisterNetSyncVariableBool( "m_HasBase" );
1965
1966
1967 ConstructionInit();
1968
1969 if (ConfigIsExisting("hybridAttachments"))
1970 {
1973 }
1974 if (ConfigIsExisting("mountables"))
1975 {
1978 }
1979
1981 SetAllowDamage(true);
1982 }
1983
1985 {
1986 return "disableBaseDamage";
1987 }
1988
1990 {
1991 return true;
1992 }
1993
1995 {
1996 return EInventoryIconVisibility.HIDE_VICINITY;
1997 }
1998
2000 {
2001 super.InitItemSounds();
2002
2006
2011 }
2012
2014 {
2015 return "putDown_FenceKit_SoundSet";
2016 }
2017
2019 {
2020 return "Shelter_Site_Build_Loop_SoundSet";
2021 }
2022
2023
2025 {
2027 {
2028 SetSynchDirty();
2029 }
2030 }
2031
2033 {
2035 super.OnVariablesSynchronized();
2036
2038 }
2039
2041 {
2042
2044
2045
2047
2048
2050 }
2051
2052
2054 {
2055
2056 int offset;
2057 int mask;
2058
2059 if ( part_id >= 1 && part_id <= 31 )
2060 {
2061 offset = part_id - 1;
2062 mask = 1 << offset;
2063
2065 }
2066 else if ( part_id >= 32 && part_id <= 62 )
2067 {
2068 offset = ( part_id % 32 );
2069 mask = 1 << offset;
2070
2072 }
2073 else if ( part_id >= 63 && part_id <= 93 )
2074 {
2075 offset = ( part_id % 63 );
2076 mask = 1 << offset;
2077
2079 }
2080 }
2081
2083 {
2084
2085 int offset;
2086 int mask;
2087
2088 if ( part_id >= 1 && part_id <= 31 )
2089 {
2090 offset = part_id - 1;
2091 mask = 1 << offset;
2092
2094 }
2095 else if ( part_id >= 32 && part_id <= 62 )
2096 {
2097 offset = ( part_id % 32 );
2098 mask = 1 << offset;
2099
2101 }
2102 else if ( part_id >= 63 && part_id <= 93 )
2103 {
2104 offset = ( part_id % 63 );
2105 mask = 1 << offset;
2106
2108 }
2109 }
2110
2112 {
2113
2114 int offset;
2115 int mask;
2116
2117 if ( part_id >= 1 && part_id <= 31 )
2118 {
2119 offset = part_id - 1;
2120 mask = 1 << offset;
2121
2123 {
2124 return true;
2125 }
2126 }
2127 else if ( part_id >= 32 && part_id <= 62 )
2128 {
2129 offset = ( part_id % 32 );
2130 mask = 1 << offset;
2131
2133 {
2134 return true;
2135 }
2136 }
2137 else if ( part_id >= 63 && part_id <= 93 )
2138 {
2139 offset = ( part_id % 63 );
2140 mask = 1 << offset;
2141
2143 {
2144 return true;
2145 }
2146 }
2147
2148 return false;
2149 }
2150
2152 {
2155 }
2156
2158 {
2159
2162 }
2163
2165 {
2167 {
2170
2171 switch( build_action_id )
2172 {
2176 }
2177 }
2178 }
2179
2180
2182 {
2184 bool is_base = part.
IsBase();
2187 if ( is_part_built_sync )
2188 {
2190 {
2194
2195 if (is_base)
2196 {
2199 }
2200 }
2201 }
2202 else
2203 {
2205 {
2209
2210 if (is_base)
2211 {
2214 }
2215 }
2216 }
2217
2218
2220 }
2221
2222
2224 {
2227
2228 for ( int i = 0; i < construction_parts.Count(); ++i )
2229 {
2230 string key = construction_parts.GetKey( i );
2233 }
2234
2235
2237 }
2238
2240 {
2243
2244 for ( int i = 0; i < construction_parts.Count(); ++i )
2245 {
2246 string key = construction_parts.GetKey( i );
2248
2249 if ( value.
GetId() ==
id )
2250 {
2251 return value;
2252 }
2253 }
2254
2255 return NULL;
2256 }
2257
2258
2259
2261 {
2263 }
2264
2266 {
2268 }
2269
2271 {
2272 return true;
2273 }
2274
2276 {
2277 return false;
2278 }
2279
2280
2282 {
2285 {
2287 }
2288
2289 return construction_kit;
2290 }
2291
2293 {
2296 {
2298 }
2299 }
2300
2302 {
2304 }
2305
2307 {
2308 return "";
2309 }
2310
2312 {
2314 g_Game.ObjectDelete( construction_kit );
2315 }
2316
2317
2319 {
2321 g_Game.ObjectDelete(
this );
2322 }
2323
2324
2326 {
2327 super.EEDelete(parent);
2328
2330 {
2331 areaDamage.Destroy();
2332 }
2333
2334 }
2335
2337 {
2338 super.OnStoreSave( ctx );
2339
2340
2344
2346 }
2347
2349 {
2350 if ( !super.OnStoreLoad( ctx, version ) )
2351 return false;
2352
2353
2354
2356 {
2358 return false;
2359 }
2361 {
2363 return false;
2364 }
2366 {
2368 return false;
2369 }
2370
2371
2373 {
2375 return false;
2376 }
2377
2378
2379 return true;
2380 }
2381
2383 {
2384 super.AfterStoreLoad();
2385
2387 {
2389 }
2390 }
2391
2393 {
2394
2396
2397
2400
2401
2403 }
2404
2406 {
2407 super.OnCreatePhysics();
2408
2409 ConstructionInit();
2411 }
2412
2414 {
2416 return;
2417
2418 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2419 }
2420
2422 {
2424 {
2426 }
2427
2428 super.EEOnAfterLoad();
2429 }
2430
2432 {
2433 super.EEItemAttached( item, slot_name );
2434
2438 }
2439
2441 {
2442 super.EEItemDetached( item, slot_name );
2443
2446 }
2447
2448 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2449 {
2452
2455 }
2456
2457
2459 {
2460 return true;
2461 }
2462
2463
2464
2466 {
2468
2469
2470 if (construtionPart.
IsBase())
2471 {
2473
2474
2476 }
2477
2478
2480
2481
2483
2484
2486
2488
2490
2491
2493
2494
2496 }
2497
2499 {
2500
2502 }
2503
2504
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
2545 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2546 {
2549
2550
2552
2553
2555
2556
2558
2559
2561
2563
2564
2566
2567
2569
2570
2571 if (construtionPart.
IsBase())
2572 {
2573
2575 }
2576 }
2577
2579 {
2580
2582 }
2583
2584
2586 {
2588
2591 }
2592
2594 {
2596
2598 {
2600 }
2601 else
2602 {
2604 }
2605
2607 }
2608
2610 {
2612
2614 foreach (
string slotName : attachmentSlots)
2615 {
2617 }
2618
2619
2622 else
2624
2626 }
2627
2629 {
2630 string slotNameMounted = slot_name + "_Mounted";
2631 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2632
2633 if (attachment)
2634 {
2635 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2636 if (barbedWire && barbedWire.IsMounted())
2638 else
2640
2641 if (is_locked)
2642 {
2643 SetAnimationPhase(slotNameMounted, 0);
2644 SetAnimationPhase(slot_name, 1);
2645 }
2646 else
2647 {
2648 SetAnimationPhase(slotNameMounted, 1);
2649 SetAnimationPhase(slot_name, 0);
2650 }
2651 }
2652 else
2653 {
2654 SetAnimationPhase(slotNameMounted, 1);
2655 SetAnimationPhase(slot_name, 1);
2656
2658 }
2659 }
2660
2661
2663 {
2666
2669
2672
2673 foreach (
string slotName : attachmentSlots)
2674 {
2676 }
2677
2678
2680 {
2683
2685 }
2686 else
2687 {
2690
2692 }
2693
2696 }
2697
2699 {
2700
2702 return;
2703
2704 string slot_name_mounted = slot_name + "_Mounted";
2705 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2706
2707
2709 RemoveProxyPhysics( slot_name_mounted );
2710 RemoveProxyPhysics( slot_name );
2711
2712 if ( attachment )
2713 {
2715 if ( is_locked )
2716 {
2718 AddProxyPhysics( slot_name_mounted );
2719 }
2720 else
2721 {
2723 AddProxyPhysics( slot_name );
2724 }
2725 }
2726 }
2727
2729 {
2730 SetAffectPathgraph( true, false );
2732 }
2733
2735 {
2736 return true;
2737 }
2738
2740 {
2741 return true;
2742 }
2743
2745 {
2746 if ( attachment )
2747 {
2749 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2750
2751 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2752 }
2753
2754 return false;
2755 }
2756
2758 {
2760 }
2761
2762
2764 {
2765 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2766 if (
g_Game.ConfigIsExisting( config_path ) )
2767 {
2768 g_Game.ConfigGetTextArray( config_path, attachment_slots );
2769 }
2770 }
2771
2773 {
2774 return true;
2775 }
2776
2778 {
2779 return true;
2780 }
2781
2783 {
2784 return true;
2785 }
2786
2787
2789 {
2792 }
2793
2795 {
2797 }
2798
2800 {
2802 }
2803
2805 {
2806 int attachment_count = GetInventory().AttachmentCount();
2807 if ( attachment_count > 0 )
2808 {
2809 if (
HasBase() && attachment_count == 1 )
2810 {
2811 return false;
2812 }
2813
2814 return true;
2815 }
2816
2817 return false;
2818 }
2819
2821 {
2822 return true;
2823 }
2824
2826 {
2827 return false;
2828 }
2829
2830
2832 {
2833 return false;
2834 }
2835
2837 {
2838 return false;
2839 }
2840
2841
2843 {
2844 return false;
2845 }
2846
2847
2848
2850 {
2851 return true;
2852 }
2853
2855 {
2856 return true;
2857 }
2858
2861 {
2862 return false;
2863 }
2864
2865
2867 {
2868 return false;
2869 }
2870
2871
2873 {
2874 return true;
2875 }
2876
2877
2879 {
2880 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
2881 {
2882 return false;
2883 }
2884
2885 return true;
2886 }
2887
2889 {
2892
2893 return item;
2894 }
2895
2896
2898 {
2900 {
2901
2903
2904
2907
2909 if ( MemoryPointExists( slot_name + "_min" ) )
2910 {
2911 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
2912 }
2913 if ( MemoryPointExists( slot_name + "_max" ) )
2914 {
2915 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
2916 }
2917
2918
2921
2922
2925 center = ModelToWorld( center );
2926
2927
2930
2931 areaDamage.SetExtents( extents[0], extents[1] );
2932 areaDamage.SetAreaPosition( center );
2936 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
2937 areaDamage.SetAmmoName( "BarbedWireHit" );
2938 areaDamage.Spawn();
2939
2941 }
2942 }
2943
2945 {
2946 if ( angle_deg != 0 )
2947 {
2948
2950
2951
2953 if ( MemoryPointExists( "rotate_axis" ) )
2954 {
2955 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
2956 }
2957 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];
2958 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];
2959 center[0] = r_center_x;
2960 center[2] = r_center_z;
2961 }
2962 }
2963
2965 {
2967 {
2970 {
2971 if (areaDamage)
2972 {
2973 areaDamage.Destroy();
2974 }
2975
2977 }
2978 }
2979 }
2980
2982 {
2983 return true;
2984 }
2985
2986
2987
2988
2990 {
2992 }
2993
2995 {
2997 }
2998
3000 {
3002 }
3003
3005 {
3007
3008 switch ( material_type )
3009 {
3015 }
3016
3017 return "";
3018 }
3019
3021 {
3023
3024 switch ( material_type )
3025 {
3031 }
3032
3033 return "";
3034 }
3035
3036
3038 {
3040 {
3041
3043 {
3044 SetHealth(slot_name,"Health",item.GetHealth());
3045 }
3046 }
3047 }
3048
3050 {
3051 return 111;
3052 }
3053
3055 {
3056 super.SetActions();
3057
3061 }
3062
3064 {
3066 if (!construction)
3067 return;
3068
3070 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3071 {
3074 {
3076 }
3077 }
3078 }
3079
3081 {
3083 if (!construction)
3084 return;
3085
3087 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3088 {
3091 {
3092 construction.HandleEntityFalling(part.
GetPartName());
3093 }
3094 }
3095 }
3096
3099 {
3101 return;
3102
3105
3106 if (DestroyOnFall())
3107 {
3109 {
3111 }
3112 else
3113 {
3115 {
3117 }
3119 }
3120 }
3121 }
3122
3124 {
3125 if (HasAnyAttachmentsOrCargo())
3126 {
3129 }
3130 }
3131
3132
3133
3134
3135
3138 {
3139 return null;
3140 }
3141
3143 {
3145 }
3146
3148 {
3151
3152 Man p;
3153
3154 #ifdef SERVER
3156 g_Game.GetWorld().GetPlayerList(players);
3157 if (players.Count())
3158 p = players[0];
3159 #else
3161 #endif
3162
3164 {
3165 bool excluded = false;
3167 if (excludes)
3168 {
3169 foreach (string exclude : excludes)
3170 {
3172 {
3173 excluded = true;
3174 break;
3175 }
3176 }
3177 }
3178
3179 if (!excluded)
3180 {
3182 }
3183 }
3184
3186 }
3187
3189
3191 [
Obsolete(
"handled in the Construction component directly")]
3193 {
3194 }
3195
3196 [
Obsolete(
"handled in the Construction component directly")]
3198 {
3199 }
3200
3201 [
Obsolete(
"obsolete debug method")]
3203 {
3204 }
3205}
3206
3208{
3209#ifdef BSB_DEBUG
3211#else
3212
3213#endif
3214}
3216{
3217#ifdef BSB_DEBUG_SPAM
3219#else
3220
3221#endif
3222}
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.