2363{
2365
2367
2369
2376
2377
2378
2384
2390
2392
2396
2397
2399 {
2401
2402
2403 RegisterNetSyncVariableInt( "m_SyncParts01" );
2404 RegisterNetSyncVariableInt( "m_SyncParts02" );
2405 RegisterNetSyncVariableInt( "m_SyncParts03" );
2406 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2407 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2408 RegisterNetSyncVariableBool( "m_HasBase" );
2409
2410
2411 ConstructionInit();
2412
2413 if (ConfigIsExisting("hybridAttachments"))
2414 {
2417 }
2418 if (ConfigIsExisting("mountables"))
2419 {
2422 }
2423
2425 SetAllowDamage(true);
2426 }
2427
2429 {
2430 return "disableBaseDamage";
2431 }
2432
2434 {
2435 return true;
2436 }
2437
2439 {
2440 return EInventoryIconVisibility.HIDE_VICINITY;
2441 }
2442
2444 {
2445 super.InitItemSounds();
2446
2450
2455 }
2456
2458 {
2459 return "putDown_FenceKit_SoundSet";
2460 }
2461
2463 {
2464 return "Shelter_Site_Build_Loop_SoundSet";
2465 }
2466
2467
2469 {
2471 {
2472 SetSynchDirty();
2473 }
2474 }
2475
2477 {
2479 super.OnVariablesSynchronized();
2480
2482 }
2483
2485 {
2486
2488
2489
2491
2492
2494 }
2495
2496
2498 {
2499
2500 int offset;
2501 int mask;
2502
2503 if ( part_id >= 1 && part_id <= 31 )
2504 {
2505 offset = part_id - 1;
2506 mask = 1 << offset;
2507
2509 }
2510 else if ( part_id >= 32 && part_id <= 62 )
2511 {
2512 offset = ( part_id % 32 );
2513 mask = 1 << offset;
2514
2516 }
2517 else if ( part_id >= 63 && part_id <= 93 )
2518 {
2519 offset = ( part_id % 63 );
2520 mask = 1 << offset;
2521
2523 }
2524 }
2525
2527 {
2528
2529 int offset;
2530 int mask;
2531
2532 if ( part_id >= 1 && part_id <= 31 )
2533 {
2534 offset = part_id - 1;
2535 mask = 1 << offset;
2536
2538 }
2539 else if ( part_id >= 32 && part_id <= 62 )
2540 {
2541 offset = ( part_id % 32 );
2542 mask = 1 << offset;
2543
2545 }
2546 else if ( part_id >= 63 && part_id <= 93 )
2547 {
2548 offset = ( part_id % 63 );
2549 mask = 1 << offset;
2550
2552 }
2553 }
2554
2556 {
2557
2558 int offset;
2559 int mask;
2560
2561 if ( part_id >= 1 && part_id <= 31 )
2562 {
2563 offset = part_id - 1;
2564 mask = 1 << offset;
2565
2567 {
2568 return true;
2569 }
2570 }
2571 else if ( part_id >= 32 && part_id <= 62 )
2572 {
2573 offset = ( part_id % 32 );
2574 mask = 1 << offset;
2575
2577 {
2578 return true;
2579 }
2580 }
2581 else if ( part_id >= 63 && part_id <= 93 )
2582 {
2583 offset = ( part_id % 63 );
2584 mask = 1 << offset;
2585
2587 {
2588 return true;
2589 }
2590 }
2591
2592 return false;
2593 }
2594
2596 {
2599 }
2600
2602 {
2603
2606 }
2607
2609 {
2611 {
2614
2615 switch( build_action_id )
2616 {
2620 }
2621 }
2622 }
2623
2624
2626 {
2628 bool is_base = part.
IsBase();
2631 if ( is_part_built_sync )
2632 {
2634 {
2638
2639 if (is_base)
2640 {
2643 }
2644 }
2645 }
2646 else
2647 {
2649 {
2653
2654 if (is_base)
2655 {
2658 }
2659 }
2660 }
2661
2662
2664 }
2665
2666
2668 {
2671
2672 for ( int i = 0; i < construction_parts.Count(); ++i )
2673 {
2674 string key = construction_parts.GetKey( i );
2677 }
2678
2679
2681 }
2682
2684 {
2687
2688 for ( int i = 0; i < construction_parts.Count(); ++i )
2689 {
2690 string key = construction_parts.GetKey( i );
2692
2693 if ( value.
GetId() ==
id )
2694 {
2695 return value;
2696 }
2697 }
2698
2699 return NULL;
2700 }
2701
2702
2703
2705 {
2707 }
2708
2710 {
2712 }
2713
2715 {
2716 return true;
2717 }
2718
2720 {
2721 return false;
2722 }
2723
2724
2726 {
2729 {
2731 }
2732
2733 return construction_kit;
2734 }
2735
2737 {
2740 {
2742 }
2743 }
2744
2746 {
2748 }
2749
2751 {
2752 return "";
2753 }
2754
2756 {
2758 g_Game.ObjectDelete( construction_kit );
2759 }
2760
2761
2763 {
2765 g_Game.ObjectDelete(
this );
2766 }
2767
2768
2770 {
2771 super.EEDelete(parent);
2772
2774 {
2775 areaDamage.Destroy();
2776 }
2777
2778 }
2779
2781 {
2782 super.OnStoreSave( ctx );
2783
2784
2788
2790 }
2791
2793 {
2794 if ( !super.OnStoreLoad( ctx, version ) )
2795 return false;
2796
2797
2798
2800 {
2802 return false;
2803 }
2805 {
2807 return false;
2808 }
2810 {
2812 return false;
2813 }
2814
2815
2817 {
2819 return false;
2820 }
2821
2822
2823 return true;
2824 }
2825
2827 {
2828 super.AfterStoreLoad();
2829
2831 {
2833 }
2834 }
2835
2837 {
2838
2840
2841
2844
2845
2847 }
2848
2850 {
2851 super.OnCreatePhysics();
2852
2853 ConstructionInit();
2855 }
2856
2858 {
2860 return;
2861
2862 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2863 }
2864
2866 {
2868 {
2870 }
2871
2872 super.EEOnAfterLoad();
2873 }
2874
2876 {
2877 super.EEItemAttached( item, slot_name );
2878
2882 }
2883
2885 {
2886 super.EEItemDetached( item, slot_name );
2887
2890 }
2891
2892 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2893 {
2896
2899 }
2900
2901
2903 {
2904 return true;
2905 }
2906
2907
2908
2910 {
2912
2913
2914 if (construtionPart.
IsBase())
2915 {
2917
2918
2920 }
2921
2922
2924
2925
2927
2928
2930
2932
2934
2935
2937
2938
2940 }
2941
2943 {
2944
2946 }
2947
2948
2950 {
2953
2954
2956
2957
2959
2960
2962
2963
2965
2967
2968
2970
2971
2973
2974
2975 if (construtionPart.
IsBase())
2976 {
2977
2979 }
2980 }
2981
2983 {
2984
2986 }
2987
2988
2989 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2990 {
2993
2994
2996
2997
2999
3000
3002
3003
3005
3007
3008
3010
3011
3013
3014
3015 if (construtionPart.
IsBase())
3016 {
3017
3019 }
3020 }
3021
3023 {
3024
3026 }
3027
3028
3030 {
3032
3035 }
3036
3038 {
3040
3042 {
3044 }
3045 else
3046 {
3048 }
3049
3051 }
3052
3054 {
3056
3058 foreach (
string slotName : attachmentSlots)
3059 {
3061 }
3062
3063
3066 else
3068
3070 }
3071
3073 {
3074 string slotNameMounted = slot_name + "_Mounted";
3075 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3076
3077 if (attachment)
3078 {
3079 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3080 if (barbedWire && barbedWire.IsMounted())
3082 else
3084
3085 if (is_locked)
3086 {
3087 SetAnimationPhase(slotNameMounted, 0);
3088 SetAnimationPhase(slot_name, 1);
3089 }
3090 else
3091 {
3092 SetAnimationPhase(slotNameMounted, 1);
3093 SetAnimationPhase(slot_name, 0);
3094 }
3095 }
3096 else
3097 {
3098 SetAnimationPhase(slotNameMounted, 1);
3099 SetAnimationPhase(slot_name, 1);
3100
3102 }
3103 }
3104
3105
3107 {
3110
3113
3116
3117 foreach (
string slotName : attachmentSlots)
3118 {
3120 }
3121
3122
3124 {
3127
3129 }
3130 else
3131 {
3134
3136 }
3137
3140 }
3141
3143 {
3144
3146 return;
3147
3148 string slot_name_mounted = slot_name + "_Mounted";
3149 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3150
3151
3153 RemoveProxyPhysics( slot_name_mounted );
3154 RemoveProxyPhysics( slot_name );
3155
3156 if ( attachment )
3157 {
3159 if ( is_locked )
3160 {
3162 AddProxyPhysics( slot_name_mounted );
3163 }
3164 else
3165 {
3167 AddProxyPhysics( slot_name );
3168 }
3169 }
3170 }
3171
3173 {
3174 SetAffectPathgraph( true, false );
3176 }
3177
3179 {
3180 return true;
3181 }
3182
3184 {
3185 return true;
3186 }
3187
3189 {
3190 if ( attachment )
3191 {
3193 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3194
3195 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3196 }
3197
3198 return false;
3199 }
3200
3202 {
3204 }
3205
3206
3208 {
3209 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3210 if (
g_Game.ConfigIsExisting( config_path ) )
3211 {
3212 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3213 }
3214 }
3215
3217 {
3218 return true;
3219 }
3220
3222 {
3223 return true;
3224 }
3225
3227 {
3228 return true;
3229 }
3230
3231
3233 {
3236 }
3237
3239 {
3241 }
3242
3244 {
3246 }
3247
3249 {
3250 int attachment_count = GetInventory().AttachmentCount();
3251 if ( attachment_count > 0 )
3252 {
3253 if (
HasBase() && attachment_count == 1 )
3254 {
3255 return false;
3256 }
3257
3258 return true;
3259 }
3260
3261 return false;
3262 }
3263
3265 {
3266 return true;
3267 }
3268
3270 {
3271 return false;
3272 }
3273
3274
3276 {
3277 return false;
3278 }
3279
3281 {
3282 return false;
3283 }
3284
3285
3287 {
3288 return false;
3289 }
3290
3291
3292
3294 {
3295 return true;
3296 }
3297
3299 {
3300 return true;
3301 }
3302
3305 {
3306 return false;
3307 }
3308
3309
3311 {
3312 return false;
3313 }
3314
3315
3317 {
3318 return true;
3319 }
3320
3321
3323 {
3324 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3325 {
3326 return false;
3327 }
3328
3329 return true;
3330 }
3331
3333 {
3336
3337 return item;
3338 }
3339
3340
3342 {
3344 {
3345
3347
3348
3351
3353 if ( MemoryPointExists( slot_name + "_min" ) )
3354 {
3355 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3356 }
3357 if ( MemoryPointExists( slot_name + "_max" ) )
3358 {
3359 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3360 }
3361
3362
3365
3366
3369 center = ModelToWorld( center );
3370
3371
3374
3375 areaDamage.SetExtents( extents[0], extents[1] );
3376 areaDamage.SetAreaPosition( center );
3380 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3381 areaDamage.SetAmmoName( "BarbedWireHit" );
3382 areaDamage.Spawn();
3383
3385 }
3386 }
3387
3389 {
3390 if ( angle_deg != 0 )
3391 {
3392
3394
3395
3397 if ( MemoryPointExists( "rotate_axis" ) )
3398 {
3399 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3400 }
3401 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];
3402 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];
3403 center[0] = r_center_x;
3404 center[2] = r_center_z;
3405 }
3406 }
3407
3409 {
3411 {
3414 {
3415 if (areaDamage)
3416 {
3417 areaDamage.Destroy();
3418 }
3419
3421 }
3422 }
3423 }
3424
3426 {
3427 return true;
3428 }
3429
3430
3431
3432
3434 {
3436 }
3437
3439 {
3441 }
3442
3444 {
3446 }
3447
3449 {
3451
3452 switch ( material_type )
3453 {
3459 }
3460
3461 return "";
3462 }
3463
3465 {
3467
3468 switch ( material_type )
3469 {
3475 }
3476
3477 return "";
3478 }
3479
3480
3482 {
3484 {
3485
3487 {
3488 SetHealth(slot_name,"Health",item.GetHealth());
3489 }
3490 }
3491 }
3492
3494 {
3495 return 111;
3496 }
3497
3499 {
3500 super.SetActions();
3501
3505 }
3506
3508 {
3510 if (!construction)
3511 return;
3512
3514 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3515 {
3518 {
3520 }
3521 }
3522 }
3523
3525 {
3527 if (!construction)
3528 return;
3529
3531 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3532 {
3535 {
3536 construction.HandleEntityFalling(part.
GetPartName());
3537 }
3538 }
3539 }
3540
3543 {
3545 return;
3546
3549
3550 if (DestroyOnFall())
3551 {
3553 {
3555 }
3556 else
3557 {
3559 {
3561 }
3563 }
3564 }
3565 }
3566
3568 {
3569 if (HasAnyAttachmentsOrCargo())
3570 {
3573 }
3574 }
3575
3576
3577
3578
3579
3582 {
3583 return null;
3584 }
3585
3587 {
3589 }
3590
3592 {
3595
3596 Man p;
3597
3598 #ifdef SERVER
3600 g_Game.GetWorld().GetPlayerList(players);
3601 if (players.Count())
3602 p = players[0];
3603 #else
3605 #endif
3606
3608 {
3609 bool excluded = false;
3611 if (excludes)
3612 {
3613 foreach (string exclude : excludes)
3614 {
3616 {
3617 excluded = true;
3618 break;
3619 }
3620 }
3621 }
3622
3623 if (!excluded)
3624 {
3626 }
3627 }
3628
3630 }
3631
3633
3635 [
Obsolete(
"handled in the Construction component directly")]
3637 {
3638 }
3639
3640 [
Obsolete(
"handled in the Construction component directly")]
3642 {
3643 }
3644
3645 [
Obsolete(
"obsolete debug method")]
3647 {
3648 }
3649}
3650
3652{
3653#ifdef BSB_DEBUG
3655#else
3656
3657#endif
3658}
3660{
3661#ifdef BSB_DEBUG_SPAM
3663#else
3664
3665#endif
3666}
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.