2472{
2474
2476
2478
2485
2486
2487
2493
2499
2501
2505
2506
2508 {
2510
2511
2512 RegisterNetSyncVariableInt( "m_SyncParts01" );
2513 RegisterNetSyncVariableInt( "m_SyncParts02" );
2514 RegisterNetSyncVariableInt( "m_SyncParts03" );
2515 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2516 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2517 RegisterNetSyncVariableBool( "m_HasBase" );
2518
2519
2520 ConstructionInit();
2521
2522 if (ConfigIsExisting("hybridAttachments"))
2523 {
2526 }
2527 if (ConfigIsExisting("mountables"))
2528 {
2531 }
2532
2534 SetAllowDamage(true);
2535 }
2536
2538 {
2539 return "disableBaseDamage";
2540 }
2541
2543 {
2544 return true;
2545 }
2546
2548 {
2549 return EInventoryIconVisibility.HIDE_VICINITY;
2550 }
2551
2553 {
2554 super.InitItemSounds();
2555
2559
2564 }
2565
2567 {
2568 return "putDown_FenceKit_SoundSet";
2569 }
2570
2572 {
2573 return "Shelter_Site_Build_Loop_SoundSet";
2574 }
2575
2576
2578 {
2580 {
2581 SetSynchDirty();
2582 }
2583 }
2584
2586 {
2588 super.OnVariablesSynchronized();
2589
2591 }
2592
2594 {
2595
2597
2598
2600
2601
2603 }
2604
2605
2607 {
2608
2609 int offset;
2610 int mask;
2611
2612 if ( part_id >= 1 && part_id <= 31 )
2613 {
2614 offset = part_id - 1;
2615 mask = 1 << offset;
2616
2618 }
2619 else if ( part_id >= 32 && part_id <= 62 )
2620 {
2621 offset = ( part_id % 32 );
2622 mask = 1 << offset;
2623
2625 }
2626 else if ( part_id >= 63 && part_id <= 93 )
2627 {
2628 offset = ( part_id % 63 );
2629 mask = 1 << offset;
2630
2632 }
2633 }
2634
2636 {
2637
2638 int offset;
2639 int mask;
2640
2641 if ( part_id >= 1 && part_id <= 31 )
2642 {
2643 offset = part_id - 1;
2644 mask = 1 << offset;
2645
2647 }
2648 else if ( part_id >= 32 && part_id <= 62 )
2649 {
2650 offset = ( part_id % 32 );
2651 mask = 1 << offset;
2652
2654 }
2655 else if ( part_id >= 63 && part_id <= 93 )
2656 {
2657 offset = ( part_id % 63 );
2658 mask = 1 << offset;
2659
2661 }
2662 }
2663
2665 {
2666
2667 int offset;
2668 int mask;
2669
2670 if ( part_id >= 1 && part_id <= 31 )
2671 {
2672 offset = part_id - 1;
2673 mask = 1 << offset;
2674
2676 {
2677 return true;
2678 }
2679 }
2680 else if ( part_id >= 32 && part_id <= 62 )
2681 {
2682 offset = ( part_id % 32 );
2683 mask = 1 << offset;
2684
2686 {
2687 return true;
2688 }
2689 }
2690 else if ( part_id >= 63 && part_id <= 93 )
2691 {
2692 offset = ( part_id % 63 );
2693 mask = 1 << offset;
2694
2696 {
2697 return true;
2698 }
2699 }
2700
2701 return false;
2702 }
2703
2705 {
2708 }
2709
2711 {
2712
2715 }
2716
2718 {
2720 {
2723
2724 switch( build_action_id )
2725 {
2729 }
2730 }
2731 }
2732
2733
2735 {
2737 bool is_base = part.
IsBase();
2740 if ( is_part_built_sync )
2741 {
2743 {
2747
2748 if (is_base)
2749 {
2752 }
2753 }
2754 }
2755 else
2756 {
2758 {
2762
2763 if (is_base)
2764 {
2767 }
2768 }
2769 }
2770
2771
2773 }
2774
2775
2777 {
2780
2781 for ( int i = 0; i < construction_parts.Count(); ++i )
2782 {
2783 string key = construction_parts.GetKey( i );
2786 }
2787
2788
2790 }
2791
2793 {
2796
2797 for ( int i = 0; i < construction_parts.Count(); ++i )
2798 {
2799 string key = construction_parts.GetKey( i );
2801
2802 if ( value.
GetId() ==
id )
2803 {
2804 return value;
2805 }
2806 }
2807
2808 return NULL;
2809 }
2810
2811
2812
2814 {
2816 }
2817
2819 {
2821 }
2822
2824 {
2825 return true;
2826 }
2827
2829 {
2830 return false;
2831 }
2832
2833
2835 {
2838 {
2840 }
2841
2842 return construction_kit;
2843 }
2844
2846 {
2849 {
2851 }
2852 }
2853
2855 {
2857 }
2858
2860 {
2861 return "";
2862 }
2863
2865 {
2867 g_Game.ObjectDelete( construction_kit );
2868 }
2869
2870
2872 {
2874 g_Game.ObjectDelete(
this );
2875 }
2876
2877
2879 {
2880 super.EEDelete(parent);
2881
2883 {
2884 areaDamage.Destroy();
2885 }
2886
2887 }
2888
2890 {
2891 super.OnStoreSave( ctx );
2892
2893
2897
2899 }
2900
2902 {
2903 if ( !super.OnStoreLoad( ctx, version ) )
2904 return false;
2905
2906
2907
2909 {
2911 return false;
2912 }
2914 {
2916 return false;
2917 }
2919 {
2921 return false;
2922 }
2923
2924
2926 {
2928 return false;
2929 }
2930
2931
2932 return true;
2933 }
2934
2936 {
2937 super.AfterStoreLoad();
2938
2940 {
2942 }
2943 }
2944
2946 {
2947
2949
2950
2953
2954
2956 }
2957
2959 {
2960 super.OnCreatePhysics();
2961
2962 ConstructionInit();
2964 }
2965
2967 {
2969 return;
2970
2971 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2972 }
2973
2975 {
2977 {
2979 }
2980
2981 super.EEOnAfterLoad();
2982 }
2983
2985 {
2986 super.EEItemAttached( item, slot_name );
2987
2991 }
2992
2994 {
2995 super.EEItemDetached( item, slot_name );
2996
2999 }
3000
3001 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
3002 {
3005
3008 }
3009
3010
3012 {
3013 return true;
3014 }
3015
3016
3017
3019 {
3021
3022
3023 if (construtionPart.
IsBase())
3024 {
3026
3027
3029 }
3030
3031
3033
3034
3036
3037
3039
3041
3043
3044
3046
3047
3049 }
3050
3052 {
3053
3055 }
3056
3057
3059 {
3062
3063
3065
3066
3068
3069
3071
3072
3074
3076
3077
3079
3080
3082
3083
3084 if (construtionPart.
IsBase())
3085 {
3086
3088 }
3089 }
3090
3092 {
3093
3095 }
3096
3097
3098 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3099 {
3102
3103
3105
3106
3108
3109
3111
3112
3114
3116
3117
3119
3120
3122
3123
3124 if (construtionPart.
IsBase())
3125 {
3126
3128 }
3129 }
3130
3132 {
3133
3135 }
3136
3137
3139 {
3141
3144 }
3145
3147 {
3149
3151 {
3153 }
3154 else
3155 {
3157 }
3158
3160 }
3161
3163 {
3165
3167 foreach (
string slotName : attachmentSlots)
3168 {
3170 }
3171
3172
3175 else
3177
3179 }
3180
3182 {
3183 string slotNameMounted = slot_name + "_Mounted";
3184 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3185
3186 if (attachment)
3187 {
3188 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3189 if (barbedWire && barbedWire.IsMounted())
3191 else
3193
3194 if (is_locked)
3195 {
3196 SetAnimationPhase(slotNameMounted, 0);
3197 SetAnimationPhase(slot_name, 1);
3198 }
3199 else
3200 {
3201 SetAnimationPhase(slotNameMounted, 1);
3202 SetAnimationPhase(slot_name, 0);
3203 }
3204 }
3205 else
3206 {
3207 SetAnimationPhase(slotNameMounted, 1);
3208 SetAnimationPhase(slot_name, 1);
3209
3211 }
3212 }
3213
3214
3216 {
3219
3222
3225
3226 foreach (
string slotName : attachmentSlots)
3227 {
3229 }
3230
3231
3233 {
3236
3238 }
3239 else
3240 {
3243
3245 }
3246
3249 }
3250
3252 {
3253
3255 return;
3256
3257 string slot_name_mounted = slot_name + "_Mounted";
3258 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3259
3260
3262 RemoveProxyPhysics( slot_name_mounted );
3263 RemoveProxyPhysics( slot_name );
3264
3265 if ( attachment )
3266 {
3268 if ( is_locked )
3269 {
3271 AddProxyPhysics( slot_name_mounted );
3272 }
3273 else
3274 {
3276 AddProxyPhysics( slot_name );
3277 }
3278 }
3279 }
3280
3282 {
3283 SetAffectPathgraph( true, false );
3285 }
3286
3288 {
3289 return true;
3290 }
3291
3293 {
3294 return true;
3295 }
3296
3298 {
3299 if ( attachment )
3300 {
3302 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3303
3304 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3305 }
3306
3307 return false;
3308 }
3309
3311 {
3313 }
3314
3315
3317 {
3318 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3319 if (
g_Game.ConfigIsExisting( config_path ) )
3320 {
3321 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3322 }
3323 }
3324
3326 {
3327 return true;
3328 }
3329
3331 {
3332 return true;
3333 }
3334
3336 {
3337 return true;
3338 }
3339
3340
3342 {
3345 }
3346
3348 {
3350 }
3351
3353 {
3355 }
3356
3358 {
3359 int attachment_count = GetInventory().AttachmentCount();
3360 if ( attachment_count > 0 )
3361 {
3362 if (
HasBase() && attachment_count == 1 )
3363 {
3364 return false;
3365 }
3366
3367 return true;
3368 }
3369
3370 return false;
3371 }
3372
3374 {
3375 return true;
3376 }
3377
3379 {
3380 return false;
3381 }
3382
3383
3385 {
3386 return false;
3387 }
3388
3390 {
3391 return false;
3392 }
3393
3394
3396 {
3397 return false;
3398 }
3399
3400
3401
3403 {
3404 return true;
3405 }
3406
3408 {
3409 return true;
3410 }
3411
3414 {
3415 return false;
3416 }
3417
3418
3420 {
3421 return false;
3422 }
3423
3424
3426 {
3427 return true;
3428 }
3429
3430
3432 {
3433 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3434 {
3435 return false;
3436 }
3437
3438 return true;
3439 }
3440
3442 {
3445
3446 return item;
3447 }
3448
3449
3451 {
3453 {
3454
3456
3457
3460
3462 if ( MemoryPointExists( slot_name + "_min" ) )
3463 {
3464 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3465 }
3466 if ( MemoryPointExists( slot_name + "_max" ) )
3467 {
3468 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3469 }
3470
3471
3474
3475
3478 center = ModelToWorld( center );
3479
3480
3483
3484 areaDamage.SetExtents( extents[0], extents[1] );
3485 areaDamage.SetAreaPosition( center );
3489 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3490 areaDamage.SetAmmoName( "BarbedWireHit" );
3491 areaDamage.Spawn();
3492
3494 }
3495 }
3496
3498 {
3499 if ( angle_deg != 0 )
3500 {
3501
3503
3504
3506 if ( MemoryPointExists( "rotate_axis" ) )
3507 {
3508 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3509 }
3510 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];
3511 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];
3512 center[0] = r_center_x;
3513 center[2] = r_center_z;
3514 }
3515 }
3516
3518 {
3520 {
3523 {
3524 if (areaDamage)
3525 {
3526 areaDamage.Destroy();
3527 }
3528
3530 }
3531 }
3532 }
3533
3535 {
3536 return true;
3537 }
3538
3539
3540
3541
3543 {
3545 }
3546
3548 {
3550 }
3551
3553 {
3555 }
3556
3558 {
3560
3561 switch ( material_type )
3562 {
3568 }
3569
3570 return "";
3571 }
3572
3574 {
3576
3577 switch ( material_type )
3578 {
3584 }
3585
3586 return "";
3587 }
3588
3589
3591 {
3593 {
3594
3596 {
3597 SetHealth(slot_name,"Health",item.GetHealth());
3598 }
3599 }
3600 }
3601
3603 {
3604 return 111;
3605 }
3606
3608 {
3609 super.SetActions();
3610
3614 }
3615
3617 {
3619 if (!construction)
3620 return;
3621
3623 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3624 {
3627 {
3629 }
3630 }
3631 }
3632
3634 {
3636 if (!construction)
3637 return;
3638
3640 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3641 {
3644 {
3645 construction.HandleEntityFalling(part.
GetPartName());
3646 }
3647 }
3648 }
3649
3652 {
3654 return;
3655
3658
3659 if (DestroyOnFall())
3660 {
3662 {
3664 }
3665 else
3666 {
3668 {
3670 }
3672 }
3673 }
3674 }
3675
3677 {
3678 if (HasAnyAttachmentsOrCargo())
3679 {
3682 }
3683 }
3684
3685
3686
3687
3688
3691 {
3692 return null;
3693 }
3694
3696 {
3698 }
3699
3701 {
3704
3705 Man p;
3706
3707 #ifdef SERVER
3709 g_Game.GetWorld().GetPlayerList(players);
3710 if (players.Count())
3711 p = players[0];
3712 #else
3714 #endif
3715
3717 {
3718 bool excluded = false;
3720 if (excludes)
3721 {
3722 foreach (string exclude : excludes)
3723 {
3725 {
3726 excluded = true;
3727 break;
3728 }
3729 }
3730 }
3731
3732 if (!excluded)
3733 {
3735 }
3736 }
3737
3739 }
3740
3742
3744 [
Obsolete(
"handled in the Construction component directly")]
3746 {
3747 }
3748
3749 [
Obsolete(
"handled in the Construction component directly")]
3751 {
3752 }
3753
3754 [
Obsolete(
"obsolete debug method")]
3756 {
3757 }
3758}
3759
3761{
3762#ifdef BSB_DEBUG
3764#else
3765
3766#endif
3767}
3769{
3770#ifdef BSB_DEBUG_SPAM
3772#else
3773
3774#endif
3775}
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.