2252{
2254
2256
2258
2265
2266
2267
2273
2279
2281
2285
2286
2288 {
2290
2291
2292 RegisterNetSyncVariableInt( "m_SyncParts01" );
2293 RegisterNetSyncVariableInt( "m_SyncParts02" );
2294 RegisterNetSyncVariableInt( "m_SyncParts03" );
2295 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2296 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2297 RegisterNetSyncVariableBool( "m_HasBase" );
2298
2299
2300 ConstructionInit();
2301
2302 if (ConfigIsExisting("hybridAttachments"))
2303 {
2306 }
2307 if (ConfigIsExisting("mountables"))
2308 {
2311 }
2312
2314 SetAllowDamage(true);
2315 }
2316
2318 {
2319 return "disableBaseDamage";
2320 }
2321
2323 {
2324 return true;
2325 }
2326
2328 {
2329 return EInventoryIconVisibility.HIDE_VICINITY;
2330 }
2331
2333 {
2334 super.InitItemSounds();
2335
2339
2344 }
2345
2347 {
2348 return "putDown_FenceKit_SoundSet";
2349 }
2350
2352 {
2353 return "Shelter_Site_Build_Loop_SoundSet";
2354 }
2355
2356
2358 {
2360 {
2361 SetSynchDirty();
2362 }
2363 }
2364
2366 {
2368 super.OnVariablesSynchronized();
2369
2371 }
2372
2374 {
2375
2377
2378
2380
2381
2383 }
2384
2385
2387 {
2388
2389 int offset;
2390 int mask;
2391
2392 if ( part_id >= 1 && part_id <= 31 )
2393 {
2394 offset = part_id - 1;
2395 mask = 1 << offset;
2396
2398 }
2399 else if ( part_id >= 32 && part_id <= 62 )
2400 {
2401 offset = ( part_id % 32 );
2402 mask = 1 << offset;
2403
2405 }
2406 else if ( part_id >= 63 && part_id <= 93 )
2407 {
2408 offset = ( part_id % 63 );
2409 mask = 1 << offset;
2410
2412 }
2413 }
2414
2416 {
2417
2418 int offset;
2419 int mask;
2420
2421 if ( part_id >= 1 && part_id <= 31 )
2422 {
2423 offset = part_id - 1;
2424 mask = 1 << offset;
2425
2427 }
2428 else if ( part_id >= 32 && part_id <= 62 )
2429 {
2430 offset = ( part_id % 32 );
2431 mask = 1 << offset;
2432
2434 }
2435 else if ( part_id >= 63 && part_id <= 93 )
2436 {
2437 offset = ( part_id % 63 );
2438 mask = 1 << offset;
2439
2441 }
2442 }
2443
2445 {
2446
2447 int offset;
2448 int mask;
2449
2450 if ( part_id >= 1 && part_id <= 31 )
2451 {
2452 offset = part_id - 1;
2453 mask = 1 << offset;
2454
2456 {
2457 return true;
2458 }
2459 }
2460 else if ( part_id >= 32 && part_id <= 62 )
2461 {
2462 offset = ( part_id % 32 );
2463 mask = 1 << offset;
2464
2466 {
2467 return true;
2468 }
2469 }
2470 else if ( part_id >= 63 && part_id <= 93 )
2471 {
2472 offset = ( part_id % 63 );
2473 mask = 1 << offset;
2474
2476 {
2477 return true;
2478 }
2479 }
2480
2481 return false;
2482 }
2483
2485 {
2488 }
2489
2491 {
2492
2495 }
2496
2498 {
2500 {
2503
2504 switch( build_action_id )
2505 {
2509 }
2510 }
2511 }
2512
2513
2515 {
2517 bool is_base = part.
IsBase();
2520 if ( is_part_built_sync )
2521 {
2523 {
2527
2528 if (is_base)
2529 {
2532 }
2533 }
2534 }
2535 else
2536 {
2538 {
2542
2543 if (is_base)
2544 {
2547 }
2548 }
2549 }
2550
2551
2553 }
2554
2555
2557 {
2560
2561 for ( int i = 0; i < construction_parts.Count(); ++i )
2562 {
2563 string key = construction_parts.GetKey( i );
2566 }
2567
2568
2570 }
2571
2573 {
2576
2577 for ( int i = 0; i < construction_parts.Count(); ++i )
2578 {
2579 string key = construction_parts.GetKey( i );
2581
2582 if ( value.
GetId() ==
id )
2583 {
2584 return value;
2585 }
2586 }
2587
2588 return NULL;
2589 }
2590
2591
2592
2594 {
2596 }
2597
2599 {
2601 }
2602
2604 {
2605 return true;
2606 }
2607
2609 {
2610 return false;
2611 }
2612
2613
2615 {
2618 {
2620 }
2621
2622 return construction_kit;
2623 }
2624
2626 {
2629 {
2631 }
2632 }
2633
2635 {
2637 }
2638
2640 {
2641 return "";
2642 }
2643
2645 {
2647 g_Game.ObjectDelete( construction_kit );
2648 }
2649
2650
2652 {
2654 g_Game.ObjectDelete(
this );
2655 }
2656
2657
2659 {
2660 super.EEDelete(parent);
2661
2663 {
2664 areaDamage.Destroy();
2665 }
2666
2667 }
2668
2670 {
2671 super.OnStoreSave( ctx );
2672
2673
2677
2679 }
2680
2682 {
2683 if ( !super.OnStoreLoad( ctx, version ) )
2684 return false;
2685
2686
2687
2689 {
2691 return false;
2692 }
2694 {
2696 return false;
2697 }
2699 {
2701 return false;
2702 }
2703
2704
2706 {
2708 return false;
2709 }
2710
2711
2712 return true;
2713 }
2714
2716 {
2717 super.AfterStoreLoad();
2718
2720 {
2722 }
2723 }
2724
2726 {
2727
2729
2730
2733
2734
2736 }
2737
2739 {
2740 super.OnCreatePhysics();
2741
2742 ConstructionInit();
2744 }
2745
2747 {
2749 return;
2750
2751 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2752 }
2753
2755 {
2757 {
2759 }
2760
2761 super.EEOnAfterLoad();
2762 }
2763
2765 {
2766 super.EEItemAttached( item, slot_name );
2767
2771 }
2772
2774 {
2775 super.EEItemDetached( item, slot_name );
2776
2779 }
2780
2781 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2782 {
2785
2788 }
2789
2790
2792 {
2793 return true;
2794 }
2795
2796
2797
2799 {
2801
2802
2803 if (construtionPart.
IsBase())
2804 {
2806
2807
2809 }
2810
2811
2813
2814
2816
2817
2819
2821
2823
2824
2826
2827
2829 }
2830
2832 {
2833
2835 }
2836
2837
2839 {
2842
2843
2845
2846
2848
2849
2851
2852
2854
2856
2857
2859
2860
2862
2863
2864 if (construtionPart.
IsBase())
2865 {
2866
2868 }
2869 }
2870
2872 {
2873
2875 }
2876
2877
2878 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2879 {
2882
2883
2885
2886
2888
2889
2891
2892
2894
2896
2897
2899
2900
2902
2903
2904 if (construtionPart.
IsBase())
2905 {
2906
2908 }
2909 }
2910
2912 {
2913
2915 }
2916
2917
2919 {
2921
2924 }
2925
2927 {
2929
2931 {
2933 }
2934 else
2935 {
2937 }
2938
2940 }
2941
2943 {
2945
2947 foreach (
string slotName : attachmentSlots)
2948 {
2950 }
2951
2952
2955 else
2957
2959 }
2960
2962 {
2963 string slotNameMounted = slot_name + "_Mounted";
2964 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2965
2966 if (attachment)
2967 {
2968 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2969 if (barbedWire && barbedWire.IsMounted())
2971 else
2973
2974 if (is_locked)
2975 {
2976 SetAnimationPhase(slotNameMounted, 0);
2977 SetAnimationPhase(slot_name, 1);
2978 }
2979 else
2980 {
2981 SetAnimationPhase(slotNameMounted, 1);
2982 SetAnimationPhase(slot_name, 0);
2983 }
2984 }
2985 else
2986 {
2987 SetAnimationPhase(slotNameMounted, 1);
2988 SetAnimationPhase(slot_name, 1);
2989
2991 }
2992 }
2993
2994
2996 {
2999
3002
3005
3006 foreach (
string slotName : attachmentSlots)
3007 {
3009 }
3010
3011
3013 {
3016
3018 }
3019 else
3020 {
3023
3025 }
3026
3029 }
3030
3032 {
3033
3035 return;
3036
3037 string slot_name_mounted = slot_name + "_Mounted";
3038 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3039
3040
3042 RemoveProxyPhysics( slot_name_mounted );
3043 RemoveProxyPhysics( slot_name );
3044
3045 if ( attachment )
3046 {
3048 if ( is_locked )
3049 {
3051 AddProxyPhysics( slot_name_mounted );
3052 }
3053 else
3054 {
3056 AddProxyPhysics( slot_name );
3057 }
3058 }
3059 }
3060
3062 {
3063 SetAffectPathgraph( true, false );
3065 }
3066
3068 {
3069 return true;
3070 }
3071
3073 {
3074 return true;
3075 }
3076
3078 {
3079 if ( attachment )
3080 {
3082 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3083
3084 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3085 }
3086
3087 return false;
3088 }
3089
3091 {
3093 }
3094
3095
3097 {
3098 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3099 if (
g_Game.ConfigIsExisting( config_path ) )
3100 {
3101 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3102 }
3103 }
3104
3106 {
3107 return true;
3108 }
3109
3111 {
3112 return true;
3113 }
3114
3116 {
3117 return true;
3118 }
3119
3120
3122 {
3125 }
3126
3128 {
3130 }
3131
3133 {
3135 }
3136
3138 {
3139 int attachment_count = GetInventory().AttachmentCount();
3140 if ( attachment_count > 0 )
3141 {
3142 if (
HasBase() && attachment_count == 1 )
3143 {
3144 return false;
3145 }
3146
3147 return true;
3148 }
3149
3150 return false;
3151 }
3152
3154 {
3155 return true;
3156 }
3157
3159 {
3160 return false;
3161 }
3162
3163
3165 {
3166 return false;
3167 }
3168
3170 {
3171 return false;
3172 }
3173
3174
3176 {
3177 return false;
3178 }
3179
3180
3181
3183 {
3184 return true;
3185 }
3186
3188 {
3189 return true;
3190 }
3191
3194 {
3195 return false;
3196 }
3197
3198
3200 {
3201 return false;
3202 }
3203
3204
3206 {
3207 return true;
3208 }
3209
3210
3212 {
3213 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3214 {
3215 return false;
3216 }
3217
3218 return true;
3219 }
3220
3222 {
3225
3226 return item;
3227 }
3228
3229
3231 {
3233 {
3234
3236
3237
3240
3242 if ( MemoryPointExists( slot_name + "_min" ) )
3243 {
3244 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3245 }
3246 if ( MemoryPointExists( slot_name + "_max" ) )
3247 {
3248 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3249 }
3250
3251
3254
3255
3258 center = ModelToWorld( center );
3259
3260
3263
3264 areaDamage.SetExtents( extents[0], extents[1] );
3265 areaDamage.SetAreaPosition( center );
3269 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3270 areaDamage.SetAmmoName( "BarbedWireHit" );
3271 areaDamage.Spawn();
3272
3274 }
3275 }
3276
3278 {
3279 if ( angle_deg != 0 )
3280 {
3281
3283
3284
3286 if ( MemoryPointExists( "rotate_axis" ) )
3287 {
3288 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3289 }
3290 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];
3291 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];
3292 center[0] = r_center_x;
3293 center[2] = r_center_z;
3294 }
3295 }
3296
3298 {
3300 {
3303 {
3304 if (areaDamage)
3305 {
3306 areaDamage.Destroy();
3307 }
3308
3310 }
3311 }
3312 }
3313
3315 {
3316 return true;
3317 }
3318
3319
3320
3321
3323 {
3325 }
3326
3328 {
3330 }
3331
3333 {
3335 }
3336
3338 {
3340
3341 switch ( material_type )
3342 {
3348 }
3349
3350 return "";
3351 }
3352
3354 {
3356
3357 switch ( material_type )
3358 {
3364 }
3365
3366 return "";
3367 }
3368
3369
3371 {
3373 {
3374
3376 {
3377 SetHealth(slot_name,"Health",item.GetHealth());
3378 }
3379 }
3380 }
3381
3383 {
3384 return 111;
3385 }
3386
3388 {
3389 super.SetActions();
3390
3394 }
3395
3397 {
3399 if (!construction)
3400 return;
3401
3403 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3404 {
3407 {
3409 }
3410 }
3411 }
3412
3414 {
3416 if (!construction)
3417 return;
3418
3420 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3421 {
3424 {
3425 construction.HandleEntityFalling(part.
GetPartName());
3426 }
3427 }
3428 }
3429
3432 {
3434 return;
3435
3438
3439 if (DestroyOnFall())
3440 {
3442 {
3444 }
3445 else
3446 {
3448 {
3450 }
3452 }
3453 }
3454 }
3455
3457 {
3458 if (HasAnyAttachmentsOrCargo())
3459 {
3462 }
3463 }
3464
3465
3466
3467
3468
3471 {
3472 return null;
3473 }
3474
3476 {
3478 }
3479
3481 {
3484
3485 Man p;
3486
3487 #ifdef SERVER
3489 g_Game.GetWorld().GetPlayerList(players);
3490 if (players.Count())
3491 p = players[0];
3492 #else
3494 #endif
3495
3497 {
3498 bool excluded = false;
3500 if (excludes)
3501 {
3502 foreach (string exclude : excludes)
3503 {
3505 {
3506 excluded = true;
3507 break;
3508 }
3509 }
3510 }
3511
3512 if (!excluded)
3513 {
3515 }
3516 }
3517
3519 }
3520
3522
3524 [
Obsolete(
"handled in the Construction component directly")]
3526 {
3527 }
3528
3529 [
Obsolete(
"handled in the Construction component directly")]
3531 {
3532 }
3533
3534 [
Obsolete(
"obsolete debug method")]
3536 {
3537 }
3538}
3539
3541{
3542#ifdef BSB_DEBUG
3544#else
3545
3546#endif
3547}
3549{
3550#ifdef BSB_DEBUG_SPAM
3552#else
3553
3554#endif
3555}
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.