2521{
2523
2525
2527
2534
2535
2536
2542
2548
2550
2554
2555
2557 {
2559
2560
2561 RegisterNetSyncVariableInt( "m_SyncParts01" );
2562 RegisterNetSyncVariableInt( "m_SyncParts02" );
2563 RegisterNetSyncVariableInt( "m_SyncParts03" );
2564 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2565 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2566 RegisterNetSyncVariableBool( "m_HasBase" );
2567
2568
2569 ConstructionInit();
2570
2571 if (ConfigIsExisting("hybridAttachments"))
2572 {
2575 }
2576 if (ConfigIsExisting("mountables"))
2577 {
2580 }
2581
2583 SetAllowDamage(true);
2584 }
2585
2587 {
2588 return "disableBaseDamage";
2589 }
2590
2592 {
2593 return true;
2594 }
2595
2597 {
2598 return EInventoryIconVisibility.HIDE_VICINITY;
2599 }
2600
2602 {
2603 super.InitItemSounds();
2604
2608
2613 }
2614
2616 {
2617 return "putDown_FenceKit_SoundSet";
2618 }
2619
2621 {
2622 return "Shelter_Site_Build_Loop_SoundSet";
2623 }
2624
2625
2627 {
2629 {
2630 SetSynchDirty();
2631 }
2632 }
2633
2635 {
2637 super.OnVariablesSynchronized();
2638
2640 }
2641
2643 {
2644
2646
2647
2649
2650
2652 }
2653
2654
2656 {
2657
2658 int offset;
2659 int mask;
2660
2661 if ( part_id >= 1 && part_id <= 31 )
2662 {
2663 offset = part_id - 1;
2664 mask = 1 << offset;
2665
2667 }
2668 else if ( part_id >= 32 && part_id <= 62 )
2669 {
2670 offset = ( part_id % 32 );
2671 mask = 1 << offset;
2672
2674 }
2675 else if ( part_id >= 63 && part_id <= 93 )
2676 {
2677 offset = ( part_id % 63 );
2678 mask = 1 << offset;
2679
2681 }
2682 }
2683
2685 {
2686
2687 int offset;
2688 int mask;
2689
2690 if ( part_id >= 1 && part_id <= 31 )
2691 {
2692 offset = part_id - 1;
2693 mask = 1 << offset;
2694
2696 }
2697 else if ( part_id >= 32 && part_id <= 62 )
2698 {
2699 offset = ( part_id % 32 );
2700 mask = 1 << offset;
2701
2703 }
2704 else if ( part_id >= 63 && part_id <= 93 )
2705 {
2706 offset = ( part_id % 63 );
2707 mask = 1 << offset;
2708
2710 }
2711 }
2712
2714 {
2715
2716 int offset;
2717 int mask;
2718
2719 if ( part_id >= 1 && part_id <= 31 )
2720 {
2721 offset = part_id - 1;
2722 mask = 1 << offset;
2723
2725 {
2726 return true;
2727 }
2728 }
2729 else if ( part_id >= 32 && part_id <= 62 )
2730 {
2731 offset = ( part_id % 32 );
2732 mask = 1 << offset;
2733
2735 {
2736 return true;
2737 }
2738 }
2739 else if ( part_id >= 63 && part_id <= 93 )
2740 {
2741 offset = ( part_id % 63 );
2742 mask = 1 << offset;
2743
2745 {
2746 return true;
2747 }
2748 }
2749
2750 return false;
2751 }
2752
2754 {
2757 }
2758
2760 {
2761
2764 }
2765
2767 {
2769 {
2772
2773 switch( build_action_id )
2774 {
2778 }
2779 }
2780 }
2781
2782
2784 {
2786 bool is_base = part.
IsBase();
2789 if ( is_part_built_sync )
2790 {
2792 {
2796
2797 if (is_base)
2798 {
2801 }
2802 }
2803 }
2804 else
2805 {
2807 {
2811
2812 if (is_base)
2813 {
2816 }
2817 }
2818 }
2819
2820
2822 }
2823
2824
2826 {
2829
2830 for ( int i = 0; i < construction_parts.Count(); ++i )
2831 {
2832 string key = construction_parts.GetKey( i );
2835 }
2836
2837
2839 }
2840
2842 {
2845
2846 for ( int i = 0; i < construction_parts.Count(); ++i )
2847 {
2848 string key = construction_parts.GetKey( i );
2850
2851 if ( value.
GetId() ==
id )
2852 {
2853 return value;
2854 }
2855 }
2856
2857 return NULL;
2858 }
2859
2860
2861
2863 {
2865 }
2866
2868 {
2870 }
2871
2873 {
2874 return true;
2875 }
2876
2878 {
2879 return false;
2880 }
2881
2882
2884 {
2887 {
2889 }
2890
2891 return construction_kit;
2892 }
2893
2895 {
2898 {
2900 }
2901 }
2902
2904 {
2906 }
2907
2909 {
2910 return "";
2911 }
2912
2914 {
2916 g_Game.ObjectDelete( construction_kit );
2917 }
2918
2919
2921 {
2923 g_Game.ObjectDelete(
this );
2924 }
2925
2926
2928 {
2929 super.EEDelete(parent);
2930
2932 {
2933 areaDamage.Destroy();
2934 }
2935
2936 }
2937
2939 {
2940 super.OnStoreSave( ctx );
2941
2942
2946
2948 }
2949
2951 {
2952 if ( !super.OnStoreLoad( ctx, version ) )
2953 return false;
2954
2955
2956
2958 {
2960 return false;
2961 }
2963 {
2965 return false;
2966 }
2968 {
2970 return false;
2971 }
2972
2973
2975 {
2977 return false;
2978 }
2979
2980
2981 return true;
2982 }
2983
2985 {
2986 super.AfterStoreLoad();
2987
2989 {
2991 }
2992 }
2993
2995 {
2996
2998
2999
3002
3003
3005 }
3006
3008 {
3009 super.OnCreatePhysics();
3010
3011 ConstructionInit();
3013 }
3014
3016 {
3018 return;
3019
3020 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
3021 }
3022
3024 {
3026 {
3028 }
3029
3030 super.EEOnAfterLoad();
3031 }
3032
3034 {
3035 super.EEItemAttached( item, slot_name );
3036
3040 }
3041
3043 {
3044 super.EEItemDetached( item, slot_name );
3045
3048 }
3049
3050 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
3051 {
3054
3057 }
3058
3059
3061 {
3062 return true;
3063 }
3064
3065
3066
3068 {
3070
3071
3072 if (construtionPart.
IsBase())
3073 {
3075
3076
3078 }
3079
3080
3082
3083
3085
3086
3088
3090
3092
3093
3095
3096
3098 }
3099
3101 {
3102
3104 }
3105
3106
3108 {
3111
3112
3114
3115
3117
3118
3120
3121
3123
3125
3126
3128
3129
3131
3132
3133 if (construtionPart.
IsBase())
3134 {
3135
3137 }
3138 }
3139
3141 {
3142
3144 }
3145
3146
3147 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3148 {
3151
3152
3154
3155
3157
3158
3160
3161
3163
3165
3166
3168
3169
3171
3172
3173 if (construtionPart.
IsBase())
3174 {
3175
3177 }
3178 }
3179
3181 {
3182
3184 }
3185
3186
3188 {
3190
3193 }
3194
3196 {
3198
3200 {
3202 }
3203 else
3204 {
3206 }
3207
3209 }
3210
3212 {
3214
3216 foreach (
string slotName : attachmentSlots)
3217 {
3219 }
3220
3221
3224 else
3226
3228 }
3229
3231 {
3232 string slotNameMounted = slot_name + "_Mounted";
3233 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3234
3235 if (attachment)
3236 {
3237 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3238 if (barbedWire && barbedWire.IsMounted())
3240 else
3242
3243 if (is_locked)
3244 {
3245 SetAnimationPhase(slotNameMounted, 0);
3246 SetAnimationPhase(slot_name, 1);
3247 }
3248 else
3249 {
3250 SetAnimationPhase(slotNameMounted, 1);
3251 SetAnimationPhase(slot_name, 0);
3252 }
3253 }
3254 else
3255 {
3256 SetAnimationPhase(slotNameMounted, 1);
3257 SetAnimationPhase(slot_name, 1);
3258
3260 }
3261 }
3262
3263
3265 {
3268
3271
3274
3275 foreach (
string slotName : attachmentSlots)
3276 {
3278 }
3279
3280
3282 {
3285
3287 }
3288 else
3289 {
3292
3294 }
3295
3298 }
3299
3301 {
3302
3304 return;
3305
3306 string slot_name_mounted = slot_name + "_Mounted";
3307 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3308
3309
3311 RemoveProxyPhysics( slot_name_mounted );
3312 RemoveProxyPhysics( slot_name );
3313
3314 if ( attachment )
3315 {
3317 if ( is_locked )
3318 {
3320 AddProxyPhysics( slot_name_mounted );
3321 }
3322 else
3323 {
3325 AddProxyPhysics( slot_name );
3326 }
3327 }
3328 }
3329
3331 {
3332 SetAffectPathgraph( true, false );
3334 }
3335
3337 {
3338 return true;
3339 }
3340
3342 {
3343 return true;
3344 }
3345
3347 {
3348 if ( attachment )
3349 {
3351 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3352
3353 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3354 }
3355
3356 return false;
3357 }
3358
3360 {
3362 }
3363
3364
3366 {
3367 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3368 if (
g_Game.ConfigIsExisting( config_path ) )
3369 {
3370 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3371 }
3372 }
3373
3375 {
3376 return true;
3377 }
3378
3380 {
3381 return true;
3382 }
3383
3385 {
3386 return true;
3387 }
3388
3389
3391 {
3394 }
3395
3397 {
3399 }
3400
3402 {
3404 }
3405
3407 {
3408 int attachment_count = GetInventory().AttachmentCount();
3409 if ( attachment_count > 0 )
3410 {
3411 if (
HasBase() && attachment_count == 1 )
3412 {
3413 return false;
3414 }
3415
3416 return true;
3417 }
3418
3419 return false;
3420 }
3421
3423 {
3424 return true;
3425 }
3426
3428 {
3429 return false;
3430 }
3431
3432
3434 {
3435 return false;
3436 }
3437
3439 {
3440 return false;
3441 }
3442
3443
3445 {
3446 return false;
3447 }
3448
3449
3450
3452 {
3453 return true;
3454 }
3455
3457 {
3458 return true;
3459 }
3460
3463 {
3464 return false;
3465 }
3466
3467
3469 {
3470 return false;
3471 }
3472
3473
3475 {
3476 return true;
3477 }
3478
3479
3481 {
3482 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3483 {
3484 return false;
3485 }
3486
3487 return true;
3488 }
3489
3491 {
3494
3495 return item;
3496 }
3497
3498
3500 {
3502 {
3503
3505
3506
3509
3511 if ( MemoryPointExists( slot_name + "_min" ) )
3512 {
3513 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3514 }
3515 if ( MemoryPointExists( slot_name + "_max" ) )
3516 {
3517 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3518 }
3519
3520
3523
3524
3527 center = ModelToWorld( center );
3528
3529
3532
3533 areaDamage.SetExtents( extents[0], extents[1] );
3534 areaDamage.SetAreaPosition( center );
3538 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3539 areaDamage.SetAmmoName( "BarbedWireHit" );
3540 areaDamage.Spawn();
3541
3543 }
3544 }
3545
3547 {
3548 if ( angle_deg != 0 )
3549 {
3550
3552
3553
3555 if ( MemoryPointExists( "rotate_axis" ) )
3556 {
3557 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3558 }
3559 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];
3560 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];
3561 center[0] = r_center_x;
3562 center[2] = r_center_z;
3563 }
3564 }
3565
3567 {
3569 {
3572 {
3573 if (areaDamage)
3574 {
3575 areaDamage.Destroy();
3576 }
3577
3579 }
3580 }
3581 }
3582
3584 {
3585 return true;
3586 }
3587
3588
3589
3590
3592 {
3594 }
3595
3597 {
3599 }
3600
3602 {
3604 }
3605
3607 {
3609
3610 switch ( material_type )
3611 {
3617 }
3618
3619 return "";
3620 }
3621
3623 {
3625
3626 switch ( material_type )
3627 {
3633 }
3634
3635 return "";
3636 }
3637
3638
3640 {
3642 {
3643
3645 {
3646 SetHealth(slot_name,"Health",item.GetHealth());
3647 }
3648 }
3649 }
3650
3652 {
3653 return 111;
3654 }
3655
3657 {
3658 super.SetActions();
3659
3663 }
3664
3666 {
3668 if (!construction)
3669 return;
3670
3672 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3673 {
3676 {
3678 }
3679 }
3680 }
3681
3683 {
3685 if (!construction)
3686 return;
3687
3689 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3690 {
3693 {
3694 construction.HandleEntityFalling(part.
GetPartName());
3695 }
3696 }
3697 }
3698
3701 {
3703 return;
3704
3707
3708 if (DestroyOnFall())
3709 {
3711 {
3713 }
3714 else
3715 {
3717 {
3719 }
3721 }
3722 }
3723 }
3724
3726 {
3727 if (HasAnyAttachmentsOrCargo())
3728 {
3731 }
3732 }
3733
3734
3735
3736
3737
3740 {
3741 return null;
3742 }
3743
3745 {
3747 }
3748
3750 {
3753
3754 Man p;
3755
3756 #ifdef SERVER
3758 g_Game.GetWorld().GetPlayerList(players);
3759 if (players.Count())
3760 p = players[0];
3761 #else
3763 #endif
3764
3766 {
3767 bool excluded = false;
3769 if (excludes)
3770 {
3771 foreach (string exclude : excludes)
3772 {
3774 {
3775 excluded = true;
3776 break;
3777 }
3778 }
3779 }
3780
3781 if (!excluded)
3782 {
3784 }
3785 }
3786
3788 }
3789
3791
3793 [
Obsolete(
"handled in the Construction component directly")]
3795 {
3796 }
3797
3798 [
Obsolete(
"handled in the Construction component directly")]
3800 {
3801 }
3802
3803 [
Obsolete(
"obsolete debug method")]
3805 {
3806 }
3807}
3808
3810{
3811#ifdef BSB_DEBUG
3813#else
3814
3815#endif
3816}
3818{
3819#ifdef BSB_DEBUG_SPAM
3821#else
3822
3823#endif
3824}
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.