2318{
2320
2322
2324
2331
2332
2333
2339
2345
2347
2351
2352
2354 {
2356
2357
2358 RegisterNetSyncVariableInt( "m_SyncParts01" );
2359 RegisterNetSyncVariableInt( "m_SyncParts02" );
2360 RegisterNetSyncVariableInt( "m_SyncParts03" );
2361 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2362 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2363 RegisterNetSyncVariableBool( "m_HasBase" );
2364
2365
2366 ConstructionInit();
2367
2368 if (ConfigIsExisting("hybridAttachments"))
2369 {
2372 }
2373 if (ConfigIsExisting("mountables"))
2374 {
2377 }
2378
2380 SetAllowDamage(true);
2381 }
2382
2384 {
2385 return "disableBaseDamage";
2386 }
2387
2389 {
2390 return true;
2391 }
2392
2394 {
2395 return EInventoryIconVisibility.HIDE_VICINITY;
2396 }
2397
2399 {
2400 super.InitItemSounds();
2401
2405
2410 }
2411
2413 {
2414 return "putDown_FenceKit_SoundSet";
2415 }
2416
2418 {
2419 return "Shelter_Site_Build_Loop_SoundSet";
2420 }
2421
2422
2424 {
2426 {
2427 SetSynchDirty();
2428 }
2429 }
2430
2432 {
2434 super.OnVariablesSynchronized();
2435
2437 }
2438
2440 {
2441
2443
2444
2446
2447
2449 }
2450
2451
2453 {
2454
2455 int offset;
2456 int mask;
2457
2458 if ( part_id >= 1 && part_id <= 31 )
2459 {
2460 offset = part_id - 1;
2461 mask = 1 << offset;
2462
2464 }
2465 else if ( part_id >= 32 && part_id <= 62 )
2466 {
2467 offset = ( part_id % 32 );
2468 mask = 1 << offset;
2469
2471 }
2472 else if ( part_id >= 63 && part_id <= 93 )
2473 {
2474 offset = ( part_id % 63 );
2475 mask = 1 << offset;
2476
2478 }
2479 }
2480
2482 {
2483
2484 int offset;
2485 int mask;
2486
2487 if ( part_id >= 1 && part_id <= 31 )
2488 {
2489 offset = part_id - 1;
2490 mask = 1 << offset;
2491
2493 }
2494 else if ( part_id >= 32 && part_id <= 62 )
2495 {
2496 offset = ( part_id % 32 );
2497 mask = 1 << offset;
2498
2500 }
2501 else if ( part_id >= 63 && part_id <= 93 )
2502 {
2503 offset = ( part_id % 63 );
2504 mask = 1 << offset;
2505
2507 }
2508 }
2509
2511 {
2512
2513 int offset;
2514 int mask;
2515
2516 if ( part_id >= 1 && part_id <= 31 )
2517 {
2518 offset = part_id - 1;
2519 mask = 1 << offset;
2520
2522 {
2523 return true;
2524 }
2525 }
2526 else if ( part_id >= 32 && part_id <= 62 )
2527 {
2528 offset = ( part_id % 32 );
2529 mask = 1 << offset;
2530
2532 {
2533 return true;
2534 }
2535 }
2536 else if ( part_id >= 63 && part_id <= 93 )
2537 {
2538 offset = ( part_id % 63 );
2539 mask = 1 << offset;
2540
2542 {
2543 return true;
2544 }
2545 }
2546
2547 return false;
2548 }
2549
2551 {
2554 }
2555
2557 {
2558
2561 }
2562
2564 {
2566 {
2569
2570 switch( build_action_id )
2571 {
2575 }
2576 }
2577 }
2578
2579
2581 {
2583 bool is_base = part.
IsBase();
2586 if ( is_part_built_sync )
2587 {
2589 {
2593
2594 if (is_base)
2595 {
2598 }
2599 }
2600 }
2601 else
2602 {
2604 {
2608
2609 if (is_base)
2610 {
2613 }
2614 }
2615 }
2616
2617
2619 }
2620
2621
2623 {
2626
2627 for ( int i = 0; i < construction_parts.Count(); ++i )
2628 {
2629 string key = construction_parts.GetKey( i );
2632 }
2633
2634
2636 }
2637
2639 {
2642
2643 for ( int i = 0; i < construction_parts.Count(); ++i )
2644 {
2645 string key = construction_parts.GetKey( i );
2647
2648 if ( value.
GetId() ==
id )
2649 {
2650 return value;
2651 }
2652 }
2653
2654 return NULL;
2655 }
2656
2657
2658
2660 {
2662 }
2663
2665 {
2667 }
2668
2670 {
2671 return true;
2672 }
2673
2675 {
2676 return false;
2677 }
2678
2679
2681 {
2684 {
2686 }
2687
2688 return construction_kit;
2689 }
2690
2692 {
2695 {
2697 }
2698 }
2699
2701 {
2703 }
2704
2706 {
2707 return "";
2708 }
2709
2711 {
2713 g_Game.ObjectDelete( construction_kit );
2714 }
2715
2716
2718 {
2720 g_Game.ObjectDelete(
this );
2721 }
2722
2723
2725 {
2726 super.EEDelete(parent);
2727
2729 {
2730 areaDamage.Destroy();
2731 }
2732
2733 }
2734
2736 {
2737 super.OnStoreSave( ctx );
2738
2739
2743
2745 }
2746
2748 {
2749 if ( !super.OnStoreLoad( ctx, version ) )
2750 return false;
2751
2752
2753
2755 {
2757 return false;
2758 }
2760 {
2762 return false;
2763 }
2765 {
2767 return false;
2768 }
2769
2770
2772 {
2774 return false;
2775 }
2776
2777
2778 return true;
2779 }
2780
2782 {
2783 super.AfterStoreLoad();
2784
2786 {
2788 }
2789 }
2790
2792 {
2793
2795
2796
2799
2800
2802 }
2803
2805 {
2806 super.OnCreatePhysics();
2807
2808 ConstructionInit();
2810 }
2811
2813 {
2815 return;
2816
2817 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2818 }
2819
2821 {
2823 {
2825 }
2826
2827 super.EEOnAfterLoad();
2828 }
2829
2831 {
2832 super.EEItemAttached( item, slot_name );
2833
2837 }
2838
2840 {
2841 super.EEItemDetached( item, slot_name );
2842
2845 }
2846
2847 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2848 {
2851
2854 }
2855
2856
2858 {
2859 return true;
2860 }
2861
2862
2863
2865 {
2867
2868
2869 if (construtionPart.
IsBase())
2870 {
2872
2873
2875 }
2876
2877
2879
2880
2882
2883
2885
2887
2889
2890
2892
2893
2895 }
2896
2898 {
2899
2901 }
2902
2903
2905 {
2908
2909
2911
2912
2914
2915
2917
2918
2920
2922
2923
2925
2926
2928
2929
2930 if (construtionPart.
IsBase())
2931 {
2932
2934 }
2935 }
2936
2938 {
2939
2941 }
2942
2943
2944 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2945 {
2948
2949
2951
2952
2954
2955
2957
2958
2960
2962
2963
2965
2966
2968
2969
2970 if (construtionPart.
IsBase())
2971 {
2972
2974 }
2975 }
2976
2978 {
2979
2981 }
2982
2983
2985 {
2987
2990 }
2991
2993 {
2995
2997 {
2999 }
3000 else
3001 {
3003 }
3004
3006 }
3007
3009 {
3011
3013 foreach (
string slotName : attachmentSlots)
3014 {
3016 }
3017
3018
3021 else
3023
3025 }
3026
3028 {
3029 string slotNameMounted = slot_name + "_Mounted";
3030 EntityAI attachment = FindAttachmentBySlotName(slot_name);
3031
3032 if (attachment)
3033 {
3034 BarbedWire barbedWire = BarbedWire.Cast(attachment);
3035 if (barbedWire && barbedWire.IsMounted())
3037 else
3039
3040 if (is_locked)
3041 {
3042 SetAnimationPhase(slotNameMounted, 0);
3043 SetAnimationPhase(slot_name, 1);
3044 }
3045 else
3046 {
3047 SetAnimationPhase(slotNameMounted, 1);
3048 SetAnimationPhase(slot_name, 0);
3049 }
3050 }
3051 else
3052 {
3053 SetAnimationPhase(slotNameMounted, 1);
3054 SetAnimationPhase(slot_name, 1);
3055
3057 }
3058 }
3059
3060
3062 {
3065
3068
3071
3072 foreach (
string slotName : attachmentSlots)
3073 {
3075 }
3076
3077
3079 {
3082
3084 }
3085 else
3086 {
3089
3091 }
3092
3095 }
3096
3098 {
3099
3101 return;
3102
3103 string slot_name_mounted = slot_name + "_Mounted";
3104 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3105
3106
3108 RemoveProxyPhysics( slot_name_mounted );
3109 RemoveProxyPhysics( slot_name );
3110
3111 if ( attachment )
3112 {
3114 if ( is_locked )
3115 {
3117 AddProxyPhysics( slot_name_mounted );
3118 }
3119 else
3120 {
3122 AddProxyPhysics( slot_name );
3123 }
3124 }
3125 }
3126
3128 {
3129 SetAffectPathgraph( true, false );
3131 }
3132
3134 {
3135 return true;
3136 }
3137
3139 {
3140 return true;
3141 }
3142
3144 {
3145 if ( attachment )
3146 {
3148 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3149
3150 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3151 }
3152
3153 return false;
3154 }
3155
3157 {
3159 }
3160
3161
3163 {
3164 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3165 if (
g_Game.ConfigIsExisting( config_path ) )
3166 {
3167 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3168 }
3169 }
3170
3172 {
3173 return true;
3174 }
3175
3177 {
3178 return true;
3179 }
3180
3182 {
3183 return true;
3184 }
3185
3186
3188 {
3191 }
3192
3194 {
3196 }
3197
3199 {
3201 }
3202
3204 {
3205 int attachment_count = GetInventory().AttachmentCount();
3206 if ( attachment_count > 0 )
3207 {
3208 if (
HasBase() && attachment_count == 1 )
3209 {
3210 return false;
3211 }
3212
3213 return true;
3214 }
3215
3216 return false;
3217 }
3218
3220 {
3221 return true;
3222 }
3223
3225 {
3226 return false;
3227 }
3228
3229
3231 {
3232 return false;
3233 }
3234
3236 {
3237 return false;
3238 }
3239
3240
3242 {
3243 return false;
3244 }
3245
3246
3247
3249 {
3250 return true;
3251 }
3252
3254 {
3255 return true;
3256 }
3257
3260 {
3261 return false;
3262 }
3263
3264
3266 {
3267 return false;
3268 }
3269
3270
3272 {
3273 return true;
3274 }
3275
3276
3278 {
3279 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3280 {
3281 return false;
3282 }
3283
3284 return true;
3285 }
3286
3288 {
3291
3292 return item;
3293 }
3294
3295
3297 {
3299 {
3300
3302
3303
3306
3308 if ( MemoryPointExists( slot_name + "_min" ) )
3309 {
3310 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3311 }
3312 if ( MemoryPointExists( slot_name + "_max" ) )
3313 {
3314 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3315 }
3316
3317
3320
3321
3324 center = ModelToWorld( center );
3325
3326
3329
3330 areaDamage.SetExtents( extents[0], extents[1] );
3331 areaDamage.SetAreaPosition( center );
3335 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3336 areaDamage.SetAmmoName( "BarbedWireHit" );
3337 areaDamage.Spawn();
3338
3340 }
3341 }
3342
3344 {
3345 if ( angle_deg != 0 )
3346 {
3347
3349
3350
3352 if ( MemoryPointExists( "rotate_axis" ) )
3353 {
3354 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3355 }
3356 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];
3357 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];
3358 center[0] = r_center_x;
3359 center[2] = r_center_z;
3360 }
3361 }
3362
3364 {
3366 {
3369 {
3370 if (areaDamage)
3371 {
3372 areaDamage.Destroy();
3373 }
3374
3376 }
3377 }
3378 }
3379
3381 {
3382 return true;
3383 }
3384
3385
3386
3387
3389 {
3391 }
3392
3394 {
3396 }
3397
3399 {
3401 }
3402
3404 {
3406
3407 switch ( material_type )
3408 {
3414 }
3415
3416 return "";
3417 }
3418
3420 {
3422
3423 switch ( material_type )
3424 {
3430 }
3431
3432 return "";
3433 }
3434
3435
3437 {
3439 {
3440
3442 {
3443 SetHealth(slot_name,"Health",item.GetHealth());
3444 }
3445 }
3446 }
3447
3449 {
3450 return 111;
3451 }
3452
3454 {
3455 super.SetActions();
3456
3460 }
3461
3463 {
3465 if (!construction)
3466 return;
3467
3469 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3470 {
3473 {
3475 }
3476 }
3477 }
3478
3480 {
3482 if (!construction)
3483 return;
3484
3486 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3487 {
3490 {
3491 construction.HandleEntityFalling(part.
GetPartName());
3492 }
3493 }
3494 }
3495
3498 {
3500 return;
3501
3504
3505 if (DestroyOnFall())
3506 {
3508 {
3510 }
3511 else
3512 {
3514 {
3516 }
3518 }
3519 }
3520 }
3521
3523 {
3524 if (HasAnyAttachmentsOrCargo())
3525 {
3528 }
3529 }
3530
3531
3532
3533
3534
3537 {
3538 return null;
3539 }
3540
3542 {
3544 }
3545
3547 {
3550
3551 Man p;
3552
3553 #ifdef SERVER
3555 g_Game.GetWorld().GetPlayerList(players);
3556 if (players.Count())
3557 p = players[0];
3558 #else
3560 #endif
3561
3563 {
3564 bool excluded = false;
3566 if (excludes)
3567 {
3568 foreach (string exclude : excludes)
3569 {
3571 {
3572 excluded = true;
3573 break;
3574 }
3575 }
3576 }
3577
3578 if (!excluded)
3579 {
3581 }
3582 }
3583
3585 }
3586
3588
3590 [
Obsolete(
"handled in the Construction component directly")]
3592 {
3593 }
3594
3595 [
Obsolete(
"handled in the Construction component directly")]
3597 {
3598 }
3599
3600 [
Obsolete(
"obsolete debug method")]
3602 {
3603 }
3604}
3605
3607{
3608#ifdef BSB_DEBUG
3610#else
3611
3612#endif
3613}
3615{
3616#ifdef BSB_DEBUG_SPAM
3618#else
3619
3620#endif
3621}
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.