2437{
2439
2441
2443
2450
2451
2452
2458
2464
2466
2470
2471
2473 {
2475
2476
2477 RegisterNetSyncVariableInt( "m_SyncParts01" );
2478 RegisterNetSyncVariableInt( "m_SyncParts02" );
2479 RegisterNetSyncVariableInt( "m_SyncParts03" );
2480 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2481 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2482 RegisterNetSyncVariableBool( "m_HasBase" );
2483
2484
2485 ConstructionInit();
2486
2487 if (ConfigIsExisting("hybridAttachments"))
2488 {
2491 }
2492 if (ConfigIsExisting("mountables"))
2493 {
2496 }
2497
2499 SetAllowDamage(true);
2500 }
2501
2503 {
2504 return "disableBaseDamage";
2505 }
2506
2508 {
2509 return true;
2510 }
2511
2513 {
2514 return EInventoryIconVisibility.HIDE_VICINITY;
2515 }
2516
2518 {
2519 super.InitItemSounds();
2520
2524
2529 }
2530
2532 {
2533 return "putDown_FenceKit_SoundSet";
2534 }
2535
2537 {
2538 return "Shelter_Site_Build_Loop_SoundSet";
2539 }
2540
2541
2543 {
2545 {
2546 SetSynchDirty();
2547 }
2548 }
2549
2551 {
2553 super.OnVariablesSynchronized();
2554
2556 }
2557
2559 {
2560
2562
2563
2565
2566
2568 }
2569
2570
2572 {
2573
2574 int offset;
2575 int mask;
2576
2577 if ( part_id >= 1 && part_id <= 31 )
2578 {
2579 offset = part_id - 1;
2580 mask = 1 << offset;
2581
2583 }
2584 else if ( part_id >= 32 && part_id <= 62 )
2585 {
2586 offset = ( part_id % 32 );
2587 mask = 1 << offset;
2588
2590 }
2591 else if ( part_id >= 63 && part_id <= 93 )
2592 {
2593 offset = ( part_id % 63 );
2594 mask = 1 << offset;
2595
2597 }
2598 }
2599
2601 {
2602
2603 int offset;
2604 int mask;
2605
2606 if ( part_id >= 1 && part_id <= 31 )
2607 {
2608 offset = part_id - 1;
2609 mask = 1 << offset;
2610
2612 }
2613 else if ( part_id >= 32 && part_id <= 62 )
2614 {
2615 offset = ( part_id % 32 );
2616 mask = 1 << offset;
2617
2619 }
2620 else if ( part_id >= 63 && part_id <= 93 )
2621 {
2622 offset = ( part_id % 63 );
2623 mask = 1 << offset;
2624
2626 }
2627 }
2628
2630 {
2631
2632 int offset;
2633 int mask;
2634
2635 if ( part_id >= 1 && part_id <= 31 )
2636 {
2637 offset = part_id - 1;
2638 mask = 1 << offset;
2639
2641 {
2642 return true;
2643 }
2644 }
2645 else if ( part_id >= 32 && part_id <= 62 )
2646 {
2647 offset = ( part_id % 32 );
2648 mask = 1 << offset;
2649
2651 {
2652 return true;
2653 }
2654 }
2655 else if ( part_id >= 63 && part_id <= 93 )
2656 {
2657 offset = ( part_id % 63 );
2658 mask = 1 << offset;
2659
2661 {
2662 return true;
2663 }
2664 }
2665
2666 return false;
2667 }
2668
2670 {
2673 }
2674
2676 {
2677
2680 }
2681
2683 {
2685 {
2688
2689 switch( build_action_id )
2690 {
2694 }
2695 }
2696 }
2697
2698
2700 {
2702 bool is_base = part.
IsBase();
2705 if ( is_part_built_sync )
2706 {
2708 {
2712
2713 if (is_base)
2714 {
2717 }
2718 }
2719 }
2720 else
2721 {
2723 {
2727
2728 if (is_base)
2729 {
2732 }
2733 }
2734 }
2735
2736
2738 }
2739
2740
2742 {
2745
2746 for ( int i = 0; i < construction_parts.Count(); ++i )
2747 {
2748 string key = construction_parts.GetKey( i );
2751 }
2752
2753
2755 }
2756
2758 {
2761
2762 for ( int i = 0; i < construction_parts.Count(); ++i )
2763 {
2764 string key = construction_parts.GetKey( i );
2766
2767 if ( value.
GetId() ==
id )
2768 {
2769 return value;
2770 }
2771 }
2772
2773 return NULL;
2774 }
2775
2776
2777
2779 {
2781 }
2782
2784 {
2786 }
2787
2789 {
2790 return true;
2791 }
2792
2794 {
2795 return false;
2796 }
2797
2798
2800 {
2803 {
2805 }
2806
2807 return construction_kit;
2808 }
2809
2811 {
2814 {
2816 }
2817 }
2818
2820 {
2822 }
2823
2825 {
2826 return "";
2827 }
2828
2830 {
2832 g_Game.ObjectDelete( construction_kit );
2833 }
2834
2835
2837 {
2839 g_Game.ObjectDelete(
this );
2840 }
2841
2842
2844 {
2845 super.EEDelete(parent);
2846
2848 {
2849 areaDamage.Destroy();
2850 }
2851
2852 }
2853
2855 {
2856 super.OnStoreSave( ctx );
2857
2858
2862
2864 }
2865
2867 {
2868 if ( !super.OnStoreLoad( ctx, version ) )
2869 return false;
2870
2871
2872
2874 {
2876 return false;
2877 }
2879 {
2881 return false;
2882 }
2884 {
2886 return false;
2887 }
2888
2889
2891 {
2893 return false;
2894 }
2895
2896
2897 return true;
2898 }
2899
2901 {
2902 super.AfterStoreLoad();
2903
2905 {
2907 }
2908 }
2909
2911 {
2912
2914
2915
2918
2919
2921 }
2922
2924 {
2925 super.OnCreatePhysics();
2926
2927 ConstructionInit();
2929 }
2930
2932 {
2934 return;
2935
2936 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2937 }
2938
2940 {
2942 {
2944 }
2945
2946 super.EEOnAfterLoad();
2947 }
2948
2950 {
2951 super.EEItemAttached( item, slot_name );
2952
2956 }
2957
2959 {
2960 super.EEItemDetached( item, slot_name );
2961
2964 }
2965
2966 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2967 {
2970
2973 }
2974
2975
2977 {
2978 return true;
2979 }
2980
2981
2982
2984 {
2986
2987
2988 if (construtionPart.
IsBase())
2989 {
2991
2992
2994 }
2995
2996
2998
2999
3001
3002
3004
3006
3008
3009
3011
3012
3014 }
3015
3017 {
3018
3020 }
3021
3022
3024 {
3027
3028
3030
3031
3033
3034
3036
3037
3039
3041
3042
3044
3045
3047
3048
3049 if (construtionPart.
IsBase())
3050 {
3051
3053 }
3054 }
3055
3057 {
3058
3060 }
3061
3062
3063 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3064 {
3067
3068
3070
3071
3073
3074
3076
3077
3079
3081
3082
3084
3085
3087
3088
3089 if (construtionPart.
IsBase())
3090 {
3091
3093 }
3094 }
3095
3097 {
3098
3100 }
3101
3102
3104 {
3106
3109 }
3110
3112 {
3114
3116 {
3118 }
3119 else
3120 {
3122 }
3123
3125 }
3126
3128 {
3130
3132 foreach (
string slotName : attachmentSlots)
3133 {
3135 }
3136
3137
3140 else
3142
3144 }
3145
3147 {
3148 string slotNameMounted = slot_name + "_Mounted";
3149 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3150
3151 if (attachment)
3152 {
3153 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3154 if (barbedWire && barbedWire.IsMounted())
3156 else
3158
3159 if (is_locked)
3160 {
3161 SetAnimationPhase(slotNameMounted, 0);
3162 SetAnimationPhase(slot_name, 1);
3163 }
3164 else
3165 {
3166 SetAnimationPhase(slotNameMounted, 1);
3167 SetAnimationPhase(slot_name, 0);
3168 }
3169 }
3170 else
3171 {
3172 SetAnimationPhase(slotNameMounted, 1);
3173 SetAnimationPhase(slot_name, 1);
3174
3176 }
3177 }
3178
3179
3181 {
3184
3187
3190
3191 foreach (
string slotName : attachmentSlots)
3192 {
3194 }
3195
3196
3198 {
3201
3203 }
3204 else
3205 {
3208
3210 }
3211
3214 }
3215
3217 {
3218
3220 return;
3221
3222 string slot_name_mounted = slot_name + "_Mounted";
3223 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3224
3225
3227 RemoveProxyPhysics( slot_name_mounted );
3228 RemoveProxyPhysics( slot_name );
3229
3230 if ( attachment )
3231 {
3233 if ( is_locked )
3234 {
3236 AddProxyPhysics( slot_name_mounted );
3237 }
3238 else
3239 {
3241 AddProxyPhysics( slot_name );
3242 }
3243 }
3244 }
3245
3247 {
3248 SetAffectPathgraph( true, false );
3250 }
3251
3253 {
3254 return true;
3255 }
3256
3258 {
3259 return true;
3260 }
3261
3263 {
3264 if ( attachment )
3265 {
3267 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3268
3269 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3270 }
3271
3272 return false;
3273 }
3274
3276 {
3278 }
3279
3280
3282 {
3283 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3284 if (
g_Game.ConfigIsExisting( config_path ) )
3285 {
3286 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3287 }
3288 }
3289
3291 {
3292 return true;
3293 }
3294
3296 {
3297 return true;
3298 }
3299
3301 {
3302 return true;
3303 }
3304
3305
3307 {
3310 }
3311
3313 {
3315 }
3316
3318 {
3320 }
3321
3323 {
3324 int attachment_count = GetInventory().AttachmentCount();
3325 if ( attachment_count > 0 )
3326 {
3327 if (
HasBase() && attachment_count == 1 )
3328 {
3329 return false;
3330 }
3331
3332 return true;
3333 }
3334
3335 return false;
3336 }
3337
3339 {
3340 return true;
3341 }
3342
3344 {
3345 return false;
3346 }
3347
3348
3350 {
3351 return false;
3352 }
3353
3355 {
3356 return false;
3357 }
3358
3359
3361 {
3362 return false;
3363 }
3364
3365
3366
3368 {
3369 return true;
3370 }
3371
3373 {
3374 return true;
3375 }
3376
3379 {
3380 return false;
3381 }
3382
3383
3385 {
3386 return false;
3387 }
3388
3389
3391 {
3392 return true;
3393 }
3394
3395
3397 {
3398 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3399 {
3400 return false;
3401 }
3402
3403 return true;
3404 }
3405
3407 {
3410
3411 return item;
3412 }
3413
3414
3416 {
3418 {
3419
3421
3422
3425
3427 if ( MemoryPointExists( slot_name + "_min" ) )
3428 {
3429 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3430 }
3431 if ( MemoryPointExists( slot_name + "_max" ) )
3432 {
3433 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3434 }
3435
3436
3439
3440
3443 center = ModelToWorld( center );
3444
3445
3448
3449 areaDamage.SetExtents( extents[0], extents[1] );
3450 areaDamage.SetAreaPosition( center );
3454 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3455 areaDamage.SetAmmoName( "BarbedWireHit" );
3456 areaDamage.Spawn();
3457
3459 }
3460 }
3461
3463 {
3464 if ( angle_deg != 0 )
3465 {
3466
3468
3469
3471 if ( MemoryPointExists( "rotate_axis" ) )
3472 {
3473 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3474 }
3475 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];
3476 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];
3477 center[0] = r_center_x;
3478 center[2] = r_center_z;
3479 }
3480 }
3481
3483 {
3485 {
3488 {
3489 if (areaDamage)
3490 {
3491 areaDamage.Destroy();
3492 }
3493
3495 }
3496 }
3497 }
3498
3500 {
3501 return true;
3502 }
3503
3504
3505
3506
3508 {
3510 }
3511
3513 {
3515 }
3516
3518 {
3520 }
3521
3523 {
3525
3526 switch ( material_type )
3527 {
3533 }
3534
3535 return "";
3536 }
3537
3539 {
3541
3542 switch ( material_type )
3543 {
3549 }
3550
3551 return "";
3552 }
3553
3554
3556 {
3558 {
3559
3561 {
3562 SetHealth(slot_name,"Health",item.GetHealth());
3563 }
3564 }
3565 }
3566
3568 {
3569 return 111;
3570 }
3571
3573 {
3574 super.SetActions();
3575
3579 }
3580
3582 {
3584 if (!construction)
3585 return;
3586
3588 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3589 {
3592 {
3594 }
3595 }
3596 }
3597
3599 {
3601 if (!construction)
3602 return;
3603
3605 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3606 {
3609 {
3610 construction.HandleEntityFalling(part.
GetPartName());
3611 }
3612 }
3613 }
3614
3617 {
3619 return;
3620
3623
3624 if (DestroyOnFall())
3625 {
3627 {
3629 }
3630 else
3631 {
3633 {
3635 }
3637 }
3638 }
3639 }
3640
3642 {
3643 if (HasAnyAttachmentsOrCargo())
3644 {
3647 }
3648 }
3649
3650
3651
3652
3653
3656 {
3657 return null;
3658 }
3659
3661 {
3663 }
3664
3666 {
3669
3670 Man p;
3671
3672 #ifdef SERVER
3674 g_Game.GetWorld().GetPlayerList(players);
3675 if (players.Count())
3676 p = players[0];
3677 #else
3679 #endif
3680
3682 {
3683 bool excluded = false;
3685 if (excludes)
3686 {
3687 foreach (string exclude : excludes)
3688 {
3690 {
3691 excluded = true;
3692 break;
3693 }
3694 }
3695 }
3696
3697 if (!excluded)
3698 {
3700 }
3701 }
3702
3704 }
3705
3707
3709 [
Obsolete(
"handled in the Construction component directly")]
3711 {
3712 }
3713
3714 [
Obsolete(
"handled in the Construction component directly")]
3716 {
3717 }
3718
3719 [
Obsolete(
"obsolete debug method")]
3721 {
3722 }
3723}
3724
3726{
3727#ifdef BSB_DEBUG
3729#else
3730
3731#endif
3732}
3734{
3735#ifdef BSB_DEBUG_SPAM
3737#else
3738
3739#endif
3740}
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.