2118{
2120
2122
2124
2131
2132
2133
2139
2145
2147
2151
2152
2154 {
2156
2157
2158 RegisterNetSyncVariableInt( "m_SyncParts01" );
2159 RegisterNetSyncVariableInt( "m_SyncParts02" );
2160 RegisterNetSyncVariableInt( "m_SyncParts03" );
2161 RegisterNetSyncVariableInt( "m_InteractedPartId" );
2162 RegisterNetSyncVariableInt( "m_PerformedActionId" );
2163 RegisterNetSyncVariableBool( "m_HasBase" );
2164
2165
2166 ConstructionInit();
2167
2168 if (ConfigIsExisting("hybridAttachments"))
2169 {
2172 }
2173 if (ConfigIsExisting("mountables"))
2174 {
2177 }
2178
2180 SetAllowDamage(true);
2181 }
2182
2184 {
2185 return "disableBaseDamage";
2186 }
2187
2189 {
2190 return true;
2191 }
2192
2194 {
2195 return EInventoryIconVisibility.HIDE_VICINITY;
2196 }
2197
2199 {
2200 super.InitItemSounds();
2201
2205
2210 }
2211
2213 {
2214 return "putDown_FenceKit_SoundSet";
2215 }
2216
2218 {
2219 return "Shelter_Site_Build_Loop_SoundSet";
2220 }
2221
2222
2224 {
2226 {
2227 SetSynchDirty();
2228 }
2229 }
2230
2232 {
2234 super.OnVariablesSynchronized();
2235
2237 }
2238
2240 {
2241
2243
2244
2246
2247
2249 }
2250
2251
2253 {
2254
2255 int offset;
2256 int mask;
2257
2258 if ( part_id >= 1 && part_id <= 31 )
2259 {
2260 offset = part_id - 1;
2261 mask = 1 << offset;
2262
2264 }
2265 else if ( part_id >= 32 && part_id <= 62 )
2266 {
2267 offset = ( part_id % 32 );
2268 mask = 1 << offset;
2269
2271 }
2272 else if ( part_id >= 63 && part_id <= 93 )
2273 {
2274 offset = ( part_id % 63 );
2275 mask = 1 << offset;
2276
2278 }
2279 }
2280
2282 {
2283
2284 int offset;
2285 int mask;
2286
2287 if ( part_id >= 1 && part_id <= 31 )
2288 {
2289 offset = part_id - 1;
2290 mask = 1 << offset;
2291
2293 }
2294 else if ( part_id >= 32 && part_id <= 62 )
2295 {
2296 offset = ( part_id % 32 );
2297 mask = 1 << offset;
2298
2300 }
2301 else if ( part_id >= 63 && part_id <= 93 )
2302 {
2303 offset = ( part_id % 63 );
2304 mask = 1 << offset;
2305
2307 }
2308 }
2309
2311 {
2312
2313 int offset;
2314 int mask;
2315
2316 if ( part_id >= 1 && part_id <= 31 )
2317 {
2318 offset = part_id - 1;
2319 mask = 1 << offset;
2320
2322 {
2323 return true;
2324 }
2325 }
2326 else if ( part_id >= 32 && part_id <= 62 )
2327 {
2328 offset = ( part_id % 32 );
2329 mask = 1 << offset;
2330
2332 {
2333 return true;
2334 }
2335 }
2336 else if ( part_id >= 63 && part_id <= 93 )
2337 {
2338 offset = ( part_id % 63 );
2339 mask = 1 << offset;
2340
2342 {
2343 return true;
2344 }
2345 }
2346
2347 return false;
2348 }
2349
2351 {
2354 }
2355
2357 {
2358
2361 }
2362
2364 {
2366 {
2369
2370 switch( build_action_id )
2371 {
2375 }
2376 }
2377 }
2378
2379
2381 {
2383 bool is_base = part.
IsBase();
2386 if ( is_part_built_sync )
2387 {
2389 {
2393
2394 if (is_base)
2395 {
2398 }
2399 }
2400 }
2401 else
2402 {
2404 {
2408
2409 if (is_base)
2410 {
2413 }
2414 }
2415 }
2416
2417
2419 }
2420
2421
2423 {
2426
2427 for ( int i = 0; i < construction_parts.Count(); ++i )
2428 {
2429 string key = construction_parts.GetKey( i );
2432 }
2433
2434
2436 }
2437
2439 {
2442
2443 for ( int i = 0; i < construction_parts.Count(); ++i )
2444 {
2445 string key = construction_parts.GetKey( i );
2447
2448 if ( value.
GetId() ==
id )
2449 {
2450 return value;
2451 }
2452 }
2453
2454 return NULL;
2455 }
2456
2457
2458
2460 {
2462 }
2463
2465 {
2467 }
2468
2470 {
2471 return true;
2472 }
2473
2475 {
2476 return false;
2477 }
2478
2479
2481 {
2484 {
2486 }
2487
2488 return construction_kit;
2489 }
2490
2492 {
2495 {
2497 }
2498 }
2499
2501 {
2503 }
2504
2506 {
2507 return "";
2508 }
2509
2511 {
2513 g_Game.ObjectDelete( construction_kit );
2514 }
2515
2516
2518 {
2520 g_Game.ObjectDelete(
this );
2521 }
2522
2523
2525 {
2526 super.EEDelete(parent);
2527
2529 {
2530 areaDamage.Destroy();
2531 }
2532
2533 }
2534
2536 {
2537 super.OnStoreSave( ctx );
2538
2539
2543
2545 }
2546
2548 {
2549 if ( !super.OnStoreLoad( ctx, version ) )
2550 return false;
2551
2552
2553
2555 {
2557 return false;
2558 }
2560 {
2562 return false;
2563 }
2565 {
2567 return false;
2568 }
2569
2570
2572 {
2574 return false;
2575 }
2576
2577
2578 return true;
2579 }
2580
2582 {
2583 super.AfterStoreLoad();
2584
2586 {
2588 }
2589 }
2590
2592 {
2593
2595
2596
2599
2600
2602 }
2603
2605 {
2606 super.OnCreatePhysics();
2607
2608 ConstructionInit();
2610 }
2611
2613 {
2615 return;
2616
2617 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2618 }
2619
2621 {
2623 {
2625 }
2626
2627 super.EEOnAfterLoad();
2628 }
2629
2631 {
2632 super.EEItemAttached( item, slot_name );
2633
2637 }
2638
2640 {
2641 super.EEItemDetached( item, slot_name );
2642
2645 }
2646
2647 protected void OnSetSlotLock(
int slotId,
bool locked,
bool was_locked )
2648 {
2651
2654 }
2655
2656
2658 {
2659 return true;
2660 }
2661
2662
2663
2665 {
2667
2668
2669 if (construtionPart.
IsBase())
2670 {
2672
2673
2675 }
2676
2677
2679
2680
2682
2683
2685
2687
2689
2690
2692
2693
2695 }
2696
2698 {
2699
2701 }
2702
2703
2705 {
2708
2709
2711
2712
2714
2715
2717
2718
2720
2722
2723
2725
2726
2728
2729
2730 if (construtionPart.
IsBase())
2731 {
2732
2734 }
2735 }
2736
2738 {
2739
2741 }
2742
2743
2744 void OnPartDestroyedServer(Man player,
string part_name,
int action_id,
bool destroyed_by_connected_part =
false)
2745 {
2748
2749
2751
2752
2754
2755
2757
2758
2760
2762
2763
2765
2766
2768
2769
2770 if (construtionPart.
IsBase())
2771 {
2772
2774 }
2775 }
2776
2778 {
2779
2781 }
2782
2783
2785 {
2787
2790 }
2791
2793 {
2795
2797 {
2799 }
2800 else
2801 {
2803 }
2804
2806 }
2807
2809 {
2811
2813 foreach (
string slotName : attachmentSlots)
2814 {
2816 }
2817
2818
2821 else
2823
2825 }
2826
2828 {
2829 string slotNameMounted = slot_name + "_Mounted";
2830 EntityAI attachment = FindAttachmentBySlotName(slot_name);
2831
2832 if (attachment)
2833 {
2834 BarbedWire barbedWire = BarbedWire.Cast(attachment);
2835 if (barbedWire && barbedWire.IsMounted())
2837 else
2839
2840 if (is_locked)
2841 {
2842 SetAnimationPhase(slotNameMounted, 0);
2843 SetAnimationPhase(slot_name, 1);
2844 }
2845 else
2846 {
2847 SetAnimationPhase(slotNameMounted, 1);
2848 SetAnimationPhase(slot_name, 0);
2849 }
2850 }
2851 else
2852 {
2853 SetAnimationPhase(slotNameMounted, 1);
2854 SetAnimationPhase(slot_name, 1);
2855
2857 }
2858 }
2859
2860
2862 {
2865
2868
2871
2872 foreach (
string slotName : attachmentSlots)
2873 {
2875 }
2876
2877
2879 {
2882
2884 }
2885 else
2886 {
2889
2891 }
2892
2895 }
2896
2898 {
2899
2901 return;
2902
2903 string slot_name_mounted = slot_name + "_Mounted";
2904 EntityAI attachment = FindAttachmentBySlotName( slot_name );
2905
2906
2908 RemoveProxyPhysics( slot_name_mounted );
2909 RemoveProxyPhysics( slot_name );
2910
2911 if ( attachment )
2912 {
2914 if ( is_locked )
2915 {
2917 AddProxyPhysics( slot_name_mounted );
2918 }
2919 else
2920 {
2922 AddProxyPhysics( slot_name );
2923 }
2924 }
2925 }
2926
2928 {
2929 SetAffectPathgraph( true, false );
2931 }
2932
2934 {
2935 return true;
2936 }
2937
2939 {
2940 return true;
2941 }
2942
2944 {
2945 if ( attachment )
2946 {
2948 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
2949
2950 return GetInventory().GetSlotLock( inventory_location.
GetSlot() );
2951 }
2952
2953 return false;
2954 }
2955
2957 {
2959 }
2960
2961
2963 {
2964 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
2965 if (
g_Game.ConfigIsExisting( config_path ) )
2966 {
2967 g_Game.ConfigGetTextArray( config_path, attachment_slots );
2968 }
2969 }
2970
2972 {
2973 return true;
2974 }
2975
2977 {
2978 return true;
2979 }
2980
2982 {
2983 return true;
2984 }
2985
2986
2988 {
2991 }
2992
2994 {
2996 }
2997
2999 {
3001 }
3002
3004 {
3005 int attachment_count = GetInventory().AttachmentCount();
3006 if ( attachment_count > 0 )
3007 {
3008 if (
HasBase() && attachment_count == 1 )
3009 {
3010 return false;
3011 }
3012
3013 return true;
3014 }
3015
3016 return false;
3017 }
3018
3020 {
3021 return true;
3022 }
3023
3025 {
3026 return false;
3027 }
3028
3029
3031 {
3032 return false;
3033 }
3034
3036 {
3037 return false;
3038 }
3039
3040
3042 {
3043 return false;
3044 }
3045
3046
3047
3049 {
3050 return true;
3051 }
3052
3054 {
3055 return true;
3056 }
3057
3060 {
3061 return false;
3062 }
3063
3064
3066 {
3067 return false;
3068 }
3069
3070
3072 {
3073 return true;
3074 }
3075
3076
3078 {
3079 if (
HasBase() || GetInventory().AttachmentCount() > 0 )
3080 {
3081 return false;
3082 }
3083
3084 return true;
3085 }
3086
3088 {
3091
3092 return item;
3093 }
3094
3095
3097 {
3099 {
3100
3102
3103
3106
3108 if ( MemoryPointExists( slot_name + "_min" ) )
3109 {
3110 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
3111 }
3112 if ( MemoryPointExists( slot_name + "_max" ) )
3113 {
3114 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
3115 }
3116
3117
3120
3121
3124 center = ModelToWorld( center );
3125
3126
3129
3130 areaDamage.SetExtents( extents[0], extents[1] );
3131 areaDamage.SetAreaPosition( center );
3135 areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
3136 areaDamage.SetAmmoName( "BarbedWireHit" );
3137 areaDamage.Spawn();
3138
3140 }
3141 }
3142
3144 {
3145 if ( angle_deg != 0 )
3146 {
3147
3149
3150
3152 if ( MemoryPointExists( "rotate_axis" ) )
3153 {
3154 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
3155 }
3156 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];
3157 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];
3158 center[0] = r_center_x;
3159 center[2] = r_center_z;
3160 }
3161 }
3162
3164 {
3166 {
3169 {
3170 if (areaDamage)
3171 {
3172 areaDamage.Destroy();
3173 }
3174
3176 }
3177 }
3178 }
3179
3181 {
3182 return true;
3183 }
3184
3185
3186
3187
3189 {
3191 }
3192
3194 {
3196 }
3197
3199 {
3201 }
3202
3204 {
3206
3207 switch ( material_type )
3208 {
3214 }
3215
3216 return "";
3217 }
3218
3220 {
3222
3223 switch ( material_type )
3224 {
3230 }
3231
3232 return "";
3233 }
3234
3235
3237 {
3239 {
3240
3242 {
3243 SetHealth(slot_name,"Health",item.GetHealth());
3244 }
3245 }
3246 }
3247
3249 {
3250 return 111;
3251 }
3252
3254 {
3255 super.SetActions();
3256
3260 }
3261
3263 {
3265 if (!construction)
3266 return;
3267
3269 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3270 {
3273 {
3275 }
3276 }
3277 }
3278
3280 {
3282 if (!construction)
3283 return;
3284
3286 for ( int i = constructionParts.Count() - 1; i >= 0; --i )
3287 {
3290 {
3291 construction.HandleEntityFalling(part.
GetPartName());
3292 }
3293 }
3294 }
3295
3298 {
3300 return;
3301
3304
3305 if (DestroyOnFall())
3306 {
3308 {
3310 }
3311 else
3312 {
3314 {
3316 }
3318 }
3319 }
3320 }
3321
3323 {
3324 if (HasAnyAttachmentsOrCargo())
3325 {
3328 }
3329 }
3330
3331
3332
3333
3334
3337 {
3338 return null;
3339 }
3340
3342 {
3344 }
3345
3347 {
3350
3351 Man p;
3352
3353 #ifdef SERVER
3355 g_Game.GetWorld().GetPlayerList(players);
3356 if (players.Count())
3357 p = players[0];
3358 #else
3360 #endif
3361
3363 {
3364 bool excluded = false;
3366 if (excludes)
3367 {
3368 foreach (string exclude : excludes)
3369 {
3371 {
3372 excluded = true;
3373 break;
3374 }
3375 }
3376 }
3377
3378 if (!excluded)
3379 {
3381 }
3382 }
3383
3385 }
3386
3388
3390 [
Obsolete(
"handled in the Construction component directly")]
3392 {
3393 }
3394
3395 [
Obsolete(
"handled in the Construction component directly")]
3397 {
3398 }
3399
3400 [
Obsolete(
"obsolete debug method")]
3402 {
3403 }
3404}
3405
3407{
3408#ifdef BSB_DEBUG
3410#else
3411
3412#endif
3413}
3415{
3416#ifdef BSB_DEBUG_SPAM
3418#else
3419
3420#endif
3421}
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.