2355{
2357
2359
2361
2368
2369
2370
2376
2382
2384
2388
2389
2391 {
2393
2394
2395 RegisterNetSyncVariableInt( "m_SyncParts01" );
2396 RegisterNetSyncVariableInt( "m_SyncParts02" );
2397 RegisterNetSyncVariableInt( "m_SyncParts03" );
2398 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2399 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2400 RegisterNetSyncVariableBool( "m_HasBase" );
2401
2402
2403 ConstructionInit();
2404
2405 if (ConfigIsExisting("hybridAttachments"))
2406 {
2409 }
2410 if (ConfigIsExisting("mountables"))
2411 {
2414 }
2415
2417 SetAllowDamage(true);
2418 }
2419
2421 {
2422 return "disableBaseDamage";
2423 }
2424
2426 {
2427 return true;
2428 }
2429
2431 {
2432 return EInventoryIconVisibility.HIDE_VICINITY;
2433 }
2434
2436 {
2437 super.InitItemSounds();
2438
2442
2447 }
2448
2450 {
2451 return "putDown_FenceKit_SoundSet";
2452 }
2453
2455 {
2456 return "Shelter_Site_Build_Loop_SoundSet";
2457 }
2458
2459
2461 {
2463 {
2464 SetSynchDirty();
2465 }
2466 }
2467
2469 {
2471 super.OnVariablesSynchronized();
2472
2474 }
2475
2477 {
2478
2480
2481
2483
2484
2486 }
2487
2488
2490 {
2491
2492 int offset;
2493 int mask;
2494
2495 if ( part_id >= 1 && part_id <= 31 )
2496 {
2497 offset = part_id - 1;
2498 mask = 1 << offset;
2499
2501 }
2502 else if ( part_id >= 32 && part_id <= 62 )
2503 {
2504 offset = ( part_id % 32 );
2505 mask = 1 << offset;
2506
2508 }
2509 else if ( part_id >= 63 && part_id <= 93 )
2510 {
2511 offset = ( part_id % 63 );
2512 mask = 1 << offset;
2513
2515 }
2516 }
2517
2519 {
2520
2521 int offset;
2522 int mask;
2523
2524 if ( part_id >= 1 && part_id <= 31 )
2525 {
2526 offset = part_id - 1;
2527 mask = 1 << offset;
2528
2530 }
2531 else if ( part_id >= 32 && part_id <= 62 )
2532 {
2533 offset = ( part_id % 32 );
2534 mask = 1 << offset;
2535
2537 }
2538 else if ( part_id >= 63 && part_id <= 93 )
2539 {
2540 offset = ( part_id % 63 );
2541 mask = 1 << offset;
2542
2544 }
2545 }
2546
2548 {
2549
2550 int offset;
2551 int mask;
2552
2553 if ( part_id >= 1 && part_id <= 31 )
2554 {
2555 offset = part_id - 1;
2556 mask = 1 << offset;
2557
2559 {
2560 return true;
2561 }
2562 }
2563 else if ( part_id >= 32 && part_id <= 62 )
2564 {
2565 offset = ( part_id % 32 );
2566 mask = 1 << offset;
2567
2569 {
2570 return true;
2571 }
2572 }
2573 else if ( part_id >= 63 && part_id <= 93 )
2574 {
2575 offset = ( part_id % 63 );
2576 mask = 1 << offset;
2577
2579 {
2580 return true;
2581 }
2582 }
2583
2584 return false;
2585 }
2586
2588 {
2591 }
2592
2594 {
2595
2598 }
2599
2601 {
2603 {
2606
2607 switch( build_action_id )
2608 {
2612 }
2613 }
2614 }
2615
2616
2618 {
2620 bool is_base = part.
IsBase();
2623 if ( is_part_built_sync )
2624 {
2626 {
2630
2631 if (is_base)
2632 {
2635 }
2636 }
2637 }
2638 else
2639 {
2641 {
2645
2646 if (is_base)
2647 {
2650 }
2651 }
2652 }
2653
2654
2656 }
2657
2658
2660 {
2663
2664 for ( int i = 0; i < construction_parts.Count(); ++i )
2665 {
2666 string key = construction_parts.GetKey( i );
2669 }
2670
2671
2673 }
2674
2676 {
2679
2680 for ( int i = 0; i < construction_parts.Count(); ++i )
2681 {
2682 string key = construction_parts.GetKey( i );
2684
2685 if ( value.
GetId() ==
id )
2686 {
2687 return value;
2688 }
2689 }
2690
2691 return NULL;
2692 }
2693
2694
2695
2697 {
2699 }
2700
2702 {
2704 }
2705
2707 {
2708 return true;
2709 }
2710
2712 {
2713 return false;
2714 }
2715
2716
2718 {
2721 {
2723 }
2724
2725 return construction_kit;
2726 }
2727
2729 {
2732 {
2734 }
2735 }
2736
2738 {
2740 }
2741
2743 {
2744 return "";
2745 }
2746
2748 {
2750 g_Game.ObjectDelete( construction_kit );
2751 }
2752
2753
2755 {
2757 g_Game.ObjectDelete(
this );
2758 }
2759
2760
2762 {
2763 super.EEDelete(parent);
2764
2766 {
2767 areaDamage.Destroy();
2768 }
2769
2770 }
2771
2773 {
2774 super.OnStoreSave( ctx );
2775
2776
2780
2782 }
2783
2785 {
2786 if ( !super.OnStoreLoad( ctx, version ) )
2787 return false;
2788
2789
2790
2792 {
2794 return false;
2795 }
2797 {
2799 return false;
2800 }
2802 {
2804 return false;
2805 }
2806
2807
2809 {
2811 return false;
2812 }
2813
2814
2815 return true;
2816 }
2817
2819 {
2820 super.AfterStoreLoad();
2821
2823 {
2825 }
2826 }
2827
2829 {
2830
2832
2833
2836
2837
2839 }
2840
2842 {
2843 super.OnCreatePhysics();
2844
2845 ConstructionInit();
2847 }
2848
2850 {
2852 return;
2853
2854 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2855 }
2856
2858 {
2860 {
2862 }
2863
2864 super.EEOnAfterLoad();
2865 }
2866
2868 {
2869 super.EEItemAttached( item, slot_name );
2870
2874 }
2875
2877 {
2878 super.EEItemDetached( item, slot_name );
2879
2882 }
2883
2884 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2885 {
2888
2891 }
2892
2893
2895 {
2896 return true;
2897 }
2898
2899
2900
2902 {
2904
2905
2906 if (construtionPart.
IsBase())
2907 {
2909
2910
2912 }
2913
2914
2916
2917
2919
2920
2922
2924
2926
2927
2929
2930
2932 }
2933
2935 {
2936
2938 }
2939
2940
2942 {
2945
2946
2948
2949
2951
2952
2954
2955
2957
2959
2960
2962
2963
2965
2966
2967 if (construtionPart.
IsBase())
2968 {
2969
2971 }
2972 }
2973
2975 {
2976
2978 }
2979
2980
2981 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2982 {
2985
2986
2988
2989
2991
2992
2994
2995
2997
2999
3000
3002
3003
3005
3006
3007 if (construtionPart.
IsBase())
3008 {
3009
3011 }
3012 }
3013
3015 {
3016
3018 }
3019
3020
3022 {
3024
3027 }
3028
3030 {
3032
3034 {
3036 }
3037 else
3038 {
3040 }
3041
3043 }
3044
3046 {
3048
3050 foreach (
string slotName : attachmentSlots)
3051 {
3053 }
3054
3055
3058 else
3060
3062 }
3063
3065 {
3066 string slotNameMounted = slot_name + "_Mounted";
3067 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3068
3069 if (attachment)
3070 {
3071 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3072 if (barbedWire && barbedWire.IsMounted())
3074 else
3076
3077 if (is_locked)
3078 {
3079 SetAnimationPhase(slotNameMounted, 0);
3080 SetAnimationPhase(slot_name, 1);
3081 }
3082 else
3083 {
3084 SetAnimationPhase(slotNameMounted, 1);
3085 SetAnimationPhase(slot_name, 0);
3086 }
3087 }
3088 else
3089 {
3090 SetAnimationPhase(slotNameMounted, 1);
3091 SetAnimationPhase(slot_name, 1);
3092
3094 }
3095 }
3096
3097
3099 {
3102
3105
3108
3109 foreach (
string slotName : attachmentSlots)
3110 {
3112 }
3113
3114
3116 {
3119
3121 }
3122 else
3123 {
3126
3128 }
3129
3132 }
3133
3135 {
3136
3138 return;
3139
3140 string slot_name_mounted = slot_name + "_Mounted";
3141 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3142
3143
3145 RemoveProxyPhysics( slot_name_mounted );
3146 RemoveProxyPhysics( slot_name );
3147
3148 if ( attachment )
3149 {
3151 if ( is_locked )
3152 {
3154 AddProxyPhysics( slot_name_mounted );
3155 }
3156 else
3157 {
3159 AddProxyPhysics( slot_name );
3160 }
3161 }
3162 }
3163
3165 {
3166 SetAffectPathgraph( true, false );
3168 }
3169
3171 {
3172 return true;
3173 }
3174
3176 {
3177 return true;
3178 }
3179
3181 {
3182 if ( attachment )
3183 {
3185 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3186
3187 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3188 }
3189
3190 return false;
3191 }
3192
3194 {
3196 }
3197
3198
3200 {
3201 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3202 if (
g_Game.ConfigIsExisting( config_path ) )
3203 {
3204 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3205 }
3206 }
3207
3209 {
3210 return true;
3211 }
3212
3214 {
3215 return true;
3216 }
3217
3219 {
3220 return true;
3221 }
3222
3223
3225 {
3228 }
3229
3231 {
3233 }
3234
3236 {
3238 }
3239
3241 {
3242 int attachment_count = GetInventory().AttachmentCount();
3243 if ( attachment_count > 0 )
3244 {
3245 if (
HasBase() && attachment_count == 1 )
3246 {
3247 return false;
3248 }
3249
3250 return true;
3251 }
3252
3253 return false;
3254 }
3255
3257 {
3258 return true;
3259 }
3260
3262 {
3263 return false;
3264 }
3265
3266
3268 {
3269 return false;
3270 }
3271
3273 {
3274 return false;
3275 }
3276
3277
3279 {
3280 return false;
3281 }
3282
3283
3284
3286 {
3287 return true;
3288 }
3289
3291 {
3292 return true;
3293 }
3294
3297 {
3298 return false;
3299 }
3300
3301
3303 {
3304 return false;
3305 }
3306
3307
3309 {
3310 return true;
3311 }
3312
3313
3315 {
3316 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3317 {
3318 return false;
3319 }
3320
3321 return true;
3322 }
3323
3325 {
3328
3329 return item;
3330 }
3331
3332
3334 {
3336 {
3337
3339
3340
3343
3345 if ( MemoryPointExists( slot_name + "_min" ) )
3346 {
3347 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3348 }
3349 if ( MemoryPointExists( slot_name + "_max" ) )
3350 {
3351 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3352 }
3353
3354
3357
3358
3361 center = ModelToWorld( center );
3362
3363
3366
3367 areaDamage.SetExtents( extents[0], extents[1] );
3368 areaDamage.SetAreaPosition( center );
3372 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3373 areaDamage.SetAmmoName( "BarbedWireHit" );
3374 areaDamage.Spawn();
3375
3377 }
3378 }
3379
3381 {
3382 if ( angle_deg != 0 )
3383 {
3384
3386
3387
3389 if ( MemoryPointExists( "rotate_axis" ) )
3390 {
3391 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3392 }
3393 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];
3394 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];
3395 center[0] = r_center_x;
3396 center[2] = r_center_z;
3397 }
3398 }
3399
3401 {
3403 {
3406 {
3407 if (areaDamage)
3408 {
3409 areaDamage.Destroy();
3410 }
3411
3413 }
3414 }
3415 }
3416
3418 {
3419 return true;
3420 }
3421
3422
3423
3424
3426 {
3428 }
3429
3431 {
3433 }
3434
3436 {
3438 }
3439
3441 {
3443
3444 switch ( material_type )
3445 {
3451 }
3452
3453 return "";
3454 }
3455
3457 {
3459
3460 switch ( material_type )
3461 {
3467 }
3468
3469 return "";
3470 }
3471
3472
3474 {
3476 {
3477
3479 {
3480 SetHealth(slot_name,"Health",item.GetHealth());
3481 }
3482 }
3483 }
3484
3486 {
3487 return 111;
3488 }
3489
3491 {
3492 super.SetActions();
3493
3497 }
3498
3500 {
3502 if (!construction)
3503 return;
3504
3506 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3507 {
3510 {
3512 }
3513 }
3514 }
3515
3517 {
3519 if (!construction)
3520 return;
3521
3523 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3524 {
3527 {
3528 construction.HandleEntityFalling(part.
GetPartName());
3529 }
3530 }
3531 }
3532
3535 {
3537 return;
3538
3541
3542 if (DestroyOnFall())
3543 {
3545 {
3547 }
3548 else
3549 {
3551 {
3553 }
3555 }
3556 }
3557 }
3558
3560 {
3561 if (HasAnyAttachmentsOrCargo())
3562 {
3565 }
3566 }
3567
3568
3569
3570
3571
3574 {
3575 return null;
3576 }
3577
3579 {
3581 }
3582
3584 {
3587
3588 Man p;
3589
3590 #ifdef SERVER
3592 g_Game.GetWorld().GetPlayerList(players);
3593 if (players.Count())
3594 p = players[0];
3595 #else
3597 #endif
3598
3600 {
3601 bool excluded = false;
3603 if (excludes)
3604 {
3605 foreach (string exclude : excludes)
3606 {
3608 {
3609 excluded = true;
3610 break;
3611 }
3612 }
3613 }
3614
3615 if (!excluded)
3616 {
3618 }
3619 }
3620
3622 }
3623
3625
3627 [
Obsolete(
"handled in the Construction component directly")]
3629 {
3630 }
3631
3632 [
Obsolete(
"handled in the Construction component directly")]
3634 {
3635 }
3636
3637 [
Obsolete(
"obsolete debug method")]
3639 {
3640 }
3641}
3642
3644{
3645#ifdef BSB_DEBUG
3647#else
3648
3649#endif
3650}
3652{
3653#ifdef BSB_DEBUG_SPAM
3655#else
3656
3657#endif
3658}
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.