2156{
2158
2160
2162
2169
2170
2171
2177
2183
2185
2189
2190
2192 {
2194
2195
2196 RegisterNetSyncVariableInt( "m_SyncParts01" );
2197 RegisterNetSyncVariableInt( "m_SyncParts02" );
2198 RegisterNetSyncVariableInt( "m_SyncParts03" );
2199 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2200 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2201 RegisterNetSyncVariableBool( "m_HasBase" );
2202
2203
2204 ConstructionInit();
2205
2206 if (ConfigIsExisting("hybridAttachments"))
2207 {
2210 }
2211 if (ConfigIsExisting("mountables"))
2212 {
2215 }
2216
2218 SetAllowDamage(true);
2219 }
2220
2222 {
2223 return "disableBaseDamage";
2224 }
2225
2227 {
2228 return true;
2229 }
2230
2232 {
2233 return EInventoryIconVisibility.HIDE_VICINITY;
2234 }
2235
2237 {
2238 super.InitItemSounds();
2239
2243
2248 }
2249
2251 {
2252 return "putDown_FenceKit_SoundSet";
2253 }
2254
2256 {
2257 return "Shelter_Site_Build_Loop_SoundSet";
2258 }
2259
2260
2262 {
2264 {
2265 SetSynchDirty();
2266 }
2267 }
2268
2270 {
2272 super.OnVariablesSynchronized();
2273
2275 }
2276
2278 {
2279
2281
2282
2284
2285
2287 }
2288
2289
2291 {
2292
2293 int offset;
2294 int mask;
2295
2296 if ( part_id >= 1 && part_id <= 31 )
2297 {
2298 offset = part_id - 1;
2299 mask = 1 << offset;
2300
2302 }
2303 else if ( part_id >= 32 && part_id <= 62 )
2304 {
2305 offset = ( part_id % 32 );
2306 mask = 1 << offset;
2307
2309 }
2310 else if ( part_id >= 63 && part_id <= 93 )
2311 {
2312 offset = ( part_id % 63 );
2313 mask = 1 << offset;
2314
2316 }
2317 }
2318
2320 {
2321
2322 int offset;
2323 int mask;
2324
2325 if ( part_id >= 1 && part_id <= 31 )
2326 {
2327 offset = part_id - 1;
2328 mask = 1 << offset;
2329
2331 }
2332 else if ( part_id >= 32 && part_id <= 62 )
2333 {
2334 offset = ( part_id % 32 );
2335 mask = 1 << offset;
2336
2338 }
2339 else if ( part_id >= 63 && part_id <= 93 )
2340 {
2341 offset = ( part_id % 63 );
2342 mask = 1 << offset;
2343
2345 }
2346 }
2347
2349 {
2350
2351 int offset;
2352 int mask;
2353
2354 if ( part_id >= 1 && part_id <= 31 )
2355 {
2356 offset = part_id - 1;
2357 mask = 1 << offset;
2358
2360 {
2361 return true;
2362 }
2363 }
2364 else if ( part_id >= 32 && part_id <= 62 )
2365 {
2366 offset = ( part_id % 32 );
2367 mask = 1 << offset;
2368
2370 {
2371 return true;
2372 }
2373 }
2374 else if ( part_id >= 63 && part_id <= 93 )
2375 {
2376 offset = ( part_id % 63 );
2377 mask = 1 << offset;
2378
2380 {
2381 return true;
2382 }
2383 }
2384
2385 return false;
2386 }
2387
2389 {
2392 }
2393
2395 {
2396
2399 }
2400
2402 {
2404 {
2407
2408 switch( build_action_id )
2409 {
2413 }
2414 }
2415 }
2416
2417
2419 {
2421 bool is_base = part.
IsBase();
2424 if ( is_part_built_sync )
2425 {
2427 {
2431
2432 if (is_base)
2433 {
2436 }
2437 }
2438 }
2439 else
2440 {
2442 {
2446
2447 if (is_base)
2448 {
2451 }
2452 }
2453 }
2454
2455
2457 }
2458
2459
2461 {
2464
2465 for ( int i = 0; i < construction_parts.Count(); ++i )
2466 {
2467 string key = construction_parts.GetKey( i );
2470 }
2471
2472
2474 }
2475
2477 {
2480
2481 for ( int i = 0; i < construction_parts.Count(); ++i )
2482 {
2483 string key = construction_parts.GetKey( i );
2485
2486 if ( value.
GetId() ==
id )
2487 {
2488 return value;
2489 }
2490 }
2491
2492 return NULL;
2493 }
2494
2495
2496
2498 {
2500 }
2501
2503 {
2505 }
2506
2508 {
2509 return true;
2510 }
2511
2513 {
2514 return false;
2515 }
2516
2517
2519 {
2522 {
2524 }
2525
2526 return construction_kit;
2527 }
2528
2530 {
2533 {
2535 }
2536 }
2537
2539 {
2541 }
2542
2544 {
2545 return "";
2546 }
2547
2549 {
2551 g_Game.ObjectDelete( construction_kit );
2552 }
2553
2554
2556 {
2558 g_Game.ObjectDelete(
this );
2559 }
2560
2561
2563 {
2564 super.EEDelete(parent);
2565
2567 {
2568 areaDamage.Destroy();
2569 }
2570
2571 }
2572
2574 {
2575 super.OnStoreSave( ctx );
2576
2577
2581
2583 }
2584
2586 {
2587 if ( !super.OnStoreLoad( ctx, version ) )
2588 return false;
2589
2590
2591
2593 {
2595 return false;
2596 }
2598 {
2600 return false;
2601 }
2603 {
2605 return false;
2606 }
2607
2608
2610 {
2612 return false;
2613 }
2614
2615
2616 return true;
2617 }
2618
2620 {
2621 super.AfterStoreLoad();
2622
2624 {
2626 }
2627 }
2628
2630 {
2631
2633
2634
2637
2638
2640 }
2641
2643 {
2644 super.OnCreatePhysics();
2645
2646 ConstructionInit();
2648 }
2649
2651 {
2653 return;
2654
2655 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2656 }
2657
2659 {
2661 {
2663 }
2664
2665 super.EEOnAfterLoad();
2666 }
2667
2669 {
2670 super.EEItemAttached( item, slot_name );
2671
2675 }
2676
2678 {
2679 super.EEItemDetached( item, slot_name );
2680
2683 }
2684
2685 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2686 {
2689
2692 }
2693
2694
2696 {
2697 return true;
2698 }
2699
2700
2701
2703 {
2705
2706
2707 if (construtionPart.
IsBase())
2708 {
2710
2711
2713 }
2714
2715
2717
2718
2720
2721
2723
2725
2727
2728
2730
2731
2733 }
2734
2736 {
2737
2739 }
2740
2741
2743 {
2746
2747
2749
2750
2752
2753
2755
2756
2758
2760
2761
2763
2764
2766
2767
2768 if (construtionPart.
IsBase())
2769 {
2770
2772 }
2773 }
2774
2776 {
2777
2779 }
2780
2781
2782 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2783 {
2786
2787
2789
2790
2792
2793
2795
2796
2798
2800
2801
2803
2804
2806
2807
2808 if (construtionPart.
IsBase())
2809 {
2810
2812 }
2813 }
2814
2816 {
2817
2819 }
2820
2821
2823 {
2825
2828 }
2829
2831 {
2833
2835 {
2837 }
2838 else
2839 {
2841 }
2842
2844 }
2845
2847 {
2849
2851 foreach (
string slotName : attachmentSlots)
2852 {
2854 }
2855
2856
2859 else
2861
2863 }
2864
2866 {
2867 string slotNameMounted = slot_name + "_Mounted";
2868 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2869
2870 if (attachment)
2871 {
2872 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2873 if (barbedWire && barbedWire.IsMounted())
2875 else
2877
2878 if (is_locked)
2879 {
2880 SetAnimationPhase(slotNameMounted, 0);
2881 SetAnimationPhase(slot_name, 1);
2882 }
2883 else
2884 {
2885 SetAnimationPhase(slotNameMounted, 1);
2886 SetAnimationPhase(slot_name, 0);
2887 }
2888 }
2889 else
2890 {
2891 SetAnimationPhase(slotNameMounted, 1);
2892 SetAnimationPhase(slot_name, 1);
2893
2895 }
2896 }
2897
2898
2900 {
2903
2906
2909
2910 foreach (
string slotName : attachmentSlots)
2911 {
2913 }
2914
2915
2917 {
2920
2922 }
2923 else
2924 {
2927
2929 }
2930
2933 }
2934
2936 {
2937
2939 return;
2940
2941 string slot_name_mounted = slot_name + "_Mounted";
2942 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2943
2944
2946 RemoveProxyPhysics( slot_name_mounted );
2947 RemoveProxyPhysics( slot_name );
2948
2949 if ( attachment )
2950 {
2952 if ( is_locked )
2953 {
2955 AddProxyPhysics( slot_name_mounted );
2956 }
2957 else
2958 {
2960 AddProxyPhysics( slot_name );
2961 }
2962 }
2963 }
2964
2966 {
2967 SetAffectPathgraph( true, false );
2969 }
2970
2972 {
2973 return true;
2974 }
2975
2977 {
2978 return true;
2979 }
2980
2982 {
2983 if ( attachment )
2984 {
2986 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2987
2988 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2989 }
2990
2991 return false;
2992 }
2993
2995 {
2997 }
2998
2999
3001 {
3002 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3003 if (
g_Game.ConfigIsExisting( config_path ) )
3004 {
3005 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3006 }
3007 }
3008
3010 {
3011 return true;
3012 }
3013
3015 {
3016 return true;
3017 }
3018
3020 {
3021 return true;
3022 }
3023
3024
3026 {
3029 }
3030
3032 {
3034 }
3035
3037 {
3039 }
3040
3042 {
3043 int attachment_count = GetInventory().AttachmentCount();
3044 if ( attachment_count > 0 )
3045 {
3046 if (
HasBase() && attachment_count == 1 )
3047 {
3048 return false;
3049 }
3050
3051 return true;
3052 }
3053
3054 return false;
3055 }
3056
3058 {
3059 return true;
3060 }
3061
3063 {
3064 return false;
3065 }
3066
3067
3069 {
3070 return false;
3071 }
3072
3074 {
3075 return false;
3076 }
3077
3078
3080 {
3081 return false;
3082 }
3083
3084
3085
3087 {
3088 return true;
3089 }
3090
3092 {
3093 return true;
3094 }
3095
3098 {
3099 return false;
3100 }
3101
3102
3104 {
3105 return false;
3106 }
3107
3108
3110 {
3111 return true;
3112 }
3113
3114
3116 {
3117 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3118 {
3119 return false;
3120 }
3121
3122 return true;
3123 }
3124
3126 {
3129
3130 return item;
3131 }
3132
3133
3135 {
3137 {
3138
3140
3141
3144
3146 if ( MemoryPointExists( slot_name + "_min" ) )
3147 {
3148 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3149 }
3150 if ( MemoryPointExists( slot_name + "_max" ) )
3151 {
3152 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3153 }
3154
3155
3158
3159
3162 center = ModelToWorld( center );
3163
3164
3167
3168 areaDamage.SetExtents( extents[0], extents[1] );
3169 areaDamage.SetAreaPosition( center );
3173 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3174 areaDamage.SetAmmoName( "BarbedWireHit" );
3175 areaDamage.Spawn();
3176
3178 }
3179 }
3180
3182 {
3183 if ( angle_deg != 0 )
3184 {
3185
3187
3188
3190 if ( MemoryPointExists( "rotate_axis" ) )
3191 {
3192 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3193 }
3194 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];
3195 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];
3196 center[0] = r_center_x;
3197 center[2] = r_center_z;
3198 }
3199 }
3200
3202 {
3204 {
3207 {
3208 if (areaDamage)
3209 {
3210 areaDamage.Destroy();
3211 }
3212
3214 }
3215 }
3216 }
3217
3219 {
3220 return true;
3221 }
3222
3223
3224
3225
3227 {
3229 }
3230
3232 {
3234 }
3235
3237 {
3239 }
3240
3242 {
3244
3245 switch ( material_type )
3246 {
3252 }
3253
3254 return "";
3255 }
3256
3258 {
3260
3261 switch ( material_type )
3262 {
3268 }
3269
3270 return "";
3271 }
3272
3273
3275 {
3277 {
3278
3280 {
3281 SetHealth(slot_name,"Health",item.GetHealth());
3282 }
3283 }
3284 }
3285
3287 {
3288 return 111;
3289 }
3290
3292 {
3293 super.SetActions();
3294
3298 }
3299
3301 {
3303 if (!construction)
3304 return;
3305
3307 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3308 {
3311 {
3313 }
3314 }
3315 }
3316
3318 {
3320 if (!construction)
3321 return;
3322
3324 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3325 {
3328 {
3329 construction.HandleEntityFalling(part.
GetPartName());
3330 }
3331 }
3332 }
3333
3336 {
3338 return;
3339
3342
3343 if (DestroyOnFall())
3344 {
3346 {
3348 }
3349 else
3350 {
3352 {
3354 }
3356 }
3357 }
3358 }
3359
3361 {
3362 if (HasAnyAttachmentsOrCargo())
3363 {
3366 }
3367 }
3368
3369
3370
3371
3372
3375 {
3376 return null;
3377 }
3378
3380 {
3382 }
3383
3385 {
3388
3389 Man p;
3390
3391 #ifdef SERVER
3393 g_Game.GetWorld().GetPlayerList(players);
3394 if (players.Count())
3395 p = players[0];
3396 #else
3398 #endif
3399
3401 {
3402 bool excluded = false;
3404 if (excludes)
3405 {
3406 foreach (string exclude : excludes)
3407 {
3409 {
3410 excluded = true;
3411 break;
3412 }
3413 }
3414 }
3415
3416 if (!excluded)
3417 {
3419 }
3420 }
3421
3423 }
3424
3426
3428 [
Obsolete(
"handled in the Construction component directly")]
3430 {
3431 }
3432
3433 [
Obsolete(
"handled in the Construction component directly")]
3435 {
3436 }
3437
3438 [
Obsolete(
"obsolete debug method")]
3440 {
3441 }
3442}
3443
3445{
3446#ifdef BSB_DEBUG
3448#else
3449
3450#endif
3451}
3453{
3454#ifdef BSB_DEBUG_SPAM
3456#else
3457
3458#endif
3459}
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.