DayZ 1.24
Loading...
Searching...
No Matches
Construction.c
Go to the documentation of this file.
10
11class Construction
12{
13 static const float REPAIR_MATERIAL_PERCENTAGE = 0.15;
14 static const float DECONSTURCT_MATERIAL_LOSS = 0.2;
15 protected ref map<string, ref ConstructionPart> m_ConstructionParts; //string - part name; int - 0-not constructed, 1-constructed
17
18 //Debug
20 //Collision detectection
22
23 //============================================
24 // Construction
25 //============================================
27 {
29
30 //set parent object
31 SetParent(parent);
32 }
33
34 void Init()
35 {
37 }
38
39 //parent
41 {
42 return m_Parent;
43 }
44 protected void SetParent(BaseBuildingBase parent)
45 {
46 m_Parent = parent;
47 }
48 //============================================
49 // Construction process
50 //============================================
51 //constructed parts
53 {
55
57 {
58 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction " + Object.GetDebugName(m_Parent) + " AddToConstructedParts part=" + constrution_part.GetPartName());
59 constrution_part.SetBuiltState(true);
60 }
61 }
62
64 {
66
68 {
69 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction " + Object.GetDebugName(m_Parent) + " RemoveFromConstructedParts part=" + constrution_part.GetPartName());
70 constrution_part.SetBuiltState(false);
71 }
72 }
73
74 //BuildPart
76 {
77 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction BuildPartServer | " + part_name);
78 //reset DamageZone health
79 string damage_zone;
80 if (DamageSystem.GetDamageZoneFromComponentName(GetParent(), part_name, damage_zone))
81 {
82 GetParent().SetAllowDamage(true);
83 GetParent().SetHealthMax(damage_zone);
84 GetParent().ProcessInvulnerabilityCheck(GetParent().GetInvulnerabilityTypeString());
85 }
86
87 //on action
89
90 //destroy build collision check trigger
92
93 //call event
94 GetParent().OnPartBuiltServer(player, part_name, action_id);
95 }
96
97 //DismantlePart
99 {
100 string damage_zone;
101 DamageSystem.GetDamageZoneFromComponentName(GetParent(), part_name, damage_zone);
102
103 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction DismantlePartServer | " + part_name);
104 //receive materials
106
107 //drop non-usable materials
109
110 //call event
111 GetParent().OnPartDismantledServer(player, part_name, action_id);
112
113 //set DamageZone health to zero (redundant?)
114 /*if ( GetParent().GetHealth(damage_zone,"Health") > 0 )
115 {
116 GetParent().SetHealth(damage_zone,"Health",0);
117 }*/
118 }
119
120 //DestroyPart
122 {
123 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction DestroyPartServer | " + part_name);
124 //destroy attached materials (if locked)
126
127 //drop non-usable materials
129
130 //call event
132
133 //set DamageZone health to zero (redundant?)
134 string damage_zone;
135 if (DamageSystem.GetDamageZoneFromComponentName(GetParent(), part_name, damage_zone) && GetParent().GetHealth(damage_zone, "Health") > 0)
136 GetParent().SetHealth(damage_zone, "Health", 0);
137 }
138
140 {
141 array<string> parts;// = new array<string>;
143 if (parts)
144 {
145 for (int i = 0; i < parts.Count(); i++)
146 {
147 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction DestroyConnectedParts | " + parts.Get(i));
148 if (!ExceptionCheck(parts.Get(i)))
150 }
151 }
152 }
153
156 {
157 //gate hack
159 if (/*Fence.Cast(m_Parent) && */part.IsGate())
160 {
161 if (GetConstructionPart("wall_base_down").IsBuilt() || GetConstructionPart("wall_base_up").IsBuilt())
162 return true;
163 }
164 return false;
165 }
166
167 //============================================
168 // Update construction
169 //============================================
170 //update visual
172 {
173 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction " + Object.GetDebugName(m_Parent) + " InitVisuals");
174 for (int i = 0; i < m_ConstructionParts.Count(); ++i)
175 {
176 string key = m_ConstructionParts.GetKey(i);
178
179 if (value.IsBuilt())
180 ShowConstructionPart(value.GetPartName());
181 }
182 }
183
185 {
186 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction " + Object.GetDebugName(m_Parent) + " UpdateVisuals");
187 for (int i = 0; i < m_ConstructionParts.Count(); ++i)
188 {
189 string key = m_ConstructionParts.GetKey(i);
191 if (value.IsBuilt())
192 ShowConstructionPart(value.GetPartName());
193 else
194 HideConstructionPart(value.GetPartName());
195 }
196 }
197
198 //update physics (only)
200 {
201 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction " + Object.GetDebugName(m_Parent) + " UpdatePhysics m_ConstructionParts=" + m_ConstructionParts.Count());
202 for (int i = 0; i < m_ConstructionParts.Count(); ++i)
203 {
204 string key = m_ConstructionParts.GetKey(i);
206
207 if (value.IsBuilt())
208 {
209 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] GetType=" + m_Parent.GetType() + " i=" + i + " ADD");
210 ShowConstructionPartPhysics(value.GetPartName());
211 }
212 else
213 {
214 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] GetType=" + m_Parent.GetType() + " i=" + i + " RM");
215 HideConstructionPartPhysics(value.GetPartName());
216 }
217 }
218 }
219
221 {
222 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction " + Object.GetDebugName(m_Parent) + " InitBaseState");
223 InitVisuals();
224 }
225
226 //update construction parts
227 protected void UpdateConstructionParts()
228 {
229 string construction_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction";
230
231 if (GetGame().ConfigIsExisting(construction_path))
232 {
233 //main parts
234 for (int i = 0; i < GetGame().ConfigGetChildrenCount(construction_path); ++i)
235 {
236 string main_part_name;
237 GetGame().ConfigGetChildName(construction_path, i, main_part_name);
239
240 //parts
241 for (int j = 0; j < GetGame().ConfigGetChildrenCount(part_path); ++j)
242 {
243 string part_name;
244 GetGame().ConfigGetChildName(part_path, j, part_name);
245
246 string name;
247 GetGame().ConfigGetTextRaw(part_path + " " + part_name + " " + "name", name); //name
248 GetGame().FormatRawConfigStringKeys(name);
249 bool show_on_init = GetGame().ConfigGetInt(part_path + " " + part_name + " " + "show_on_init"); //show on init
250 int id = GetGame().ConfigGetInt(part_path + " " + part_name + " " + "id"); //part id
251 bool is_base = GetGame().ConfigGetInt(part_path + " " + part_name + " " + "is_base"); //is base (part)
252 bool is_gate = GetGame().ConfigGetInt(part_path + " " + part_name + " " + "is_gate"); //is gate (part)
253
255
256 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction name=" + name + " part_name=" + part_name + " show=" + show_on_init + " base=" + is_base + " gate=" + is_gate);
257 }
258 }
259 }
260 }
261
262 //============================================
263 // Parts
264 //============================================
269
274
275 //CONSTRUCTION
276 /*ConstructionPart GetConstructionPartToBuild( string part_name, ItemBase tool )
277 {
278 if ( CanBuildPart( part_name, tool ) )
279 {
280 return GetConstructionPart( part_name );
281 }
282
283 return NULL;
284 }*/
285
293
295 {
297 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "Materials";
298
299 if (GetGame().ConfigIsExisting(cfg_path))
300 {
301 int child_count = GetGame().ConfigGetChildrenCount(cfg_path);
302
303 for (int i = 0; i < child_count; i++)
304 {
305 string child_name;
306 GetGame().ConfigGetChildName(cfg_path, i, child_name);
307
308 //get type, quantity from material
309 string config_path;
310 string slot_name;
311 config_path = cfg_path + " " + child_name + " " + "slot_name";
312 GetGame().ConfigGetText(config_path, slot_name);
313 config_path = cfg_path + " " + child_name + " " + "quantity";
314 float quantity = GetGame().ConfigGetFloat(config_path);
315 config_path = cfg_path + " " + child_name + " " + "lockable";
316 bool lockable = GetGame().ConfigGetInt(config_path);
317
318 ItemBase attachment = ItemBase.Cast(GetParent().FindAttachmentBySlotName(slot_name));
319 if (attachment.IsRuined())
320 return true;
321 }
322 }
323 return false;
324 }
325
326 //Get all construction parts that can be build (at that current time)
328 {
329 construction_parts.Clear();
330 string part_name;
332 string key;
333
334 for (int i = 0; i < m_ConstructionParts.Count(); ++i)
335 {
336 key = m_ConstructionParts.GetKey(i);
338
339 if (main_part_name == value.GetMainPartName() && CanBuildPart(value.GetPartName(), tool, use_tool))
341
342 if (main_part_name == value.GetPartName())
343 part_name = value.GetMainPartName();
344 }
345
346 if (construction_parts.Count() == 0 && part_name)
347 {
348 for (i = 0; i < m_ConstructionParts.Count(); ++i)
349 {
350 key = m_ConstructionParts.GetKey(i);
352
353 if (part_name == value.GetMainPartName() && CanBuildPart(value.GetPartName(), tool, use_tool))
355 }
356 }
357 }
358
359 //Returns (first found) base construction part
361 {
362 for (int i = 0; i < m_ConstructionParts.Count(); ++i)
363 {
364 string key = m_ConstructionParts.GetKey(i);
366
367 if (value.IsBase())
368 return value;
369 }
370
371 return NULL;
372 }
373
374 //Returns (first found) gate construction part
376 {
377 for (int i = 0; i < m_ConstructionParts.Count(); ++i)
378 {
379 string key = m_ConstructionParts.GetKey(i);
381
382 if (value.IsGate())
383 return value;
384 }
385
386 return NULL;
387 }
388
389 //checks if construction part has required part already built
390 protected bool HasRequiredPart(string part_name)
391 {
393 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "required_parts";
394
396 GetGame().ConfigGetTextArray(cfg_path, required_parts);
397
398 //check if parts are already built
399 for (int i = 0; i < required_parts.Count(); ++i)
400 {
402 return false;
403 //hack - gate
404 /*else if (part_name == "wall_gate" && (IsPartConstructed("wall_base_down") || IsPartConstructed("wall_base_up")))
405 {
406 return true;
407 }*/
408 }
409
410 return true;
411 }
412
413 //checks if there are conflict parts already built
414 protected bool HasConflictPart(string part_name)
415 {
417 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "conflicted_parts";
419 GetGame().ConfigGetTextArray(cfg_path, conflict_parts);
420
421 //check if parts are already built
422 for (int i = 0; i < conflict_parts.Count(); i++)
423 {
425 return true;
426 }
427
428 return false;
429 }
430
431 //DECONSTRUCTION
439
441 {
443 return true;
444
445 return false;
446 }
447
448 //checks if construction part has dependent part (that is already built) because of which it cannot be deconstruct
449 //TODO return whole array of dependent parts/dependencies (one or the other), should be used to eventually destroy all dependent parts instead
451 {
452 for (int i = 0; i < m_ConstructionParts.Count(); ++i)
453 {
454 string key = m_ConstructionParts.GetKey(i);
456
457 if (construction_part.IsBuilt())
458 {
459 if (construction_part.GetRequiredParts().Find(part_name) > -1)
460 return true;
461 }
462 }
463
464 return false;
465 }
466
467 //returns array of BUILT parts that directly depend on 'part_name'
469 {
470 string name;
471 string cfg_path;
473
474 for (int i = 0; i < m_ConstructionParts.Count(); ++i)
475 {
476 name = m_ConstructionParts.GetKey(i);
478
479 if (construction_part.IsBuilt() && construction_part.GetRequiredParts() && construction_part.GetRequiredParts().Find(part_name) > -1) //does the construction part need 'part_name' to exist?
480 {
481 if (!dependent_parts)
483
484 if (!recurs || (recurs.Find(name) == -1))
485 dependent_parts.Insert(name);
486 // Print("part #" + i + ": " + name);
487 }
488 }
489
490 //fully recursive search, disconnected (unnescessary)
491 /*if (dependent_parts)
492 {
493 if ( dependent_parts.Count() > 0 )
494 {
495 ref array<string> temp = new array<string>;
496 for ( i = 0; i < dependent_parts.Count(); i++ )
497 {
498 temp = GetValidDepenentPartsArray(dependent_parts.Get(i),dependent_parts);
499 if (temp.Count() > 0)
500 {
501 dependent_parts.InsertAll(temp);
502 }
503 }
504 }
505 Print("dependent_parts.Count(): " + dependent_parts.Count());
506 }*/
507 return dependent_parts;
508 }
509
510 //gets all required parts of a construction part; fills into ConstructionPart on init
512 {
513 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "required_parts";
515 GetGame().ConfigGetTextArray(cfg_path, required_parts);
516
517 return required_parts;
518 }
519
520 //DESTROY
528
530 {
532 return true;
533
534 return false;
535 }
536
537 //CONSTRUCTION PART STATE
538 //show/hide construction part
539 protected void ShowConstructionPart(string part_name)
540 {
541 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction ShowConstructionPart - " + part_name);
542 GetParent().SetAnimationPhase(part_name, 0);
543 }
544
545 protected void HideConstructionPart(string part_name)
546 {
547 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] Construction HideConstructionPart - " + part_name);
548 GetParent().SetAnimationPhase(part_name, 1);
549 }
550
551 //show/hide physics
553 {
554 GetParent().AddProxyPhysics(part_name);
555 }
556
558 {
559 GetParent().RemoveProxyPhysics(part_name);
560 }
561
562 //is part constructed
564 {
566 if (construction_part && construction_part.IsBuilt())
567 return true;
568
569 return false;
570 }
571
572 //============================================
573 // Materials for construction
574 //============================================
575 //has materials
576 bool HasMaterials(string part_name, bool repairing = false)
577 {
579 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "Materials";
580
581 if (GetGame().ConfigIsExisting(cfg_path))
582 {
583 int child_count = GetGame().ConfigGetChildrenCount(cfg_path);
584
585 for (int i = 0; i < child_count; i++)
586 {
587 string child_name;
588 GetGame().ConfigGetChildName(cfg_path, i, child_name);
589
590 //get type, quantity from material
591 string material_path;
592 string slot_name;
593 float quantity;
594 material_path = cfg_path + " " + child_name + " " + "slot_name";
595 GetGame().ConfigGetText(material_path, slot_name);
596 material_path = cfg_path + " " + child_name + " " + "quantity";
597 quantity = GetGame().ConfigGetFloat(material_path);
598
599 if (repairing)
600 {
603 }
604
605 //if the selected material (or its quantity) is not available
607 return false;
608 }
609 }
610
611 return true; //return true even if no material required
612 }
613
614 //check if parent object has attachment of required quantity attached to it
616 {
617 ItemBase attachment = ItemBase.Cast(GetParent().FindAttachmentBySlotName(slot_name));
618
619 if (attachment && attachment.GetQuantity() >= quantity)
620 return true;
621
622 return false;
623 }
624
625 //take materials when building
626 void TakeMaterialsServer(string part_name, bool repairing = false)
627 {
629 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "Materials";
630
631 if (GetGame().ConfigIsExisting(cfg_path))
632 {
633 int child_count = GetGame().ConfigGetChildrenCount(cfg_path);
634
635 for (int i = 0; i < child_count; i++)
636 {
637 string child_name;
638 GetGame().ConfigGetChildName(cfg_path, i, child_name);
639
640 //get type, quantity from material
641 string config_path;
642 string slot_name;
643 config_path = cfg_path + " " + child_name + " " + "slot_name";
644 GetGame().ConfigGetText(config_path, slot_name);
645 config_path = cfg_path + " " + child_name + " " + "quantity";
646 float quantity = GetGame().ConfigGetFloat(config_path);
647 config_path = cfg_path + " " + child_name + " " + "lockable";
648 bool lockable = GetGame().ConfigGetInt(config_path);
649
650 ItemBase attachment = ItemBase.Cast(GetParent().FindAttachmentBySlotName(slot_name));
651 if (lockable)
652 {
653 //lock attachment
655 attachment.GetInventory().GetCurrentInventoryLocation(inventory_location);
656
657 GetParent().GetInventory().SetSlotLock(inventory_location.GetSlot(), true);
658 }
659 else
660 {
661 if (quantity > -1) //0 - ignores quantity
662 {
663 if (repairing)
664 {
667 }
668 //subtract quantity
669 attachment.AddQuantity(-quantity);
670 }
671 else //-1 - deletes the object
672 GetGame().ObjectDelete(attachment);
673 }
674 }
675 }
676 }
677
678 //receive materials when dismantling
680 {
682 bool is_base = construction_part.IsBase();
683 string main_part_name = construction_part.GetMainPartName();
684 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "Materials";
685
686 if (GetGame().ConfigIsExisting(cfg_path))
688 }
689
690 //destroy lockable materials when destroying
691 protected void DestroyMaterialsServer(Man player, string part_name)
692 {
694 string main_part_name = cPart.GetMainPartName();
695 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "Materials";
696
697 if (GetGame().ConfigIsExisting(cfg_path))
698 {
699 int child_count = GetGame().ConfigGetChildrenCount(cfg_path);
700
701 for (int i = 0; i < child_count; i++)
702 {
703 string child_name;
704 GetGame().ConfigGetChildName(cfg_path, i, child_name);
705
706 //get type, quantity from material
707 string config_path;
708 string type;
709 string slot_name;
710 config_path = cfg_path + " " + child_name + " " + "type";
711 GetGame().ConfigGetText(config_path, type);
712 config_path = cfg_path + " " + child_name + " " + "slot_name";
713 GetGame().ConfigGetText(config_path, slot_name);
714 config_path = cfg_path + " " + child_name + " " + "quantity";
715 float quantity = GetGame().ConfigGetFloat(config_path);
716 config_path = cfg_path + " " + child_name + " " + "lockable";
717 bool lockable = GetGame().ConfigGetInt(config_path);
718
719 //get material
720 ItemBase attachment = ItemBase.Cast(GetParent().FindAttachmentBySlotName(slot_name));
721
722 //material still attached
723 if (lockable) //if lockable
724 {
725 if (attachment)
726 {
728 attachment.GetInventory().GetCurrentInventoryLocation(inventory_location);
729 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + Object.GetDebugName(GetParent()) + " DestroyMaterialsServer unlock slot=" + inventory_location.GetSlot());
730
731 GetParent().GetInventory().SetSlotLock(inventory_location.GetSlot(), false);
732 GetGame().ObjectDelete(attachment); //delete object
733 }
734 }
735 }
736 }
737 }
738
740 {
742
743 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + construction_part.GetMainPartName() + " " + construction_part.GetPartName() + " " + "platform_support";
744 string platform_support;
745
746 if (GetGame().ConfigIsExisting(cfg_path))
747 GetGame().ConfigGetText(cfg_path, platform_support);
748
749 if (platform_support.Length() > 0 || construction_part.IsBase())
750 {
751 string at_cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "GUIInventoryAttachmentsProps";
752
753 if (GetGame().ConfigIsExisting(at_cfg_path))
754 {
755 int child_count = GetGame().ConfigGetChildrenCount(at_cfg_path);
756
757 for (int i = 0; i < child_count; i++)
758 {
759 string child_name;
760 GetGame().ConfigGetChildName(at_cfg_path, i, child_name);
761 child_name.ToLower();
762
763 if (child_name.Contains(platform_support))
764 {
766 GetGame().ConfigGetTextArray(at_cfg_path + " " + child_name + " " + "attachmentSlots", attachment_slots);
767
768 for (int j = 0; j < attachment_slots.Count(); ++j)
769 {
770 //get material
771 ItemBase attachment = ItemBase.Cast(GetParent().FindAttachmentBySlotName(attachment_slots.Get(j)));
772
773 //material still attached
774 if (attachment)
775 {
777 attachment.GetInventory().GetCurrentInventoryLocation(inventory_location);
778 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + Object.GetDebugName(GetParent()) + " DropNonUsableMaterials UNlocking slot=" + inventory_location.GetSlot());
779
780 //unlock slot
781 GetParent().GetInventory().SetSlotLock(inventory_location.GetSlot(), false);
782
783 EntityAI parent = GetParent();
784 if (!parent)
785 parent = player;
786
787 int quantity_max = attachment.GetTargetQuantityMax(-1);
789 vector mat[4];
790 attachment.GetTransform(mat);
791
792 if (parent.MemoryPointExists("" + part_name + "_materials"))
793 {
794 vector destination = parent.GetMemoryPointPos("" + part_name + "_materials");
795 destination = GetGame().ObjectModelToWorld(parent, destination);
796 float health = attachment.GetHealth("", "Health");
797 float quantity = attachment.GetQuantity() - 1;
798 if (quantity < 1.0)
799 quantity = 1.0;
800 float dir[4];
801 inventory_location.GetDir(dir);
802 dst.SetGroundEx(attachment, destination, dir);
803 //Print(dst.DumpToString());
804 MiscGameplayFunctions.CreateItemBasePiles(attachment.GetType(), destination, quantity, health, true);
805 attachment.AddQuantity(-quantity);
806 }
807 else
808 {
809 dst.SetGround(attachment, mat);
810
811 for (int k = attachment.GetQuantity(); k > quantity_max;)
812 {
813 Object o = parent.GetInventory().LocationCreateEntity(dst, attachment.GetType(), ECE_PLACE_ON_SURFACE, RF_DEFAULT);
814 ItemBase new_item = ItemBase.Cast(o);
815
816 if (new_item)
817 {
818 MiscGameplayFunctions.TransferItemProperties(attachment, new_item);
819 attachment.AddQuantity(-quantity_max);
820 new_item.SetQuantity(quantity_max);
821 }
822 k -= quantity_max;
823 }
824 }
825
826 //drop
827 if (attachment.GetQuantity() > 0)
828 {
829 if (GetGame().IsMultiplayer())
831 else
833 }
834 else
835 attachment.Delete();
836 }
837 }
838 }
839 }
840 }
841 }
842 }
843
844 //set lock on materials that are attached and cannot be locked/unlocked
846 {
848 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "Materials";
849
850 if (GetGame().ConfigIsExisting(cfg_path))
851 {
852 int child_count = GetGame().ConfigGetChildrenCount(cfg_path);
853
854 for (int i = 0; i < child_count; i++)
855 {
856 string child_name;
857 GetGame().ConfigGetChildName(cfg_path, i, child_name);
858
859 //get type, quantity from material
860 string config_path;
861 string type;
862 string slot_name;
863 config_path = cfg_path + " " + child_name + " " + "type";
864 GetGame().ConfigGetText(config_path, type);
865 config_path = cfg_path + " " + child_name + " " + "slot_name";
866 GetGame().ConfigGetText(config_path, slot_name);
867 config_path = cfg_path + " " + child_name + " " + "quantity";
868 float quantity = GetGame().ConfigGetFloat(config_path);
869 config_path = cfg_path + " " + child_name + " " + "lockable";
870 bool lockable = GetGame().ConfigGetInt(config_path);
871
872 //get material
873 ItemBase attachment = ItemBase.Cast(GetParent().FindAttachmentBySlotName(slot_name));
874
875 //material still attached
876 if (lockable) //if lockable
877 {
878 if (attachment)
879 {
881 attachment.GetInventory().GetCurrentInventoryLocation(inventory_location);
882 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + Object.GetDebugName(GetParent()) + " SetLockOnAttachedMaterials lock=" + lock_slot + " slot=" + inventory_location.GetSlot());
883 GetParent().GetInventory().SetSlotLock(inventory_location.GetSlot(), lock_slot);
884 }
885 }
886 }
887 }
888 }
889
890 //============================================
891 // Construction tools
892 //============================================
894 {
896 string part_cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + construction_part.GetMainPartName() + " " + construction_part.GetPartName() + " " + "build_action_type";
897 if (GetGame().ConfigIsExisting(part_cfg_path))
898 {
899 int part_build_action_type = GetGame().ConfigGetInt(part_cfg_path);
900 string tool_cfg_path = "cfgVehicles" + " " + tool.GetType() + " " + "build_action_type";
901
902 if (GetGame().ConfigIsExisting(tool_cfg_path))
903 {
904 int tool_build_action_type = GetGame().ConfigGetInt(tool_cfg_path);
905
907 return true;
908 }
909 }
910
911 return false;
912 }
913
915 {
917 string part_cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + construction_part.GetMainPartName() + " " + construction_part.GetPartName() + " " + "dismantle_action_type";
918 if (GetGame().ConfigIsExisting(part_cfg_path))
919 {
921 string tool_cfg_path = "cfgVehicles" + " " + tool.GetType() + " " + "dismantle_action_type";
922
923 if (GetGame().ConfigIsExisting(tool_cfg_path))
924 {
926
928 return true;
929 }
930 }
931
932 return false;
933 }
934
936 {
938 string part_cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + construction_part.GetMainPartName() + " " + construction_part.GetPartName() + " " + "material_type";
939 if (GetGame().ConfigIsExisting(part_cfg_path))
940 return GetGame().ConfigGetInt(part_cfg_path);
941
942 return ConstructionMaterialType.MATERIAL_NONE;
943 }
944
945 //============================================
946 // Collision check
947 //============================================
948 //Collisions (BBox and Trigger); deprecated
950 {
952 return false;
954
956 {
958 float absolute_ofset = 0.05; //we need to lift BBox even more, because it colliddes with house floors due to various reasons (probably geometry or float imperfections)
960 vector min_max[2]; //data used for creating trigger
963
964 excluded_objects.Insert(GetParent());
965
966 //get min_max and center from config and memory points
968
970 center = GetParent().ModelToWorld(center); //convert to world coordinates
972
973 //Create trigger
974 //CreateCollisionTrigger( part_name, min_max, center );
975
976 //check collision on box trigger and collision box
977 //IsTrigger colliding was turned off (for now) for easier way to build something with other players around
978 if (/* IsTriggerColliding() || */ GetGame().IsBoxCollidingGeometry(Vector(center[0], center[1] + absolute_ofset, center[2]), GetParent().GetOrientation(), edge_length, ObjIntersectView, ObjIntersectGeom, excluded_objects, collided_objects))
979 {
980 //Debug
981 // DrawDebugCollisionBox( min_max, ARGB( 150, 255, 0, 0 ) );
982 //
983 for (int i = 0; i < collided_objects.Count(); i++)
984 {
985 //Print(collided_objects.Get(i).GetType());
987 if (entity && !entity.IsIgnoredByConstruction())
988 return true;
989 }
990 }
991 //Debug
992 // DrawDebugCollisionBox( min_max, ARGB( 150, 255, 255, 255 ) );
993 }
994 return false;
995 }
996
999 {
1001 return false;
1003
1005 {
1006 vector center;
1007 float absolute_ofset = 0.05; //we need to lift BBox even more, because it colliddes with house floors due to various reasons (probably geometry or float imperfections)
1009 vector min_max[2]; //data used for creating trigger
1012
1013 excluded_objects.Insert(GetParent());
1014 if (check_data.m_AdditionalExcludes.Count() > 0)
1015 excluded_objects.InsertAll(check_data.m_AdditionalExcludes);
1016
1019 center = GetParent().ModelToWorld(center); //convert to world coordinates
1021
1022 if (GetGame().IsBoxCollidingGeometry(Vector(center[0], center[1] + absolute_ofset, center[2]), GetParent().GetOrientation(), edge_length, check_data.m_PrimaryGeometry, check_data.m_SecondaryGeometry, excluded_objects, collided_objects))
1023 {
1024 //Debug
1025 //DrawDebugCollisionBox( min_max, ARGB( 150, 255, 0, 0 ) );
1026 for (int i = 0; i < collided_objects.Count(); i++)
1027 {
1029 if (entity && !entity.IsIgnoredByConstruction())
1030 return true;
1031 }
1032 }
1033 //Debug
1034 //DrawDebugCollisionBox( min_max, ARGB( 150, 255, 255, 255 ) );
1035 }
1036 return false;
1037 }
1038
1040 {
1041 vector box_size = Vector(0, 0, 0);
1042
1043 box_size[0] = Math.AbsFloat(min_max[1][0] - min_max[0][0]);
1044 box_size[1] = Math.AbsFloat(min_max[1][1] - min_max[0][1]);
1045 box_size[2] = Math.AbsFloat(min_max[1][2] - min_max[0][2]);
1046
1047 return box_size;
1048 }
1049
1050 //returns collision box data from construction config and model p3d
1052 {
1054 string cfg_path = "cfgVehicles" + " " + GetParent().GetType() + " " + "Construction" + " " + main_part_name + " " + part_name + " " + "collision_data";
1056 GetGame().ConfigGetTextArray(cfg_path, collision_data);
1057
1058 if (collision_data.Count() > 0)
1059 {
1060 if (GetParent().MemoryPointExists(collision_data[0]))
1061 min_max[0] = GetParent().GetMemoryPointPos(collision_data[0]);
1062 if (GetParent().MemoryPointExists(collision_data[1]))
1063 min_max[1] = GetParent().GetMemoryPointPos(collision_data[1]);
1064 }
1065 }
1066
1067 //returns center point of box defined by min/max values
1069 {
1070 vector center;
1071
1072 center[0] = (min_max[1][0] - min_max[0][0]) / 2;
1073 center[1] = (min_max[1][1] - min_max[0][1]) / 2;
1074 center[2] = (min_max[1][2] - min_max[0][2]) / 2;
1075 center = Vector(min_max[1][0] - center[0], min_max[1][1] - center[1], min_max[1][2] - center[2]); //offset to box center
1076
1077 return center;
1078 }
1079
1081 {
1083 extents[0][0] = -egde_length[0] / 2; //min
1084 extents[0][1] = -egde_length[1] / 2;
1085 extents[0][2] = -egde_length[2] / 2;
1086 extents[1][0] = egde_length[0] / 2; //max
1087 extents[1][1] = egde_length[1] / 2;
1088 extents[1][2] = egde_length[2] / 2;
1089 }
1090
1091 //Debug
1093 {
1095
1096 vector mat[4];
1097 GetParent().GetTransform(mat);
1098
1100 m_CollisionBox.SetMatrix(mat);
1101 }
1102
1104 {
1105 if (m_CollisionBox)
1106 {
1107 m_CollisionBox.Destroy();
1109 }
1110 }
1111
1113 {
1115 {
1116 if (m_ConstructionBoxTrigger.GetPartName() == part_name) //already created
1117 return;
1118 else
1120 }
1121
1122 //get proper trigger extents (min<max)
1123 vector extents[2];
1125
1126 //create trigger
1127 m_ConstructionBoxTrigger = ConstructionBoxTrigger.Cast(GetGame().CreateObject("ConstructionBoxTrigger", center, false, false, false));
1128 m_ConstructionBoxTrigger.SetPosition(center);
1131
1133 }
1134 //
1135
1141
1143 {
1145 }
1146}
1147
1149{
1152 {
1153 int child_count = GetGame().ConfigGetChildrenCount(cfg_path);
1154
1155 for (int i = 0; i < child_count; i++)
1156 {
1157 string child_name;
1158 GetGame().ConfigGetChildName(cfg_path, i, child_name);
1159
1160 //get type, quantity from material
1161 string config_path;
1162 string type;
1163 string slot_name;
1164 config_path = cfg_path + " " + child_name + " " + "type";
1165 GetGame().ConfigGetText(config_path, type);
1166 config_path = cfg_path + " " + child_name + " " + "slot_name";
1167 GetGame().ConfigGetText(config_path, slot_name);
1168 config_path = cfg_path + " " + child_name + " " + "quantity";
1169 float quantity = GetGame().ConfigGetFloat(config_path);
1170 config_path = cfg_path + " " + child_name + " " + "lockable";
1171 bool lockable = GetGame().ConfigGetInt(config_path);
1172
1173 //receive material quantity
1174 ItemBase attachment = ItemBase.Cast(entity.FindAttachmentBySlotName(slot_name));
1175 int slot_id;
1176
1177 //material still attached
1178 if (lockable) //if lockable
1179 {
1180 if (attachment)
1181 {
1183 attachment.GetInventory().GetCurrentInventoryLocation(src);
1184 if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + Object.GetDebugName(entity) + " DropNonUsableMaterials UNlocking slot=" + src.GetSlot());
1185 entity.GetInventory().SetSlotLock(src.GetSlot(), false);
1186
1187 //detach if base
1188 if (is_base)
1189 {
1190 if (GetGame().IsMultiplayer() && player)
1191 {
1194 player.ServerTakeToDst(src, dst);
1195 }
1196 else
1197 entity.GetInventory().DropEntity(InventoryMode.PREDICTIVE, entity, attachment);
1198 }
1199 }
1200 }
1201 else
1202 {
1203 float pile_health;
1204 float qty_coef;
1205 vector destination = entity.GetPosition();
1206 //placed on helper memory point, if available
1207 if (entity.MemoryPointExists("" + main_part_name + "_materials"))
1208 {
1209 destination = entity.GetMemoryPointPos("" + main_part_name + "_materials");
1210 destination = GetGame().ObjectModelToWorld(entity, destination);
1211 }
1212 else if (entity.MemoryPointExists(main_part_name))
1213 {
1214 destination = entity.GetMemoryPointPos(main_part_name);
1215 destination = GetGame().ObjectModelToWorld(entity, destination);
1216 }
1217 //pile_health = GameConstants.DAMAGE_WORN_VALUE * MiscGameplayFunctions.GetTypeMaxGlobalHealth(type);
1218 pile_health = entity.GetHealth01(damagezone_name, "Health") * MiscGameplayFunctions.GetTypeMaxGlobalHealth(type);
1219 qty_coef = 1 - (entity.GetHealthLevel(damagezone_name) * Construction.DECONSTURCT_MATERIAL_LOSS) - Construction.DECONSTURCT_MATERIAL_LOSS;
1220 quantity *= qty_coef;
1222 MiscGameplayFunctions.CreateItemBasePiles(type, destination, quantity, pile_health, true);
1223 }
1224 }
1225 }
1226}
1227
1230{
1235
1243}
1244
1246{
1248
1250 {
1252 }
1253
1255 {
1256 return m_PartName;
1257 }
1258
1259 override protected void UpdateInsiders(int timeout)
1260 {
1261 super.UpdateInsiders(20);
1262 }
1263
1265 {
1266 if (GetInsiders().Count() > 0)
1267 return true;
1268
1269 return false;
1270 }
1271}
InventoryMode
NOTE: PREDICTIVE is not to be used at all in multiplayer.
Definition Inventory.c:22
const int AT_DESTROY_PART
Definition _constants.c:8
vector GetOrientation()
override string GetInvulnerabilityTypeString()
class BaseBuildingBase extends ItemBase bsbDebugPrint(string s)
const int ECE_PLACE_ON_SURFACE
const int RF_DEFAULT
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
void DropNonUsableMaterialsServer(Man player, string part_name)
void HideConstructionPartPhysics(string part_name)
bool CanDestroyPart(string part_name)
vector GetBoxCenter(vector min_max[2])
bool CanBuildPart(string part_name, ItemBase tool, bool use_tool)
void DrawDebugCollisionBox(vector min_max[2], int color)
static const float DECONSTURCT_MATERIAL_LOSS
Shape m_CollisionBox
void BuildPartServer(notnull Man player, string part_name, int action_id)
bool IsCollidingEx(CollisionCheckData check_data)
Collision check for building part.
ConstructionPart GetBaseConstructionPart()
ConstructionPart GetConstructionPartToDestroy(string part_name)
bool HasMaterials(string part_name, bool repairing=false)
vector GetCollisionBoxSize(vector min_max[2])
void GetCollisionBoxData(string part_name, out vector min_max[2])
array< string > GetRequiredParts(string part_name, string main_part_name)
class StaticConstructionMethods m_AdditionalExcludes
Data structure for passing parameters (extendable, modable)
bool MaterialIsRuined(string part_name)
bool HasConflictPart(string part_name)
ConstructionPart GetConstructionPartToDismantle(string part_name, ItemBase tool)
ConstructionPart GetConstructionPart(string part_name)
void GetTriggerExtents(vector min_max[2], out vector extents[2])
void UpdateVisuals()
void ReceiveMaterialsServer(notnull Man player, string part_name, string damagezone_name)
void GetConstructionPartsToBuild(string main_part_name, out array< ConstructionPart > construction_parts, ItemBase tool, out string real_constructionTarget, bool use_tool)
int m_PrimaryGeometry
int m_SecondaryGeometry
void ShowConstructionPart(string part_name)
bool IsTriggerColliding()
void UpdateConstructionParts()
ConstructionMaterialType GetMaterialType(string part_name)
bool IsPartConstructed(string part_name)
void DestroyConnectedParts(string part_name)
void DestroyDebugCollisionBox()
bool CanUseToolToBuildPart(string part_name, ItemBase tool)
map< string, ref ConstructionPart > GetConstructionParts()
enum ConstructionMaterialType REPAIR_MATERIAL_PERCENTAGE
ConstructionBoxTrigger m_ConstructionBoxTrigger
bool HasDependentPart(string part_name)
void CollisionCheckData()
bool HasRequiredPart(string part_name)
void DestroyPartServer(Man player, string part_name, int action_id, bool destroyed_by_connected_part=false)
void InitVisuals()
void DismantlePartServer(notnull Man player, string part_name, int action_id)
ConstructionPart GetGateConstructionPart()
ConstructionMaterialType
Definition Construction.c:2
@ MATERIAL_STAIRS
Definition Construction.c:6
@ MATERIAL_METAL
Definition Construction.c:7
@ MATERIAL_WOOD
Definition Construction.c:5
@ MATERIAL_NONE
Definition Construction.c:3
@ MATERIAL_LOG
Definition Construction.c:4
@ MATERIAL_WIRE
Definition Construction.c:8
void CreateCollisionTrigger(string part_name, vector min_max[2], vector center)
void AddToConstructedParts(string part_name)
array< string > GetValidDepenentPartsArray(string part_name, array< string > recurs=null)
void Construction(BaseBuildingBase parent)
void RemoveFromConstructedParts(string part_name)
void UpdatePhysics()
void TakeMaterialsServer(string part_name, bool repairing=false)
bool CanUseToolToDismantlePart(string part_name, ItemBase tool)
bool ExceptionCheck(string part_name)
Exceptions from 'dependent parts' hierarchy are handled here.
ref map< string, ref ConstructionPart > m_ConstructionParts
void InitBaseState()
bool IsColliding(string part_name)
void DestroyMaterialsServer(Man player, string part_name)
bool HasMaterialWithQuantityAttached(string slot_name, float quantity)
string m_PartName
void SetLockOnAttachedMaterials(string part_name, bool lock_slot)
void DestroyCollisionTrigger()
void ShowConstructionPartPhysics(string part_name)
void HideConstructionPart(string part_name)
bool CanDismantlePart(string part_name, ItemBase tool)
override Widget Init()
Definition DayZGame.c:120
void SetParent(Object parent_obj)
Set parent of the Effect.
Definition Effect.c:378
Widget m_Parent
Definition SizeToChild.c:86
static bool GetDisableIsCollidingCheck()
void UpdateInsiders(int timeout)
void SetPartName(string part_name)
Definition Debug.c:14
static Shape DrawBox(vector pos1, vector pos2, int color=0x1fff7f7f)
Definition Debug.c:401
override bool LocalTakeToDst(notnull InventoryLocation src, notnull InventoryLocation dst)
Definition Man.c:810
override bool ServerTakeToDst(notnull InventoryLocation src, notnull InventoryLocation dst)
Definition Man.c:815
script counterpart to engine's class Inventory
Definition Inventory.c:79
static bool SetGroundPosByOwner(EntityAI owner, notnull EntityAI item, out InventoryLocation ground)
Definition Inventory.c:1212
InventoryLocation.
static bool IsBaseBuildingLogEnable()
Definition Debug.c:779
Trigger only accepting Object which IsMan()
Definition ManTrigger.c:3
Definition EnMath.c:7
static void SpawnConstructionMaterialPiles(notnull EntityAI entity, Man player, string cfg_path, string main_part_name, string damagezone_name="", bool is_base=false)
spawns material from any construction; 'player' parameter optional
void SetExtents(vector mins, vector maxs)
Set the size of the Trigger, avoid using SetCollisionBox directly.
Definition Trigger.c:116
array< ref TriggerInsider > GetInsiders()
Get the current TriggerInsider array, left for backwards compatibility, moved down from ManTrigger.
Definition Trigger.c:128
proto native CGame GetGame()
class DiagMenu Shape
don't call destructor directly. Use Destroy() instead
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
static proto float Max(float x, float y)
Returns bigger of two given values.
static proto float Floor(float f)
Returns floor of value.
static proto float AbsFloat(float f)
Returns absolute value.
proto native Widget GetParent()
Get parent of the Effect.
Definition Effect.c:389