2271{
2273
2275
2277
2284
2285
2286
2292
2298
2300
2304
2305
2307 {
2309
2310
2311 RegisterNetSyncVariableInt( "m_SyncParts01" );
2312 RegisterNetSyncVariableInt( "m_SyncParts02" );
2313 RegisterNetSyncVariableInt( "m_SyncParts03" );
2314 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2315 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2316 RegisterNetSyncVariableBool( "m_HasBase" );
2317
2318
2319 ConstructionInit();
2320
2321 if (ConfigIsExisting("hybridAttachments"))
2322 {
2325 }
2326 if (ConfigIsExisting("mountables"))
2327 {
2330 }
2331
2333 SetAllowDamage(true);
2334 }
2335
2337 {
2338 return "disableBaseDamage";
2339 }
2340
2342 {
2343 return true;
2344 }
2345
2347 {
2348 return EInventoryIconVisibility.HIDE_VICINITY;
2349 }
2350
2352 {
2353 super.InitItemSounds();
2354
2358
2363 }
2364
2366 {
2367 return "putDown_FenceKit_SoundSet";
2368 }
2369
2371 {
2372 return "Shelter_Site_Build_Loop_SoundSet";
2373 }
2374
2375
2377 {
2379 {
2380 SetSynchDirty();
2381 }
2382 }
2383
2385 {
2387 super.OnVariablesSynchronized();
2388
2390 }
2391
2393 {
2394
2396
2397
2399
2400
2402 }
2403
2404
2406 {
2407
2408 int offset;
2409 int mask;
2410
2411 if ( part_id >= 1 && part_id <= 31 )
2412 {
2413 offset = part_id - 1;
2414 mask = 1 << offset;
2415
2417 }
2418 else if ( part_id >= 32 && part_id <= 62 )
2419 {
2420 offset = ( part_id % 32 );
2421 mask = 1 << offset;
2422
2424 }
2425 else if ( part_id >= 63 && part_id <= 93 )
2426 {
2427 offset = ( part_id % 63 );
2428 mask = 1 << offset;
2429
2431 }
2432 }
2433
2435 {
2436
2437 int offset;
2438 int mask;
2439
2440 if ( part_id >= 1 && part_id <= 31 )
2441 {
2442 offset = part_id - 1;
2443 mask = 1 << offset;
2444
2446 }
2447 else if ( part_id >= 32 && part_id <= 62 )
2448 {
2449 offset = ( part_id % 32 );
2450 mask = 1 << offset;
2451
2453 }
2454 else if ( part_id >= 63 && part_id <= 93 )
2455 {
2456 offset = ( part_id % 63 );
2457 mask = 1 << offset;
2458
2460 }
2461 }
2462
2464 {
2465
2466 int offset;
2467 int mask;
2468
2469 if ( part_id >= 1 && part_id <= 31 )
2470 {
2471 offset = part_id - 1;
2472 mask = 1 << offset;
2473
2475 {
2476 return true;
2477 }
2478 }
2479 else if ( part_id >= 32 && part_id <= 62 )
2480 {
2481 offset = ( part_id % 32 );
2482 mask = 1 << offset;
2483
2485 {
2486 return true;
2487 }
2488 }
2489 else if ( part_id >= 63 && part_id <= 93 )
2490 {
2491 offset = ( part_id % 63 );
2492 mask = 1 << offset;
2493
2495 {
2496 return true;
2497 }
2498 }
2499
2500 return false;
2501 }
2502
2504 {
2507 }
2508
2510 {
2511
2514 }
2515
2517 {
2519 {
2522
2523 switch( build_action_id )
2524 {
2528 }
2529 }
2530 }
2531
2532
2534 {
2536 bool is_base = part.
IsBase();
2539 if ( is_part_built_sync )
2540 {
2542 {
2546
2547 if (is_base)
2548 {
2551 }
2552 }
2553 }
2554 else
2555 {
2557 {
2561
2562 if (is_base)
2563 {
2566 }
2567 }
2568 }
2569
2570
2572 }
2573
2574
2576 {
2579
2580 for ( int i = 0; i < construction_parts.Count(); ++i )
2581 {
2582 string key = construction_parts.GetKey( i );
2585 }
2586
2587
2589 }
2590
2592 {
2595
2596 for ( int i = 0; i < construction_parts.Count(); ++i )
2597 {
2598 string key = construction_parts.GetKey( i );
2600
2601 if ( value.
GetId() ==
id )
2602 {
2603 return value;
2604 }
2605 }
2606
2607 return NULL;
2608 }
2609
2610
2611
2613 {
2615 }
2616
2618 {
2620 }
2621
2623 {
2624 return true;
2625 }
2626
2628 {
2629 return false;
2630 }
2631
2632
2634 {
2637 {
2639 }
2640
2641 return construction_kit;
2642 }
2643
2645 {
2648 {
2650 }
2651 }
2652
2654 {
2656 }
2657
2659 {
2660 return "";
2661 }
2662
2664 {
2666 g_Game.ObjectDelete( construction_kit );
2667 }
2668
2669
2671 {
2673 g_Game.ObjectDelete(
this );
2674 }
2675
2676
2678 {
2679 super.EEDelete(parent);
2680
2682 {
2683 areaDamage.Destroy();
2684 }
2685
2686 }
2687
2689 {
2690 super.OnStoreSave( ctx );
2691
2692
2696
2698 }
2699
2701 {
2702 if ( !super.OnStoreLoad( ctx, version ) )
2703 return false;
2704
2705
2706
2708 {
2710 return false;
2711 }
2713 {
2715 return false;
2716 }
2718 {
2720 return false;
2721 }
2722
2723
2725 {
2727 return false;
2728 }
2729
2730
2731 return true;
2732 }
2733
2735 {
2736 super.AfterStoreLoad();
2737
2739 {
2741 }
2742 }
2743
2745 {
2746
2748
2749
2752
2753
2755 }
2756
2758 {
2759 super.OnCreatePhysics();
2760
2761 ConstructionInit();
2763 }
2764
2766 {
2768 return;
2769
2770 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2771 }
2772
2774 {
2776 {
2778 }
2779
2780 super.EEOnAfterLoad();
2781 }
2782
2784 {
2785 super.EEItemAttached( item, slot_name );
2786
2790 }
2791
2793 {
2794 super.EEItemDetached( item, slot_name );
2795
2798 }
2799
2800 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2801 {
2804
2807 }
2808
2809
2811 {
2812 return true;
2813 }
2814
2815
2816
2818 {
2820
2821
2822 if (construtionPart.
IsBase())
2823 {
2825
2826
2828 }
2829
2830
2832
2833
2835
2836
2838
2840
2842
2843
2845
2846
2848 }
2849
2851 {
2852
2854 }
2855
2856
2858 {
2861
2862
2864
2865
2867
2868
2870
2871
2873
2875
2876
2878
2879
2881
2882
2883 if (construtionPart.
IsBase())
2884 {
2885
2887 }
2888 }
2889
2891 {
2892
2894 }
2895
2896
2897 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2898 {
2901
2902
2904
2905
2907
2908
2910
2911
2913
2915
2916
2918
2919
2921
2922
2923 if (construtionPart.
IsBase())
2924 {
2925
2927 }
2928 }
2929
2931 {
2932
2934 }
2935
2936
2938 {
2940
2943 }
2944
2946 {
2948
2950 {
2952 }
2953 else
2954 {
2956 }
2957
2959 }
2960
2962 {
2964
2966 foreach (
string slotName : attachmentSlots)
2967 {
2969 }
2970
2971
2974 else
2976
2978 }
2979
2981 {
2982 string slotNameMounted = slot_name + "_Mounted";
2983 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2984
2985 if (attachment)
2986 {
2987 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2988 if (barbedWire && barbedWire.IsMounted())
2990 else
2992
2993 if (is_locked)
2994 {
2995 SetAnimationPhase(slotNameMounted, 0);
2996 SetAnimationPhase(slot_name, 1);
2997 }
2998 else
2999 {
3000 SetAnimationPhase(slotNameMounted, 1);
3001 SetAnimationPhase(slot_name, 0);
3002 }
3003 }
3004 else
3005 {
3006 SetAnimationPhase(slotNameMounted, 1);
3007 SetAnimationPhase(slot_name, 1);
3008
3010 }
3011 }
3012
3013
3015 {
3018
3021
3024
3025 foreach (
string slotName : attachmentSlots)
3026 {
3028 }
3029
3030
3032 {
3035
3037 }
3038 else
3039 {
3042
3044 }
3045
3048 }
3049
3051 {
3052
3054 return;
3055
3056 string slot_name_mounted = slot_name + "_Mounted";
3057 EntityAI attachment = FindAttachmentBySlotName( slot_name );
3058
3059
3061 RemoveProxyPhysics( slot_name_mounted );
3062 RemoveProxyPhysics( slot_name );
3063
3064 if ( attachment )
3065 {
3067 if ( is_locked )
3068 {
3070 AddProxyPhysics( slot_name_mounted );
3071 }
3072 else
3073 {
3075 AddProxyPhysics( slot_name );
3076 }
3077 }
3078 }
3079
3081 {
3082 SetAffectPathgraph( true, false );
3084 }
3085
3087 {
3088 return true;
3089 }
3090
3092 {
3093 return true;
3094 }
3095
3097 {
3098 if ( attachment )
3099 {
3101 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3102
3103 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3104 }
3105
3106 return false;
3107 }
3108
3110 {
3112 }
3113
3114
3116 {
3117 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3118 if (
g_Game.ConfigIsExisting( config_path ) )
3119 {
3120 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3121 }
3122 }
3123
3125 {
3126 return true;
3127 }
3128
3130 {
3131 return true;
3132 }
3133
3135 {
3136 return true;
3137 }
3138
3139
3141 {
3144 }
3145
3147 {
3149 }
3150
3152 {
3154 }
3155
3157 {
3158 int attachment_count = GetInventory().AttachmentCount();
3159 if ( attachment_count > 0 )
3160 {
3161 if (
HasBase() && attachment_count == 1 )
3162 {
3163 return false;
3164 }
3165
3166 return true;
3167 }
3168
3169 return false;
3170 }
3171
3173 {
3174 return true;
3175 }
3176
3178 {
3179 return false;
3180 }
3181
3182
3184 {
3185 return false;
3186 }
3187
3189 {
3190 return false;
3191 }
3192
3193
3195 {
3196 return false;
3197 }
3198
3199
3200
3202 {
3203 return true;
3204 }
3205
3207 {
3208 return true;
3209 }
3210
3213 {
3214 return false;
3215 }
3216
3217
3219 {
3220 return false;
3221 }
3222
3223
3225 {
3226 return true;
3227 }
3228
3229
3231 {
3232 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3233 {
3234 return false;
3235 }
3236
3237 return true;
3238 }
3239
3241 {
3244
3245 return item;
3246 }
3247
3248
3250 {
3252 {
3253
3255
3256
3259
3261 if ( MemoryPointExists( slot_name + "_min" ) )
3262 {
3263 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3264 }
3265 if ( MemoryPointExists( slot_name + "_max" ) )
3266 {
3267 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3268 }
3269
3270
3273
3274
3277 center = ModelToWorld( center );
3278
3279
3282
3283 areaDamage.SetExtents( extents[0], extents[1] );
3284 areaDamage.SetAreaPosition( center );
3288 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3289 areaDamage.SetAmmoName( "BarbedWireHit" );
3290 areaDamage.Spawn();
3291
3293 }
3294 }
3295
3297 {
3298 if ( angle_deg != 0 )
3299 {
3300
3302
3303
3305 if ( MemoryPointExists( "rotate_axis" ) )
3306 {
3307 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3308 }
3309 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];
3310 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];
3311 center[0] = r_center_x;
3312 center[2] = r_center_z;
3313 }
3314 }
3315
3317 {
3319 {
3322 {
3323 if (areaDamage)
3324 {
3325 areaDamage.Destroy();
3326 }
3327
3329 }
3330 }
3331 }
3332
3334 {
3335 return true;
3336 }
3337
3338
3339
3340
3342 {
3344 }
3345
3347 {
3349 }
3350
3352 {
3354 }
3355
3357 {
3359
3360 switch ( material_type )
3361 {
3367 }
3368
3369 return "";
3370 }
3371
3373 {
3375
3376 switch ( material_type )
3377 {
3383 }
3384
3385 return "";
3386 }
3387
3388
3390 {
3392 {
3393
3395 {
3396 SetHealth(slot_name,"Health",item.GetHealth());
3397 }
3398 }
3399 }
3400
3402 {
3403 return 111;
3404 }
3405
3407 {
3408 super.SetActions();
3409
3413 }
3414
3416 {
3418 if (!construction)
3419 return;
3420
3422 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3423 {
3426 {
3428 }
3429 }
3430 }
3431
3433 {
3435 if (!construction)
3436 return;
3437
3439 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3440 {
3443 {
3444 construction.HandleEntityFalling(part.
GetPartName());
3445 }
3446 }
3447 }
3448
3451 {
3453 return;
3454
3457
3458 if (DestroyOnFall())
3459 {
3461 {
3463 }
3464 else
3465 {
3467 {
3469 }
3471 }
3472 }
3473 }
3474
3476 {
3477 if (HasAnyAttachmentsOrCargo())
3478 {
3481 }
3482 }
3483
3484
3485
3486
3487
3490 {
3491 return null;
3492 }
3493
3495 {
3497 }
3498
3500 {
3503
3504 Man p;
3505
3506 #ifdef SERVER
3508 g_Game.GetWorld().GetPlayerList(players);
3509 if (players.Count())
3510 p = players[0];
3511 #else
3513 #endif
3514
3516 {
3517 bool excluded = false;
3519 if (excludes)
3520 {
3521 foreach (string exclude : excludes)
3522 {
3524 {
3525 excluded = true;
3526 break;
3527 }
3528 }
3529 }
3530
3531 if (!excluded)
3532 {
3534 }
3535 }
3536
3538 }
3539
3541
3543 [
Obsolete(
"handled in the Construction component directly")]
3545 {
3546 }
3547
3548 [
Obsolete(
"handled in the Construction component directly")]
3550 {
3551 }
3552
3553 [
Obsolete(
"obsolete debug method")]
3555 {
3556 }
3557}
3558
3560{
3561#ifdef BSB_DEBUG
3563#else
3564
3565#endif
3566}
3568{
3569#ifdef BSB_DEBUG_SPAM
3571#else
3572
3573#endif
3574}
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.