DayZ Scripts
v1.21.156300 ยท Jun 20, 2023
 
Loading...
Searching...
No Matches
BaseBuildingBase.c
Go to the documentation of this file.
1//BASE BUILDING BASE
3{
4 const string ANIMATION_DEPLOYED = "Deployed";
5
6 float m_ConstructionKitHealth; //stored health value for used construction kit
7
9
10 bool m_HasBase = false;
11 //variables for synchronization of base building parts (2x31 is the current limit)
12 int m_SyncParts01; //synchronization for already built parts (31 parts)
13 int m_SyncParts02; //synchronization for already built parts (+31 parts)
14 int m_SyncParts03; //synchronization for already built parts (+31 parts)
15 int m_InteractedPartId; //construction part id that an action was performed on
16 int m_PerformedActionId; //action id that was performed on a construction part
17
18 //Sounds
19 //build
20 const string SOUND_BUILD_WOOD_LOG = "putDown_WoodLog_SoundSet";
21 const string SOUND_BUILD_WOOD_PLANK = "putDown_WoodPlank_SoundSet";
22 const string SOUND_BUILD_WOOD_STAIRS = "putDown_WoodStairs_SoundSet";
23 const string SOUND_BUILD_METAL = "putDown_MetalPlank_SoundSet";
24 const string SOUND_BUILD_WIRE = "putDown_BarbedWire_SoundSet";
25 //dismantle
26 const string SOUND_DISMANTLE_WOOD_LOG = "Crash_WoodPlank_SoundSet";
27 const string SOUND_DISMANTLE_WOOD_PLANK = "Crash_WoodPlank_SoundSet";
28 const string SOUND_DISMANTLE_WOOD_STAIRS = "Crash_WoodPlank_SoundSet";
29 const string SOUND_DISMANTLE_METAL = "Crash_MetalPlank_SoundSet";
30 const string SOUND_DISMANTLE_WIRE = "putDown_BarbedWire_SoundSet";
31
33
37
38 // Constructor
40 {
42
43 //synchronized variables
44 RegisterNetSyncVariableInt( "m_SyncParts01" );
45 RegisterNetSyncVariableInt( "m_SyncParts02" );
46 RegisterNetSyncVariableInt( "m_SyncParts03" );
47 RegisterNetSyncVariableInt( "m_InteractedPartId" );
48 RegisterNetSyncVariableInt( "m_PerformedActionId" );
49 RegisterNetSyncVariableBool( "m_HasBase" );
50
51 //Construction init
53
54 if (ConfigIsExisting("hybridAttachments"))
55 {
57 ConfigGetTextArray("hybridAttachments",m_HybridAttachments);
58 }
59 if (ConfigIsExisting("mountables"))
60 {
62 ConfigGetTextArray("mountables",m_Mountables);
63 }
64
65 ProcessInvulnerabilityCheck(GetInvulnerabilityTypeString());
66 }
67
69 {
70 return "disableBaseDamage";
71 }
72
73 override bool CanObstruct()
74 {
75 return true;
76 }
77
78 override int GetHideIconMask()
79 {
80 return EInventoryIconVisibility.HIDE_VICINITY;
81 }
82
83 // --- SYNCHRONIZATION
85 {
86 if ( GetGame().IsServer() )
87 {
88 SetSynchDirty();
89 }
90 }
91
93 {
94 bsbDebugPrint("[bsb] " + GetDebugName(this) + " OnVariablesSynchronized");
95 super.OnVariablesSynchronized();
96
98 }
99
100 protected void OnSynchronizedClient()
101 {
102 //update parts
104
105 //update action on part
107
108 //update visuals (client)
110 }
111
112 //parts synchronization
113 void RegisterPartForSync( int part_id )
114 {
115 //part_id must starts from index = 1
116 int offset;
117 int mask;
118
119 if ( part_id >= 1 && part_id <= 31 ) //<1,31> (31 parts)
120 {
121 offset = part_id - 1;
122 mask = 1 << offset;
123
125 }
126 else if ( part_id >= 32 && part_id <= 62 ) //<32,62> (31 parts)
127 {
128 offset = ( part_id % 32 );
129 mask = 1 << offset;
130
132 }
133 else if ( part_id >= 63 && part_id <= 93 ) //<63,93> (31 parts)
134 {
135 offset = ( part_id % 63 );
136 mask = 1 << offset;
137
139 }
140 }
141
142 void UnregisterPartForSync( int part_id )
143 {
144 //part_id must starts from index = 1
145 int offset;
146 int mask;
147
148 if ( part_id >= 1 && part_id <= 31 ) //<1,31> (31 parts)
149 {
150 offset = part_id - 1;
151 mask = 1 << offset;
152
153 m_SyncParts01 = m_SyncParts01 & ~mask;
154 }
155 else if ( part_id >= 32 && part_id <= 62 ) //<32,62> (31 parts)
156 {
157 offset = ( part_id % 32 );
158 mask = 1 << offset;
159
160 m_SyncParts02 = m_SyncParts02 & ~mask;
161 }
162 else if ( part_id >= 63 && part_id <= 93 ) //<63,93> (31 parts)
163 {
164 offset = ( part_id % 63 );
165 mask = 1 << offset;
166
167 m_SyncParts03 = m_SyncParts03 & ~mask;
168 }
169 }
170
171 bool IsPartBuildInSyncData( int part_id )
172 {
173 //part_id must starts from index = 1
174 int offset;
175 int mask;
176
177 if ( part_id >= 1 && part_id <= 31 ) //<1,31> (31 parts)
178 {
179 offset = part_id - 1;
180 mask = 1 << offset;
181
182 if ( ( m_SyncParts01 & mask ) > 0 )
183 {
184 return true;
185 }
186 }
187 else if ( part_id >= 32 && part_id <= 62 ) //<32,62> (31 parts)
188 {
189 offset = ( part_id % 32 );
190 mask = 1 << offset;
191
192 if ( ( m_SyncParts02 & mask ) > 0 )
193 {
194 return true;
195 }
196 }
197 else if ( part_id >= 63 && part_id <= 93 ) //<63,93> (31 parts)
198 {
199 offset = ( part_id % 63 );
200 mask = 1 << offset;
201
202 if ( ( m_SyncParts03 & mask ) > 0 )
203 {
204 return true;
205 }
206 }
207
208 return false;
209 }
210
211 protected void RegisterActionForSync( int part_id, int action_id )
212 {
213 m_InteractedPartId = part_id;
214 m_PerformedActionId = action_id;
215 }
216
217 protected void ResetActionSyncData()
218 {
219 //reset data
222 }
223
224 protected void SetActionFromSyncData()
225 {
226 if ( m_InteractedPartId > -1 && m_PerformedActionId > -1 )
227 {
229 int build_action_id = m_PerformedActionId;
230
231 switch( build_action_id )
232 {
233 case AT_BUILD_PART : OnPartBuiltClient( constrution_part.GetPartName(), build_action_id ); break;
234 case AT_DISMANTLE_PART : OnPartDismantledClient( constrution_part.GetPartName(), build_action_id ); break;
235 case AT_DESTROY_PART : OnPartDestroyedClient( constrution_part.GetPartName(), build_action_id ); break;
236 }
237 }
238 }
239 //------
240
242 {
243 string key = part.m_PartName;
244 bool is_base = part.IsBase();
245 bool is_part_built_sync = IsPartBuildInSyncData( part.GetId() );
246 bsbDebugSpam("[bsb] " + GetDebugName(this) + " SetPartFromSyncData try to sync: built=" + is_part_built_sync + " key=" + key + " part=" + part.GetPartName() + " part_built=" + part.IsBuilt());
247 if ( is_part_built_sync )
248 {
249 if ( !part.IsBuilt() )
250 {
251 bsbDebugPrint("[bsb] " + GetDebugName(this) + " SetPartsFromSyncData +++ " + key);
252 GetConstruction().AddToConstructedParts( key );
253 GetConstruction().ShowConstructionPartPhysics(part.GetPartName());
254
255 if (is_base)
256 {
257 bsbDebugPrint("[bsb] " + GetDebugName(this) + ANIMATION_DEPLOYED + " RM");
258 RemoveProxyPhysics( ANIMATION_DEPLOYED );
259 }
260 }
261 }
262 else
263 {
264 if ( part.IsBuilt() )
265 {
266 bsbDebugPrint("[bsb] " + GetDebugName(this) + " SetPartsFromSyncData --- " + key);
267 GetConstruction().RemoveFromConstructedParts( key );
268 GetConstruction().HideConstructionPartPhysics(part.GetPartName());
269
270 if (is_base)
271 {
272 bsbDebugPrint("[bsb] " + GetDebugName(this) + ANIMATION_DEPLOYED + " ADD");
273 AddProxyPhysics( ANIMATION_DEPLOYED );
274 }
275 }
276 }
277
278 //check slot lock for material attachments
279 GetConstruction().SetLockOnAttachedMaterials( part.GetPartName(), part.IsBuilt() ); //failsafe for corrupted sync/storage data
280 }
281
282 //set construction parts based on synchronized data
284 {
285 Construction construction = GetConstruction();
286 map<string, ref ConstructionPart> construction_parts = construction.GetConstructionParts();
287
288 for ( int i = 0; i < construction_parts.Count(); ++i )
289 {
290 string key = construction_parts.GetKey( i );
291 ConstructionPart value = construction_parts.Get( key );
292 SetPartFromSyncData(value);
293 }
294
295 //regenerate navmesh
296 UpdateNavmesh();
297 }
298
300 {
301 Construction construction = GetConstruction();
302 map<string, ref ConstructionPart> construction_parts = construction.GetConstructionParts();
303
304 for ( int i = 0; i < construction_parts.Count(); ++i )
305 {
306 string key = construction_parts.GetKey( i );
307 ConstructionPart value = construction_parts.Get( key );
308
309 if ( value.GetId() == id )
310 {
311 return value;
312 }
313 }
314
315 return NULL;
316 }
317 //
318
319 //Base
320 bool HasBase()
321 {
322 return m_HasBase;
323 }
324
325 void SetBaseState( bool has_base )
326 {
327 m_HasBase = has_base;
328 }
329
330 override bool IsDeployable()
331 {
332 return true;
333 }
334
335 bool IsOpened()
336 {
337 return false;
338 }
339
340 //--- CONSTRUCTION KIT
342 {
343 ItemBase construction_kit = ItemBase.Cast( GetGame().CreateObjectEx( GetConstructionKitType(), GetKitSpawnPosition(), ECE_PLACE_ON_SURFACE ) );
344 if ( m_ConstructionKitHealth > 0 )
345 {
346 construction_kit.SetHealth( m_ConstructionKitHealth );
347 }
348
349 return construction_kit;
350 }
351
353 {
354 ItemBase construction_kit = ItemBase.Cast(player.GetHumanInventory().CreateInHands(GetConstructionKitType()));
355 if ( m_ConstructionKitHealth > 0 )
356 {
357 construction_kit.SetHealth( m_ConstructionKitHealth );
358 }
359 }
360
362 {
363 return GetPosition();
364 }
365
366 protected string GetConstructionKitType()
367 {
368 return "";
369 }
370
371 void DestroyConstructionKit( ItemBase construction_kit )
372 {
373 m_ConstructionKitHealth = construction_kit.GetHealth();
374 GetGame().ObjectDelete( construction_kit );
375 }
376
377 //--- CONSTRUCTION
379 {
380 bsbDebugPrint("[bsb] " + GetDebugName(this) + " DestroyConstruction");
381 GetGame().ObjectDelete( this );
382 }
383
384 // --- EVENTS
385 override void OnStoreSave( ParamsWriteContext ctx )
386 {
387 super.OnStoreSave( ctx );
388
389 //sync parts 01
390 ctx.Write( m_SyncParts01 );
391 ctx.Write( m_SyncParts02 );
392 ctx.Write( m_SyncParts03 );
393
394 ctx.Write( m_HasBase );
395 }
396
397 override bool OnStoreLoad( ParamsReadContext ctx, int version )
398 {
399 if ( !super.OnStoreLoad( ctx, version ) )
400 return false;
401
402 //--- Base building data ---
403 //Restore synced parts data
404 if ( !ctx.Read( m_SyncParts01 ) )
405 {
406 m_SyncParts01 = 0; //set default
407 return false;
408 }
409 if ( !ctx.Read( m_SyncParts02 ) )
410 {
411 m_SyncParts02 = 0; //set default
412 return false;
413 }
414 if ( !ctx.Read( m_SyncParts03 ) )
415 {
416 m_SyncParts03 = 0; //set default
417 return false;
418 }
419
420 //has base
421 if ( !ctx.Read( m_HasBase ) )
422 {
423 m_HasBase = false;
424 return false;
425 }
426 //---
427
428 return true;
429 }
430
431 override void AfterStoreLoad()
432 {
433 super.AfterStoreLoad();
434
436 {
438 }
439 }
440
442 {
443 //update server data
445
446 //set base state
447 ConstructionPart construction_part = GetConstruction().GetBaseConstructionPart();
448 SetBaseState( construction_part.IsBuilt() ) ;
449
450 //synchronize after load
452 }
453
454 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
455 {
457 return;
458
459 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
460
461 if (GetGame().IsMultiplayer() && !GetGame().IsServer())
462 return;
463
464 Construction construction = GetConstruction();
465 string part_name = zone;
466 part_name.ToLower();
467
468 if ( newLevel == GameConstants.STATE_RUINED )
469 {
470 ConstructionPart construction_part = construction.GetConstructionPart( part_name );
471
472 if ( construction_part && construction.IsPartConstructed( part_name ) )
473 {
474 construction.DestroyPartServer( null, part_name, AT_DESTROY_PART );
475 construction.DestroyConnectedParts(part_name);
476 }
477
478 //barbed wire handling (hack-ish)
479 if ( part_name.Contains("barbed") )
480 {
481 BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
482 if (barbed_wire)
483 barbed_wire.SetMountedState( false );
484 }
485 }
486 }
487
488 override void EEOnAfterLoad()
489 {
491 {
493 }
494
495 super.EEOnAfterLoad();
496 }
497
498 override void EEInit()
499 {
500 super.EEInit();
501
502 // init visuals and physics
504
505 //debug
506 #ifdef DEVELOPER
508 #endif
509 }
510
511 override void EEItemAttached( EntityAI item, string slot_name )
512 {
513 super.EEItemAttached( item, slot_name );
514
515 CheckForHybridAttachments( item, slot_name );
517 UpdateAttachmentPhysics( slot_name, false );
518 }
519
520 override void EEItemDetached( EntityAI item, string slot_name )
521 {
522 super.EEItemDetached( item, slot_name );
523
525 UpdateAttachmentPhysics( slot_name, false );
526 }
527
528 protected void OnSetSlotLock( int slotId, bool locked, bool was_locked )
529 {
530 string slot_name = InventorySlots.GetSlotName( slotId );
531 bsbDebugPrint( "inv: OnSetSlotLock " + GetDebugName( this ) + " slot=" + slot_name + " locked=" + locked + " was_locked=" + was_locked );
532
533 UpdateAttachmentVisuals( slot_name, locked );
534 UpdateAttachmentPhysics( slot_name, locked );
535 }
536
537 //ignore out of reach condition
539 {
540 return true;
541 }
542
543 //CONSTRUCTION EVENTS
544 //Build
545 void OnPartBuiltServer(notnull Man player, string part_name, int action_id)
546 {
547 ConstructionPart construtionPart = GetConstruction().GetConstructionPart(part_name);
548
549 //check base state
550 if (construtionPart.IsBase())
551 {
552 SetBaseState(true);
553
554 //spawn kit
556 }
557
558 //register constructed parts for synchronization
559 RegisterPartForSync(construtionPart.GetId());
560
561 //register action that was performed on part
562 RegisterActionForSync(construtionPart.GetId(), action_id);
563
564 //synchronize
566
567 SetPartFromSyncData(construtionPart); // server part of sync, client will be synced from SetPartsFromSyncData
568
570
571 //update visuals
573
574 //reset action sync data
576 }
577
578 void OnPartBuiltClient(string part_name, int action_id)
579 {
580 //play sound
581 SoundBuildStart( part_name );
582 }
583
584 //Dismantle
585 void OnPartDismantledServer(notnull Man player, string part_name, int action_id)
586 {
587 bsbDebugPrint("[bsb] " + GetDebugName(this) + " OnPartDismantledServer " + part_name);
588 ConstructionPart construtionPart = GetConstruction().GetConstructionPart(part_name);
589
590 //register constructed parts for synchronization
591 UnregisterPartForSync(construtionPart.GetId());
592
593 //register action that was performed on part
594 RegisterActionForSync(construtionPart.GetId(), action_id);
595
596 //synchronize
598
599 // server part of sync, client will be synced from SetPartsFromSyncData
600 SetPartFromSyncData(construtionPart);
601
603
604 //update visuals
606
607 //reset action sync data
609
610 //check base state
611 if (construtionPart.IsBase())
612 {
613 //Destroy construction
615 }
616 }
617
618 void OnPartDismantledClient( string part_name, int action_id )
619 {
620 //play sound
621 SoundDismantleStart( part_name );
622 }
623
624 //Destroy
625 void OnPartDestroyedServer(Man player, string part_name, int action_id, bool destroyed_by_connected_part = false)
626 {
627 bsbDebugPrint("[bsb] " + GetDebugName(this) + " OnPartDestroyedServer " + part_name);
628 ConstructionPart construtionPart = GetConstruction().GetConstructionPart(part_name);
629
630 //register constructed parts for synchronization
631 UnregisterPartForSync(construtionPart.GetId());
632
633 //register action that was performed on part
634 RegisterActionForSync(construtionPart.GetId(), action_id);
635
636 //synchronize
638
639 // server part of sync, client will be synced from SetPartsFromSyncData
640 SetPartFromSyncData(construtionPart);
641
643
644 //update visuals
646
647 //reset action sync data
649
650 //check base state
651 if (construtionPart.IsBase())
652 {
653 //Destroy construction
655 }
656 }
657
658 void OnPartDestroyedClient( string part_name, int action_id )
659 {
660 //play sound
661 SoundDestroyStart( part_name );
662 }
663
664 // --- UPDATE
666 {
667 bsbDebugPrint("[bsb] " + GetDebugName(this) + " BaseBuildingBase::InitBaseState ");
668
669 InitVisuals();
670 UpdateNavmesh(); //regenerate navmesh
671 GetConstruction().InitBaseState();
672 }
673
675 {
676 bsbDebugPrint("[bsb] " + GetDebugName(this) + " InitVisuals");
677 //check base
678 if ( !HasBase() )
679 {
680 SetAnimationPhase( ANIMATION_DEPLOYED, 0 );
681 }
682 else
683 {
684 SetAnimationPhase( ANIMATION_DEPLOYED, 1 );
685 }
686
687 GetConstruction().UpdateVisuals();
688 }
689
691 {
692 //update attachments visuals
693 ref array<string> attachment_slots = new ref array<string>;
694 GetAttachmentSlots( this, attachment_slots );
695 for ( int i = 0; i < attachment_slots.Count(); i++ )
696 {
697 string slot_name = attachment_slots.Get( i );
698 UpdateAttachmentVisuals( slot_name, IsAttachmentSlotLocked( slot_name ) );
699 }
700
701 //check base
702 if ( !HasBase() )
703 {
704 SetAnimationPhase( ANIMATION_DEPLOYED, 0 );
705 }
706 else
707 {
708 SetAnimationPhase( ANIMATION_DEPLOYED, 1 );
709 }
710
711 GetConstruction().UpdateVisuals();
712 }
713
714 void UpdateAttachmentVisuals( string slot_name, bool is_locked )
715 {
716 string slot_name_mounted = slot_name + "_Mounted";
717 EntityAI attachment = FindAttachmentBySlotName( slot_name );
718
719 if ( attachment )
720 {
721 //manage damage area trigger
722 if ( attachment.IsInherited( BarbedWire ) )
723 {
724 BarbedWire barbed_wire = BarbedWire.Cast( attachment );
725 if ( barbed_wire.IsMounted() )
726 {
727 CreateAreaDamage( slot_name_mounted ); //create damage trigger if barbed wire is mounted
728 }
729 else
730 {
731 DestroyAreaDamage( slot_name_mounted ); //destroy damage trigger if barbed wire is not mounted
732 }
733 //Print("attachment.IsInherited( BarbedWire ): " + slot_name_mounted);
734 }
735
736 if ( is_locked )
737 {
738 SetAnimationPhase( slot_name_mounted, 0 );
739 SetAnimationPhase( slot_name, 1 );
740 }
741 else
742 {
743 SetAnimationPhase( slot_name_mounted, 1 );
744 SetAnimationPhase( slot_name, 0 );
745 }
746 }
747 else
748 {
749 SetAnimationPhase( slot_name_mounted, 1 );
750 SetAnimationPhase( slot_name, 1 );
751
752 //remove area damage trigger
753 DestroyAreaDamage( slot_name_mounted ); //try to destroy damage trigger if barbed wire is not present
754 //Print("DestroyAreaDamage(slot_name_mounted): " + slot_name_mounted);
755 }
756 }
757
758 // avoid calling this function on frequent occasions, it's a massive performance hit
760 {
761 //update attachments physics
762 bsbDebugPrint("[bsb] " + GetDebugName(this) + " BaseBuildingBase::UpdatePhysics");
763
764 ref array<string> attachment_slots = new ref array<string>;
765 GetAttachmentSlots( this, attachment_slots );
766 bsbDebugPrint("[bsb] " + GetDebugName(this) + " att_cnt=" + attachment_slots.Count());
767 for ( int i = 0; i < attachment_slots.Count(); i++ )
768 {
769 string slot_name = attachment_slots.Get( i );
770 UpdateAttachmentPhysics( slot_name, IsAttachmentSlotLocked( slot_name ) );
771 }
772
773 //check base
774 if ( !HasBase() )
775 {
776 bsbDebugPrint("[bsb] " + GetDebugName(this) + ANIMATION_DEPLOYED + " ADD");
777 AddProxyPhysics( ANIMATION_DEPLOYED );
778 }
779 else
780 {
781 bsbDebugPrint("[bsb] " + GetDebugName(this) + ANIMATION_DEPLOYED + " RM");
782 RemoveProxyPhysics( ANIMATION_DEPLOYED );
783 }
784
785 GetConstruction().UpdatePhysics();
786
787 //regenerate navmesh
789 }
790
791 void UpdateAttachmentPhysics( string slot_name, bool is_locked )
792 {
793 //checks for invalid appends; hotfix
794 if ( !m_Mountables || m_Mountables.Find(slot_name) == -1 )
795 return;
796 //----------------------------------
797 string slot_name_mounted = slot_name + "_Mounted";
798 EntityAI attachment = FindAttachmentBySlotName( slot_name );
799
800 //remove proxy physics
801 bsbDebugPrint("[bsb] " + GetDebugName(this) + " Removing ATT SLOT=" + slot_name + " RM / RM");
802 RemoveProxyPhysics( slot_name_mounted );
803 RemoveProxyPhysics( slot_name );
804
805 if ( attachment )
806 {
807 bsbDebugPrint("[bsb] " + GetDebugName(this) + " Adding ATT=" + Object.GetDebugName(attachment));
808 if ( is_locked )
809 {
810 bsbDebugPrint("[bsb] " + GetDebugName(this) + " RM / RM");
811 AddProxyPhysics( slot_name_mounted );
812 }
813 else
814 {
815 bsbDebugPrint("[bsb] " + GetDebugName(this) + " ADD");
816 AddProxyPhysics( slot_name );
817 }
818 }
819 }
820
821 protected void UpdateNavmesh()
822 {
823 SetAffectPathgraph( true, false );
824 GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( GetGame().UpdatePathgraphRegionByObject, 100, false, this );
825 }
826
827 override bool CanUseConstruction()
828 {
829 return true;
830 }
831
833 {
834 return true;
835 }
836
837 protected bool IsAttachmentSlotLocked( EntityAI attachment )
838 {
839 if ( attachment )
840 {
841 InventoryLocation inventory_location = new InventoryLocation;
842 attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
843
844 return GetInventory().GetSlotLock( inventory_location.GetSlot() );
845 }
846
847 return false;
848 }
849
850 protected bool IsAttachmentSlotLocked( string slot_name )
851 {
852 return GetInventory().GetSlotLock( InventorySlots.GetSlotIdFromString( slot_name ) );
853 }
854
855 //--- ATTACHMENT SLOTS
856 void GetAttachmentSlots( EntityAI entity, out array<string> attachment_slots )
857 {
858 string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
859 if ( GetGame().ConfigIsExisting( config_path ) )
860 {
861 GetGame().ConfigGetTextArray( config_path, attachment_slots );
862 }
863 }
864
865 bool CheckSlotVerticalDistance( int slot_id, PlayerBase player )
866 {
867 return true;
868 }
869
870 protected bool CheckMemoryPointVerticalDistance( float max_dist, string selection, PlayerBase player )
871 {
872 return true;
873 }
874
875 protected bool CheckLevelVerticalDistance( float max_dist, string selection, PlayerBase player )
876 {
877 return true;
878 }
879
880 // --- INIT
882 {
883 if ( !m_Construction )
884 {
885 m_Construction = new Construction( this );
886 }
887
888 GetConstruction().Init();
889 }
890
892 {
893 return m_Construction;
894 }
895
896 //--- INVENTORY/ATTACHMENTS CONDITIONS
897 //attachments
898 override bool CanReceiveAttachment( EntityAI attachment, int slotId )
899 {
900 return super.CanReceiveAttachment(attachment, slotId);
901 }
902
904 {
905 int attachment_count = GetInventory().AttachmentCount();
906 if ( attachment_count > 0 )
907 {
908 if ( HasBase() && attachment_count == 1 )
909 {
910 return false;
911 }
912
913 return true;
914 }
915
916 return false;
917 }
918
919 override bool ShowZonesHealth()
920 {
921 return true;
922 }
923
924 //this into/outo parent.Cargo
925 override bool CanPutInCargo( EntityAI parent )
926 {
927 return false;
928 }
929
930 override bool CanRemoveFromCargo( EntityAI parent )
931 {
932 return false;
933 }
934
935 //hands
936 override bool CanPutIntoHands( EntityAI parent )
937 {
938 return false;
939 }
940
941 //--- ACTION CONDITIONS
942 //direction
943 override bool IsFacingPlayer( PlayerBase player, string selection )
944 {
945 return true;
946 }
947
948 override bool IsPlayerInside( PlayerBase player, string selection )
949 {
950 return true;
951 }
952
955 {
956 return false;
957 }
958
959 //camera direction check
960 bool IsFacingCamera( string selection )
961 {
962 return true;
963 }
964
965 //roof check
966 bool PerformRoofCheckForBase( string partName, PlayerBase player, out bool result )
967 {
968 return false;
969 }
970
971 //selection->player distance check
972 bool HasProperDistance( string selection, PlayerBase player )
973 {
974 return true;
975 }
976
977 //folding
979 {
980 if ( HasBase() || GetInventory().AttachmentCount() > 0 )
981 {
982 return false;
983 }
984
985 return true;
986 }
987
989 {
992 return item;
993 }
994
995 //Damage triggers (barbed wire)
996 void CreateAreaDamage( string slot_name, float rotation_angle = 0 )
997 {
998 if ( GetGame() && GetGame().IsServer() )
999 {
1000 //destroy area damage if some already exists
1001 DestroyAreaDamage( slot_name );
1002
1003 //create new area damage
1005 area_damage.SetDamageComponentType(AreaDamageComponentTypes.HITZONE);
1006
1007 //Print("BBB | area_damage: " + area_damage + " | slot_name: " + slot_name);
1008
1009 vector min_max[2];
1010 if ( MemoryPointExists( slot_name + "_min" ) )
1011 {
1012 min_max[0] = GetMemoryPointPos( slot_name + "_min" );
1013 }
1014 if ( MemoryPointExists( slot_name + "_max" ) )
1015 {
1016 min_max[1] = GetMemoryPointPos( slot_name + "_max" );
1017 }
1018
1019 //get proper trigger extents (min<max)
1020 vector extents[2];
1021 GetConstruction().GetTriggerExtents( min_max, extents );
1022
1023 //get box center
1024 vector center;
1025 center = GetConstruction().GetBoxCenter( min_max );
1026 center = ModelToWorld( center );
1027
1028 //rotate center if needed
1029 vector orientation = GetOrientation();;
1030 CalcDamageAreaRotation( rotation_angle, center, orientation );
1031
1032 area_damage.SetExtents( extents[0], extents[1] );
1033 area_damage.SetAreaPosition( center );
1034 area_damage.SetAreaOrientation( orientation );
1035 area_damage.SetLoopInterval( 1.0 );
1036 area_damage.SetDeferDuration( 0.2 );
1037 area_damage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
1038 area_damage.SetAmmoName( "BarbedWireHit" );
1039 area_damage.Spawn();
1040
1041 m_DamageTriggers.Insert( slot_name, area_damage );
1042 }
1043 }
1044
1045 void CalcDamageAreaRotation( float angle_deg, out vector center, out vector orientation )
1046 {
1047 if ( angle_deg != 0 )
1048 {
1049 //orientation
1050 orientation[0] = orientation[0] - angle_deg;
1051
1052 //center
1053 vector rotate_axis;
1054 if ( MemoryPointExists( "rotate_axis" ) )
1055 {
1056 rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
1057 }
1058 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];
1059 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];
1060 center[0] = r_center_x;
1061 center[2] = r_center_z;
1062 }
1063 }
1064
1065 void DestroyAreaDamage( string slot_name )
1066 {
1067 if ( GetGame() && GetGame().IsServer() )
1068 {
1070 if ( m_DamageTriggers.Find( slot_name, area_damage ) )
1071 {
1072 if ( area_damage )
1073 {
1074 //Print("DestroyAreaDamage: " + area_damage);
1075 area_damage.Destroy();
1076 }
1077
1078 m_DamageTriggers.Remove( slot_name );
1079 }
1080 }
1081 }
1082
1084 {
1085 return true;
1086 }
1087
1088 //================================================================
1089 // SOUNDS
1090 //================================================================
1091 protected void SoundBuildStart( string part_name )
1092 {
1093 PlaySoundSet( m_Sound, GetBuildSoundByMaterial( part_name ), 0.1, 0.1 );
1094 }
1095
1096 protected void SoundDismantleStart( string part_name )
1097 {
1098 PlaySoundSet( m_Sound, GetDismantleSoundByMaterial( part_name ), 0.1, 0.1 );
1099 }
1100
1101 protected void SoundDestroyStart( string part_name )
1102 {
1103 PlaySoundSet( m_Sound, GetDismantleSoundByMaterial( part_name ), 0.1, 0.1 );
1104 }
1105
1106 protected string GetBuildSoundByMaterial( string part_name )
1107 {
1108 ConstructionMaterialType material_type = GetConstruction().GetMaterialType( part_name );
1109
1110 switch ( material_type )
1111 {
1112 case ConstructionMaterialType.MATERIAL_LOG: return SOUND_BUILD_WOOD_LOG;
1113 case ConstructionMaterialType.MATERIAL_WOOD: return SOUND_BUILD_WOOD_PLANK;
1114 case ConstructionMaterialType.MATERIAL_STAIRS: return SOUND_BUILD_WOOD_STAIRS;
1115 case ConstructionMaterialType.MATERIAL_METAL: return SOUND_BUILD_METAL;
1116 case ConstructionMaterialType.MATERIAL_WIRE: return SOUND_BUILD_WIRE;
1117 }
1118
1119 return "";
1120 }
1121
1122 protected string GetDismantleSoundByMaterial( string part_name )
1123 {
1124 ConstructionMaterialType material_type = GetConstruction().GetMaterialType( part_name );
1125
1126 switch ( material_type )
1127 {
1128 case ConstructionMaterialType.MATERIAL_LOG: return SOUND_DISMANTLE_WOOD_LOG;
1129 case ConstructionMaterialType.MATERIAL_WOOD: return SOUND_DISMANTLE_WOOD_PLANK;
1130 case ConstructionMaterialType.MATERIAL_STAIRS: return SOUND_DISMANTLE_WOOD_STAIRS;
1131 case ConstructionMaterialType.MATERIAL_METAL: return SOUND_DISMANTLE_METAL;
1132 case ConstructionMaterialType.MATERIAL_WIRE: return SOUND_DISMANTLE_WIRE;
1133 }
1134
1135 return "";
1136 }
1137
1138 //misc
1139 void CheckForHybridAttachments( EntityAI item, string slot_name )
1140 {
1141 if (!GetGame().IsMultiplayer() || GetGame().IsServer())
1142 {
1143 //if this is a hybrid attachment, set damage of appropriate damage zone. Zone name must match slot name...WIP
1144 if (m_HybridAttachments && m_HybridAttachments.Find(slot_name) != -1)
1145 {
1146 SetHealth(slot_name,"Health",item.GetHealth());
1147 }
1148 }
1149 }
1150
1152 {
1153 return 111;
1154 }
1155
1156 override void SetActions()
1157 {
1158 super.SetActions();
1159
1161 //AddAction(ActionTakeHybridAttachment);
1162 //AddAction(ActionTakeHybridAttachmentToHands);
1165 }
1166
1167 //================================================================
1168 // DEBUG
1169 //================================================================
1170 protected void DebugCustomState()
1171 {
1172 }
1173
1176 {
1177 return null;
1178 }
1179
1180 override void OnDebugSpawn()
1181 {
1182 FullyBuild();
1183 }
1184
1186 {
1188 array<ConstructionPart> parts = GetConstruction().GetConstructionParts().GetValueArray();
1189
1190 Man p;
1191
1192 #ifdef SERVER
1193 array<Man> players = new array<Man>;
1194 GetGame().GetWorld().GetPlayerList(players);
1195 if (players.Count())
1196 p = players[0];
1197 #else
1198 p = GetGame().GetPlayer();
1199 #endif
1200
1201 foreach (ConstructionPart part : parts)
1202 {
1203 bool excluded = false;
1204 string partName = part.GetPartName();
1205 if (excludes)
1206 {
1207 foreach (string exclude : excludes)
1208 {
1209 if (partName.Contains(exclude))
1210 {
1211 excluded = true;
1212 break;
1213 }
1214 }
1215 }
1216
1217 if (!excluded)
1218 {
1219 OnPartBuiltServer(p, partName, AT_BUILD_PART);
1220 }
1221 }
1222
1223 GetConstruction().UpdateVisuals();
1224 }
1225}
1226
1227void bsbDebugPrint (string s)
1229 //Print("" + s); // comment/uncomment to hide/see debug logs
1231void bsbDebugSpam (string s)
1233 //Print("" + s); // comment/uncomment to hide/see debug logs
const int AT_DISMANTLE_PART
Definition _constants.c:7
const int AT_DESTROY_PART
Definition _constants.c:8
const int AT_BUILD_PART
Definition _constants.c:6
void AddAction(typename actionName)
void RemoveAction(typename actionName)
vector GetOrientation()
const string ANIMATION_DEPLOYED
protected void SoundDestroyStart(string part_name)
int m_SyncParts01
void OnPartDismantledClient(string part_name, int action_id)
void UpdateAttachmentVisuals(string slot_name, bool is_locked)
protected void SoundBuildStart(string part_name)
const string SOUND_BUILD_WOOD_LOG
void OnPartDestroyedClient(string part_name, int action_id)
protected void SetActionFromSyncData()
const string SOUND_DISMANTLE_METAL
void GetAttachmentSlots(EntityAI entity, out array< string > attachment_slots)
protected ConstructionPart GetConstructionPartById(int id)
protected string GetDismantleSoundByMaterial(string part_name)
void ConstructionInit()
ref array< string > m_HybridAttachments
int m_InteractedPartId
bool m_HasBase
void UpdateAttachmentPhysics(string slot_name, bool is_locked)
bool IsPartBuildInSyncData(int part_id)
void SetBaseState(bool has_base)
protected void SoundDismantleStart(string part_name)
const string SOUND_BUILD_WOOD_PLANK
ref array< string > m_Mountables
const string SOUND_BUILD_WIRE
int m_SyncParts03
ItemBase CreateConstructionKit()
void RegisterPartForSync(int part_id)
Construction GetConstruction()
protected void RegisterActionForSync(int part_id, int action_id)
ref Construction m_Construction
void CheckForHybridAttachments(EntityAI item, string slot_name)
void bsbDebugSpam(string s)
void DestroyConstruction()
bool HasBase()
const string SOUND_DISMANTLE_WOOD_PLANK
void OnPartBuiltClient(string part_name, int action_id)
const string SOUND_DISMANTLE_WOOD_LOG
class BaseBuildingBase extends ItemBase bsbDebugPrint(string s)
const string SOUND_BUILD_WOOD_STAIRS
protected string GetBuildSoundByMaterial(string part_name)
void SetPartFromSyncData(ConstructionPart part)
protected bool IsAttachmentSlotLocked(EntityAI attachment)
const string SOUND_DISMANTLE_WIRE
float m_ConstructionKitHealth
protected void DebugCustomState()
void CalcDamageAreaRotation(float angle_deg, out vector center, out vector orientation)
void UnregisterPartForSync(int part_id)
int m_PerformedActionId
void SetPartsFromSyncData()
protected void OnSynchronizedClient()
void SynchronizeBaseState()
ref map< string, ref AreaDamageManager > m_DamageTriggers
const string SOUND_BUILD_METAL
void FullyBuild()
override string GetInvulnerabilityTypeString()
int m_SyncParts02
protected void ResetActionSyncData()
void SetPartsAfterStoreLoad()
const string SOUND_DISMANTLE_WOOD_STAIRS
protected void UpdateNavmesh()
const int ECE_PLACE_ON_SURFACE
void InitVisuals()
ConstructionMaterialType
Definition Construction.c:2
void Construction(BaseBuildingBase parent)
void InitBaseState()
void DestroyAreaDamage()
void CreateAreaDamage()
EffectSound m_Sound
bool m_FixDamageSystemInit
Definition ItemBase.c:4695
override string GetDebugName()
Gets the debug name for the ParticleManager.
class JsonUndergroundAreaTriggerData GetPosition
A particular version of the deferred loop used to not damage players inside vehicles.
override void SetDeferDuration(float time)
override void SetLoopInterval(float time)
override array< string > OnDebugSpawnBuildExcludes()
Excludes certain parts from being built by OnDebugSpawn, uses Contains to compare.
Definition Fence.c:854
override void UpdateVisuals()
Definition Watchtower.c:44
override void OnPartBuiltServer(notnull Man player, string part_name, int action_id)
Definition Fence.c:297
override string GetConstructionKitType()
Definition Fence.c:45
override vector GetKitSpawnPosition()
Definition Fence.c:162
proto native void ObjectDelete(Object obj)
proto native DayZPlayer GetPlayer()
override ScriptCallQueue GetCallQueue(int call_category)
Definition DayZGame.c:1153
proto native void ConfigGetTextArray(string path, out TStringArray values)
Get array of strings from config on path.
proto native World GetWorld()
Wrapper class for managing sound through SEffectManager.
Definition EffectSound.c:5
InventoryLocation.
proto native int GetSlot()
returns slot id if current type is Attachment
provides access to slot configuration
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
override void OnDebugSpawn()
void OnPartDismantledServer(notnull Man player, string part_name, int action_id)
protected void SoundDestroyStart(string part_name)
void OnPartDismantledClient(string part_name, int action_id)
protected bool IsAttachmentSlotLocked(string slot_name)
void UpdateAttachmentVisuals(string slot_name, bool is_locked)
protected void SoundBuildStart(string part_name)
void CreateAreaDamage(string slot_name, float rotation_angle=0)
void BaseBuildingBase()
void OnPartDestroyedClient(string part_name, int action_id)
override bool IgnoreOutOfReachCondition()
protected void SetActionFromSyncData()
override bool IsFacingPlayer(PlayerBase player, string selection)
protected bool CheckLevelVerticalDistance(float max_dist, string selection, PlayerBase player)
override bool CanUseConstruction()
bool HasAttachmentsBesidesBase()
override void OnStoreSave(ParamsWriteContext ctx)
void GetAttachmentSlots(EntityAI entity, out array< string > attachment_slots)
override bool ShowZonesHealth()
protected ConstructionPart GetConstructionPartById(int id)
protected string GetDismantleSoundByMaterial(string part_name)
void ConstructionInit()
ref array< string > m_HybridAttachments
int m_InteractedPartId
void UpdateAttachmentPhysics(string slot_name, bool is_locked)
bool IsPartBuildInSyncData(int part_id)
void SetBaseState(bool has_base)
override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
void UpdateVisuals()
override void EEInit()
protected void SoundDismantleStart(string part_name)
override bool CanPutInCargo(EntityAI parent)
void OnPartBuiltServer(notnull Man player, string part_name, int action_id)
ref array< string > m_Mountables
ItemBase CreateConstructionKit()
bool IsFacingCamera(string selection)
void RegisterPartForSync(int part_id)
Construction GetConstruction()
override bool IsPlayerInside(PlayerBase player, string selection)
protected void RegisterActionForSync(int part_id, int action_id)
ref Construction m_Construction
protected bool CheckMemoryPointVerticalDistance(float max_dist, string selection, PlayerBase player)
void CheckForHybridAttachments(EntityAI item, string slot_name)
void DestroyConstruction()
override void EEItemDetached(EntityAI item, string slot_name)
override int GetDamageSystemVersionChange()
override bool CanObstruct()
bool HasProperDistance(string selection, PlayerBase player)
override void AfterStoreLoad()
void DestroyAreaDamage(string slot_name)
protected string GetConstructionKitType()
ItemBase FoldBaseBuildingObject()
void OnPartBuiltClient(string part_name, int action_id)
override void EEOnAfterLoad()
override bool CanPutIntoHands(EntityAI parent)
override int GetHideIconMask()
bool PerformRoofCheckForBase(string partName, PlayerBase player, out bool result)
override bool IsIgnoredByConstruction()
protected void OnSetSlotLock(int slotId, bool locked, bool was_locked)
protected vector GetKitSpawnPosition()
array< string > OnDebugSpawnBuildExcludes()
Excludes certain parts from being built by OnDebugSpawn, uses Contains to compare.
bool MustBeBuiltFromOutside()
Some buildings can only be built from outside.
void InitVisuals()
bool CanFoldBaseBuildingObject()
void OnPartDestroyedServer(Man player, string part_name, int action_id, bool destroyed_by_connected_part=false)
protected string GetBuildSoundByMaterial(string part_name)
override bool CanUseConstructionBuild()
void SetPartFromSyncData(ConstructionPart part)
override bool CanRemoveFromCargo(EntityAI parent)
override bool IsDeployable()
protected bool IsAttachmentSlotLocked(EntityAI attachment)
override bool OnStoreLoad(ParamsReadContext ctx, int version)
protected EffectSound m_Sound
override void EEItemAttached(EntityAI item, string slot_name)
void UpdatePhysics()
void CreateConstructionKitInHands(notnull PlayerBase player)
float m_ConstructionKitHealth
void InitBaseState()
protected void DebugCustomState()
override void OnVariablesSynchronized()
void CalcDamageAreaRotation(float angle_deg, out vector center, out vector orientation)
void UnregisterPartForSync(int part_id)
bool CheckSlotVerticalDistance(int slot_id, PlayerBase player)
int m_PerformedActionId
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
void SetPartsFromSyncData()
protected void OnSynchronizedClient()
void SynchronizeBaseState()
ref map< string, ref AreaDamageManager > m_DamageTriggers
override string GetInvulnerabilityTypeString()
void DestroyConstructionKit(ItemBase construction_kit)
override void SetActions()
protected void ResetActionSyncData()
void SetPartsAfterStoreLoad()
protected void UpdateNavmesh()
Definition EnMath.c:7
proto void CallLater(func fn, int delay=0, bool repeat=false, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
adds call into the queue with given parameters and arguments (arguments are held in memory until the ...
Serialization general interface. Serializer API works with:
Definition Serializer.c:56
proto bool Write(void value_out)
proto bool Read(void value_in)
proto native void GetPlayerList(out array< Man > players)
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
proto native CGame GetGame()
const int STATE_RUINED
Definition constants.c:742
static proto float Cos(float angle)
Returns cosinus of angle in radians.
static const float DEG2RAD
Definition EnMath.c:17
static proto float Sin(float angle)
Returns sinus of angle in radians.
bool Contains(string sample)
Returns true if sample is substring of string.
Definition EnString.c:286
proto int ToLower()
Changes string to lowercase. Returns length.
const int CALL_CATEGORY_GAMEPLAY
Definition tools.c:10
const int CALL_CATEGORY_SYSTEM
Definition tools.c:8