2378{
2380
2382
2384
2391
2392
2393
2399
2405
2407
2411
2412
2414 {
2416
2417
2418 RegisterNetSyncVariableInt( "m_SyncParts01" );
2419 RegisterNetSyncVariableInt( "m_SyncParts02" );
2420 RegisterNetSyncVariableInt( "m_SyncParts03" );
2421 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2422 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2423 RegisterNetSyncVariableBool( "m_HasBase" );
2424
2425
2426 ConstructionInit();
2427
2428 if (ConfigIsExisting("hybridAttachments"))
2429 {
2432 }
2433 if (ConfigIsExisting("mountables"))
2434 {
2437 }
2438
2440 SetAllowDamage(true);
2441 }
2442
2444 {
2445 return "disableBaseDamage";
2446 }
2447
2449 {
2450 return true;
2451 }
2452
2454 {
2455 return EInventoryIconVisibility.HIDE_VICINITY;
2456 }
2457
2459 {
2460 super.InitItemSounds();
2461
2465
2470 }
2471
2473 {
2474 return "putDown_FenceKit_SoundSet";
2475 }
2476
2478 {
2479 return "Shelter_Site_Build_Loop_SoundSet";
2480 }
2481
2482
2484 {
2486 {
2487 SetSynchDirty();
2488 }
2489 }
2490
2492 {
2494 super.OnVariablesSynchronized();
2495
2497 }
2498
2500 {
2501
2503
2504
2506
2507
2509 }
2510
2511
2513 {
2514
2515 int offset;
2516 int mask;
2517
2518 if ( part_id >= 1 && part_id <= 31 )
2519 {
2520 offset = part_id - 1;
2521 mask = 1 << offset;
2522
2524 }
2525 else if ( part_id >= 32 && part_id <= 62 )
2526 {
2527 offset = ( part_id % 32 );
2528 mask = 1 << offset;
2529
2531 }
2532 else if ( part_id >= 63 && part_id <= 93 )
2533 {
2534 offset = ( part_id % 63 );
2535 mask = 1 << offset;
2536
2538 }
2539 }
2540
2542 {
2543
2544 int offset;
2545 int mask;
2546
2547 if ( part_id >= 1 && part_id <= 31 )
2548 {
2549 offset = part_id - 1;
2550 mask = 1 << offset;
2551
2553 }
2554 else if ( part_id >= 32 && part_id <= 62 )
2555 {
2556 offset = ( part_id % 32 );
2557 mask = 1 << offset;
2558
2560 }
2561 else if ( part_id >= 63 && part_id <= 93 )
2562 {
2563 offset = ( part_id % 63 );
2564 mask = 1 << offset;
2565
2567 }
2568 }
2569
2571 {
2572
2573 int offset;
2574 int mask;
2575
2576 if ( part_id >= 1 && part_id <= 31 )
2577 {
2578 offset = part_id - 1;
2579 mask = 1 << offset;
2580
2582 {
2583 return true;
2584 }
2585 }
2586 else if ( part_id >= 32 && part_id <= 62 )
2587 {
2588 offset = ( part_id % 32 );
2589 mask = 1 << offset;
2590
2592 {
2593 return true;
2594 }
2595 }
2596 else if ( part_id >= 63 && part_id <= 93 )
2597 {
2598 offset = ( part_id % 63 );
2599 mask = 1 << offset;
2600
2602 {
2603 return true;
2604 }
2605 }
2606
2607 return false;
2608 }
2609
2611 {
2614 }
2615
2617 {
2618
2621 }
2622
2624 {
2626 {
2629
2630 switch( build_action_id )
2631 {
2635 }
2636 }
2637 }
2638
2639
2641 {
2643 bool is_base = part.
IsBase();
2646 if ( is_part_built_sync )
2647 {
2649 {
2653
2654 if (is_base)
2655 {
2658 }
2659 }
2660 }
2661 else
2662 {
2664 {
2668
2669 if (is_base)
2670 {
2673 }
2674 }
2675 }
2676
2677
2679 }
2680
2681
2683 {
2686
2687 for ( int i = 0; i < construction_parts.Count(); ++i )
2688 {
2689 string key = construction_parts.GetKey( i );
2692 }
2693
2694
2696 }
2697
2699 {
2702
2703 for ( int i = 0; i < construction_parts.Count(); ++i )
2704 {
2705 string key = construction_parts.GetKey( i );
2707
2708 if ( value.
GetId() ==
id )
2709 {
2710 return value;
2711 }
2712 }
2713
2714 return NULL;
2715 }
2716
2717
2718
2720 {
2722 }
2723
2725 {
2727 }
2728
2730 {
2731 return true;
2732 }
2733
2735 {
2736 return false;
2737 }
2738
2739
2741 {
2744 {
2746 }
2747
2748 return construction_kit;
2749 }
2750
2752 {
2755 {
2757 }
2758 }
2759
2761 {
2763 }
2764
2766 {
2767 return "";
2768 }
2769
2771 {
2773 g_Game.ObjectDelete( construction_kit );
2774 }
2775
2776
2778 {
2780 g_Game.ObjectDelete(
this );
2781 }
2782
2783
2785 {
2786 super.EEDelete(parent);
2787
2789 {
2790 areaDamage.Destroy();
2791 }
2792
2793 }
2794
2796 {
2797 super.OnStoreSave( ctx );
2798
2799
2803
2805 }
2806
2808 {
2809 if ( !super.OnStoreLoad( ctx, version ) )
2810 return false;
2811
2812
2813
2815 {
2817 return false;
2818 }
2820 {
2822 return false;
2823 }
2825 {
2827 return false;
2828 }
2829
2830
2832 {
2834 return false;
2835 }
2836
2837
2838 return true;
2839 }
2840
2842 {
2843 super.AfterStoreLoad();
2844
2846 {
2848 }
2849 }
2850
2852 {
2853
2855
2856
2859
2860
2862 }
2863
2865 {
2866 super.OnCreatePhysics();
2867
2868 ConstructionInit();
2870 }
2871
2873 {
2875 return;
2876
2877 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2878 }
2879
2881 {
2883 {
2885 }
2886
2887 super.EEOnAfterLoad();
2888 }
2889
2891 {
2892 super.EEItemAttached( item, slot_name );
2893
2897 }
2898
2900 {
2901 super.EEItemDetached( item, slot_name );
2902
2905 }
2906
2907 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2908 {
2911
2914 }
2915
2916
2918 {
2919 return true;
2920 }
2921
2922
2923
2925 {
2927
2928
2929 if (construtionPart.
IsBase())
2930 {
2932
2933
2935 }
2936
2937
2939
2940
2942
2943
2945
2947
2949
2950
2952
2953
2955 }
2956
2958 {
2959
2961 }
2962
2963
2965 {
2968
2969
2971
2972
2974
2975
2977
2978
2980
2982
2983
2985
2986
2988
2989
2990 if (construtionPart.
IsBase())
2991 {
2992
2994 }
2995 }
2996
2998 {
2999
3001 }
3002
3003
3004 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
3005 {
3008
3009
3011
3012
3014
3015
3017
3018
3020
3022
3023
3025
3026
3028
3029
3030 if (construtionPart.
IsBase())
3031 {
3032
3034 }
3035 }
3036
3038 {
3039
3041 }
3042
3043
3045 {
3047
3050 }
3051
3053 {
3055
3057 {
3059 }
3060 else
3061 {
3063 }
3064
3066 }
3067
3069 {
3071
3073 foreach (
string slotName : attachmentSlots)
3074 {
3076 }
3077
3078
3081 else
3083
3085 }
3086
3088 {
3089 string slotNameMounted = slot_name + "_Mounted";
3090 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3091
3092 if (attachment)
3093 {
3094 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3095 if (barbedWire && barbedWire.IsMounted())
3097 else
3099
3100 if (is_locked)
3101 {
3102 SetAnimationPhase(slotNameMounted, 0);
3103 SetAnimationPhase(slot_name, 1);
3104 }
3105 else
3106 {
3107 SetAnimationPhase(slotNameMounted, 1);
3108 SetAnimationPhase(slot_name, 0);
3109 }
3110 }
3111 else
3112 {
3113 SetAnimationPhase(slotNameMounted, 1);
3114 SetAnimationPhase(slot_name, 1);
3115
3117 }
3118 }
3119
3120
3122 {
3125
3128
3131
3132 foreach (
string slotName : attachmentSlots)
3133 {
3135 }
3136
3137
3139 {
3142
3144 }
3145 else
3146 {
3149
3151 }
3152
3155 }
3156
3158 {
3159
3161 return;
3162
3163 string slot_name_mounted = slot_name + "_Mounted";
3164 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3165
3166
3168 RemoveProxyPhysics( slot_name_mounted );
3169 RemoveProxyPhysics( slot_name );
3170
3171 if ( attachment )
3172 {
3174 if ( is_locked )
3175 {
3177 AddProxyPhysics( slot_name_mounted );
3178 }
3179 else
3180 {
3182 AddProxyPhysics( slot_name );
3183 }
3184 }
3185 }
3186
3188 {
3189 SetAffectPathgraph( true, false );
3191 }
3192
3194 {
3195 return true;
3196 }
3197
3199 {
3200 return true;
3201 }
3202
3204 {
3205 if ( attachment )
3206 {
3208 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3209
3210 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3211 }
3212
3213 return false;
3214 }
3215
3217 {
3219 }
3220
3221
3223 {
3224 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3225 if (
g_Game.ConfigIsExisting( config_path ) )
3226 {
3227 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3228 }
3229 }
3230
3232 {
3233 return true;
3234 }
3235
3237 {
3238 return true;
3239 }
3240
3242 {
3243 return true;
3244 }
3245
3246
3248 {
3251 }
3252
3254 {
3256 }
3257
3259 {
3261 }
3262
3264 {
3265 int attachment_count = GetInventory().AttachmentCount();
3266 if ( attachment_count > 0 )
3267 {
3268 if (
HasBase() && attachment_count == 1 )
3269 {
3270 return false;
3271 }
3272
3273 return true;
3274 }
3275
3276 return false;
3277 }
3278
3280 {
3281 return true;
3282 }
3283
3285 {
3286 return false;
3287 }
3288
3289
3291 {
3292 return false;
3293 }
3294
3296 {
3297 return false;
3298 }
3299
3300
3302 {
3303 return false;
3304 }
3305
3306
3307
3309 {
3310 return true;
3311 }
3312
3314 {
3315 return true;
3316 }
3317
3320 {
3321 return false;
3322 }
3323
3324
3326 {
3327 return false;
3328 }
3329
3330
3332 {
3333 return true;
3334 }
3335
3336
3338 {
3339 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3340 {
3341 return false;
3342 }
3343
3344 return true;
3345 }
3346
3348 {
3351
3352 return item;
3353 }
3354
3355
3357 {
3359 {
3360
3362
3363
3366
3368 if ( MemoryPointExists( slot_name + "_min" ) )
3369 {
3370 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3371 }
3372 if ( MemoryPointExists( slot_name + "_max" ) )
3373 {
3374 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3375 }
3376
3377
3380
3381
3384 center = ModelToWorld( center );
3385
3386
3389
3390 areaDamage.SetExtents( extents[0], extents[1] );
3391 areaDamage.SetAreaPosition( center );
3395 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3396 areaDamage.SetAmmoName( "BarbedWireHit" );
3397 areaDamage.Spawn();
3398
3400 }
3401 }
3402
3404 {
3405 if ( angle_deg != 0 )
3406 {
3407
3409
3410
3412 if ( MemoryPointExists( "rotate_axis" ) )
3413 {
3414 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3415 }
3416 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];
3417 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];
3418 center[0] = r_center_x;
3419 center[2] = r_center_z;
3420 }
3421 }
3422
3424 {
3426 {
3429 {
3430 if (areaDamage)
3431 {
3432 areaDamage.Destroy();
3433 }
3434
3436 }
3437 }
3438 }
3439
3441 {
3442 return true;
3443 }
3444
3445
3446
3447
3449 {
3451 }
3452
3454 {
3456 }
3457
3459 {
3461 }
3462
3464 {
3466
3467 switch ( material_type )
3468 {
3474 }
3475
3476 return "";
3477 }
3478
3480 {
3482
3483 switch ( material_type )
3484 {
3490 }
3491
3492 return "";
3493 }
3494
3495
3497 {
3499 {
3500
3502 {
3503 SetHealth(slot_name,"Health",item.GetHealth());
3504 }
3505 }
3506 }
3507
3509 {
3510 return 111;
3511 }
3512
3514 {
3515 super.SetActions();
3516
3520 }
3521
3523 {
3525 if (!construction)
3526 return;
3527
3529 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3530 {
3533 {
3535 }
3536 }
3537 }
3538
3540 {
3542 if (!construction)
3543 return;
3544
3546 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3547 {
3550 {
3551 construction.HandleEntityFalling(part.
GetPartName());
3552 }
3553 }
3554 }
3555
3558 {
3560 return;
3561
3564
3565 if (DestroyOnFall())
3566 {
3568 {
3570 }
3571 else
3572 {
3574 {
3576 }
3578 }
3579 }
3580 }
3581
3583 {
3584 if (HasAnyAttachmentsOrCargo())
3585 {
3588 }
3589 }
3590
3591
3592
3593
3594
3597 {
3598 return null;
3599 }
3600
3602 {
3604 }
3605
3607 {
3610
3611 Man p;
3612
3613 #ifdef SERVER
3615 g_Game.GetWorld().GetPlayerList(players);
3616 if (players.Count())
3617 p = players[0];
3618 #else
3620 #endif
3621
3623 {
3624 bool excluded = false;
3626 if (excludes)
3627 {
3628 foreach (string exclude : excludes)
3629 {
3631 {
3632 excluded = true;
3633 break;
3634 }
3635 }
3636 }
3637
3638 if (!excluded)
3639 {
3641 }
3642 }
3643
3645 }
3646
3648
3650 [
Obsolete(
"handled in the Construction component directly")]
3652 {
3653 }
3654
3655 [
Obsolete(
"handled in the Construction component directly")]
3657 {
3658 }
3659
3660 [
Obsolete(
"obsolete debug method")]
3662 {
3663 }
3664}
3665
3667{
3668#ifdef BSB_DEBUG
3670#else
3671
3672#endif
3673}
3675{
3676#ifdef BSB_DEBUG_SPAM
3678#else
3679
3680#endif
3681}
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.