2178{
2180
2182
2184
2191
2192
2193
2199
2205
2207
2211
2212
2214 {
2216
2217
2218 RegisterNetSyncVariableInt( "m_SyncParts01" );
2219 RegisterNetSyncVariableInt( "m_SyncParts02" );
2220 RegisterNetSyncVariableInt( "m_SyncParts03" );
2221 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2222 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2223 RegisterNetSyncVariableBool( "m_HasBase" );
2224
2225
2226 ConstructionInit();
2227
2228 if (ConfigIsExisting("hybridAttachments"))
2229 {
2232 }
2233 if (ConfigIsExisting("mountables"))
2234 {
2237 }
2238
2240 SetAllowDamage(true);
2241 }
2242
2244 {
2245 return "disableBaseDamage";
2246 }
2247
2249 {
2250 return true;
2251 }
2252
2254 {
2255 return EInventoryIconVisibility.HIDE_VICINITY;
2256 }
2257
2259 {
2260 super.InitItemSounds();
2261
2265
2270 }
2271
2273 {
2274 return "putDown_FenceKit_SoundSet";
2275 }
2276
2278 {
2279 return "Shelter_Site_Build_Loop_SoundSet";
2280 }
2281
2282
2284 {
2286 {
2287 SetSynchDirty();
2288 }
2289 }
2290
2292 {
2294 super.OnVariablesSynchronized();
2295
2297 }
2298
2300 {
2301
2303
2304
2306
2307
2309 }
2310
2311
2313 {
2314
2315 int offset;
2316 int mask;
2317
2318 if ( part_id >= 1 && part_id <= 31 )
2319 {
2320 offset = part_id - 1;
2321 mask = 1 << offset;
2322
2324 }
2325 else if ( part_id >= 32 && part_id <= 62 )
2326 {
2327 offset = ( part_id % 32 );
2328 mask = 1 << offset;
2329
2331 }
2332 else if ( part_id >= 63 && part_id <= 93 )
2333 {
2334 offset = ( part_id % 63 );
2335 mask = 1 << offset;
2336
2338 }
2339 }
2340
2342 {
2343
2344 int offset;
2345 int mask;
2346
2347 if ( part_id >= 1 && part_id <= 31 )
2348 {
2349 offset = part_id - 1;
2350 mask = 1 << offset;
2351
2353 }
2354 else if ( part_id >= 32 && part_id <= 62 )
2355 {
2356 offset = ( part_id % 32 );
2357 mask = 1 << offset;
2358
2360 }
2361 else if ( part_id >= 63 && part_id <= 93 )
2362 {
2363 offset = ( part_id % 63 );
2364 mask = 1 << offset;
2365
2367 }
2368 }
2369
2371 {
2372
2373 int offset;
2374 int mask;
2375
2376 if ( part_id >= 1 && part_id <= 31 )
2377 {
2378 offset = part_id - 1;
2379 mask = 1 << offset;
2380
2382 {
2383 return true;
2384 }
2385 }
2386 else if ( part_id >= 32 && part_id <= 62 )
2387 {
2388 offset = ( part_id % 32 );
2389 mask = 1 << offset;
2390
2392 {
2393 return true;
2394 }
2395 }
2396 else if ( part_id >= 63 && part_id <= 93 )
2397 {
2398 offset = ( part_id % 63 );
2399 mask = 1 << offset;
2400
2402 {
2403 return true;
2404 }
2405 }
2406
2407 return false;
2408 }
2409
2411 {
2414 }
2415
2417 {
2418
2421 }
2422
2424 {
2426 {
2429
2430 switch( build_action_id )
2431 {
2435 }
2436 }
2437 }
2438
2439
2441 {
2443 bool is_base = part.
IsBase();
2446 if ( is_part_built_sync )
2447 {
2449 {
2453
2454 if (is_base)
2455 {
2458 }
2459 }
2460 }
2461 else
2462 {
2464 {
2468
2469 if (is_base)
2470 {
2473 }
2474 }
2475 }
2476
2477
2479 }
2480
2481
2483 {
2486
2487 for ( int i = 0; i < construction_parts.Count(); ++i )
2488 {
2489 string key = construction_parts.GetKey( i );
2492 }
2493
2494
2496 }
2497
2499 {
2502
2503 for ( int i = 0; i < construction_parts.Count(); ++i )
2504 {
2505 string key = construction_parts.GetKey( i );
2507
2508 if ( value.
GetId() ==
id )
2509 {
2510 return value;
2511 }
2512 }
2513
2514 return NULL;
2515 }
2516
2517
2518
2520 {
2522 }
2523
2525 {
2527 }
2528
2530 {
2531 return true;
2532 }
2533
2535 {
2536 return false;
2537 }
2538
2539
2541 {
2544 {
2546 }
2547
2548 return construction_kit;
2549 }
2550
2552 {
2555 {
2557 }
2558 }
2559
2561 {
2563 }
2564
2566 {
2567 return "";
2568 }
2569
2571 {
2573 g_Game.ObjectDelete( construction_kit );
2574 }
2575
2576
2578 {
2580 g_Game.ObjectDelete(
this );
2581 }
2582
2583
2585 {
2586 super.EEDelete(parent);
2587
2589 {
2590 areaDamage.Destroy();
2591 }
2592
2593 }
2594
2596 {
2597 super.OnStoreSave( ctx );
2598
2599
2603
2605 }
2606
2608 {
2609 if ( !super.OnStoreLoad( ctx, version ) )
2610 return false;
2611
2612
2613
2615 {
2617 return false;
2618 }
2620 {
2622 return false;
2623 }
2625 {
2627 return false;
2628 }
2629
2630
2632 {
2634 return false;
2635 }
2636
2637
2638 return true;
2639 }
2640
2642 {
2643 super.AfterStoreLoad();
2644
2646 {
2648 }
2649 }
2650
2652 {
2653
2655
2656
2659
2660
2662 }
2663
2665 {
2666 super.OnCreatePhysics();
2667
2668 ConstructionInit();
2670 }
2671
2673 {
2675 return;
2676
2677 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2678 }
2679
2681 {
2683 {
2685 }
2686
2687 super.EEOnAfterLoad();
2688 }
2689
2691 {
2692 super.EEItemAttached( item, slot_name );
2693
2697 }
2698
2700 {
2701 super.EEItemDetached( item, slot_name );
2702
2705 }
2706
2707 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2708 {
2711
2714 }
2715
2716
2718 {
2719 return true;
2720 }
2721
2722
2723
2725 {
2727
2728
2729 if (construtionPart.
IsBase())
2730 {
2732
2733
2735 }
2736
2737
2739
2740
2742
2743
2745
2747
2749
2750
2752
2753
2755 }
2756
2758 {
2759
2761 }
2762
2763
2765 {
2768
2769
2771
2772
2774
2775
2777
2778
2780
2782
2783
2785
2786
2788
2789
2790 if (construtionPart.
IsBase())
2791 {
2792
2794 }
2795 }
2796
2798 {
2799
2801 }
2802
2803
2804 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2805 {
2808
2809
2811
2812
2814
2815
2817
2818
2820
2822
2823
2825
2826
2828
2829
2830 if (construtionPart.
IsBase())
2831 {
2832
2834 }
2835 }
2836
2838 {
2839
2841 }
2842
2843
2845 {
2847
2850 }
2851
2853 {
2855
2857 {
2859 }
2860 else
2861 {
2863 }
2864
2866 }
2867
2869 {
2871
2873 foreach (
string slotName : attachmentSlots)
2874 {
2876 }
2877
2878
2881 else
2883
2885 }
2886
2888 {
2889 string slotNameMounted = slot_name + "_Mounted";
2890 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2891
2892 if (attachment)
2893 {
2894 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2895 if (barbedWire && barbedWire.IsMounted())
2897 else
2899
2900 if (is_locked)
2901 {
2902 SetAnimationPhase(slotNameMounted, 0);
2903 SetAnimationPhase(slot_name, 1);
2904 }
2905 else
2906 {
2907 SetAnimationPhase(slotNameMounted, 1);
2908 SetAnimationPhase(slot_name, 0);
2909 }
2910 }
2911 else
2912 {
2913 SetAnimationPhase(slotNameMounted, 1);
2914 SetAnimationPhase(slot_name, 1);
2915
2917 }
2918 }
2919
2920
2922 {
2925
2928
2931
2932 foreach (
string slotName : attachmentSlots)
2933 {
2935 }
2936
2937
2939 {
2942
2944 }
2945 else
2946 {
2949
2951 }
2952
2955 }
2956
2958 {
2959
2961 return;
2962
2963 string slot_name_mounted = slot_name + "_Mounted";
2964 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2965
2966
2968 RemoveProxyPhysics( slot_name_mounted );
2969 RemoveProxyPhysics( slot_name );
2970
2971 if ( attachment )
2972 {
2974 if ( is_locked )
2975 {
2977 AddProxyPhysics( slot_name_mounted );
2978 }
2979 else
2980 {
2982 AddProxyPhysics( slot_name );
2983 }
2984 }
2985 }
2986
2988 {
2989 SetAffectPathgraph( true, false );
2991 }
2992
2994 {
2995 return true;
2996 }
2997
2999 {
3000 return true;
3001 }
3002
3004 {
3005 if ( attachment )
3006 {
3008 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
3009
3010 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
3011 }
3012
3013 return false;
3014 }
3015
3017 {
3019 }
3020
3021
3023 {
3024 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
3025 if (
g_Game.ConfigIsExisting( config_path ) )
3026 {
3027 g_Game.ConfigGetTextArray( config_path, attachment_slots );
3028 }
3029 }
3030
3032 {
3033 return true;
3034 }
3035
3037 {
3038 return true;
3039 }
3040
3042 {
3043 return true;
3044 }
3045
3046
3048 {
3051 }
3052
3054 {
3056 }
3057
3059 {
3061 }
3062
3064 {
3065 int attachment_count = GetInventory().AttachmentCount();
3066 if ( attachment_count > 0 )
3067 {
3068 if (
HasBase() && attachment_count == 1 )
3069 {
3070 return false;
3071 }
3072
3073 return true;
3074 }
3075
3076 return false;
3077 }
3078
3080 {
3081 return true;
3082 }
3083
3085 {
3086 return false;
3087 }
3088
3089
3091 {
3092 return false;
3093 }
3094
3096 {
3097 return false;
3098 }
3099
3100
3102 {
3103 return false;
3104 }
3105
3106
3107
3109 {
3110 return true;
3111 }
3112
3114 {
3115 return true;
3116 }
3117
3120 {
3121 return false;
3122 }
3123
3124
3126 {
3127 return false;
3128 }
3129
3130
3132 {
3133 return true;
3134 }
3135
3136
3138 {
3139 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3140 {
3141 return false;
3142 }
3143
3144 return true;
3145 }
3146
3148 {
3151
3152 return item;
3153 }
3154
3155
3157 {
3159 {
3160
3162
3163
3166
3168 if ( MemoryPointExists( slot_name + "_min" ) )
3169 {
3170 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3171 }
3172 if ( MemoryPointExists( slot_name + "_max" ) )
3173 {
3174 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3175 }
3176
3177
3180
3181
3184 center = ModelToWorld( center );
3185
3186
3189
3190 areaDamage.SetExtents( extents[0], extents[1] );
3191 areaDamage.SetAreaPosition( center );
3195 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3196 areaDamage.SetAmmoName( "BarbedWireHit" );
3197 areaDamage.Spawn();
3198
3200 }
3201 }
3202
3204 {
3205 if ( angle_deg != 0 )
3206 {
3207
3209
3210
3212 if ( MemoryPointExists( "rotate_axis" ) )
3213 {
3214 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3215 }
3216 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];
3217 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];
3218 center[0] = r_center_x;
3219 center[2] = r_center_z;
3220 }
3221 }
3222
3224 {
3226 {
3229 {
3230 if (areaDamage)
3231 {
3232 areaDamage.Destroy();
3233 }
3234
3236 }
3237 }
3238 }
3239
3241 {
3242 return true;
3243 }
3244
3245
3246
3247
3249 {
3251 }
3252
3254 {
3256 }
3257
3259 {
3261 }
3262
3264 {
3266
3267 switch ( material_type )
3268 {
3274 }
3275
3276 return "";
3277 }
3278
3280 {
3282
3283 switch ( material_type )
3284 {
3290 }
3291
3292 return "";
3293 }
3294
3295
3297 {
3299 {
3300
3302 {
3303 SetHealth(slot_name,"Health",item.GetHealth());
3304 }
3305 }
3306 }
3307
3309 {
3310 return 111;
3311 }
3312
3314 {
3315 super.SetActions();
3316
3320 }
3321
3323 {
3325 if (!construction)
3326 return;
3327
3329 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3330 {
3333 {
3335 }
3336 }
3337 }
3338
3340 {
3342 if (!construction)
3343 return;
3344
3346 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3347 {
3350 {
3351 construction.HandleEntityFalling(part.
GetPartName());
3352 }
3353 }
3354 }
3355
3358 {
3360 return;
3361
3364
3365 if (DestroyOnFall())
3366 {
3368 {
3370 }
3371 else
3372 {
3374 {
3376 }
3378 }
3379 }
3380 }
3381
3383 {
3384 if (HasAnyAttachmentsOrCargo())
3385 {
3388 }
3389 }
3390
3391
3392
3393
3394
3397 {
3398 return null;
3399 }
3400
3402 {
3404 }
3405
3407 {
3410
3411 Man p;
3412
3413 #ifdef SERVER
3415 g_Game.GetWorld().GetPlayerList(players);
3416 if (players.Count())
3417 p = players[0];
3418 #else
3420 #endif
3421
3423 {
3424 bool excluded = false;
3426 if (excludes)
3427 {
3428 foreach (string exclude : excludes)
3429 {
3431 {
3432 excluded = true;
3433 break;
3434 }
3435 }
3436 }
3437
3438 if (!excluded)
3439 {
3441 }
3442 }
3443
3445 }
3446
3448
3450 [
Obsolete(
"handled in the Construction component directly")]
3452 {
3453 }
3454
3455 [
Obsolete(
"handled in the Construction component directly")]
3457 {
3458 }
3459
3460 [
Obsolete(
"obsolete debug method")]
3462 {
3463 }
3464}
3465
3467{
3468#ifdef BSB_DEBUG
3470#else
3471
3472#endif
3473}
3475{
3476#ifdef BSB_DEBUG_SPAM
3478#else
3479
3480#endif
3481}
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.