Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_EditableGroupComponent.c
Go to the documentation of this file.
1[ComponentEditorProps(category: "GameScripted/Editor (Editables)", description: "", icon: "WBData/ComponentEditorProps/componentEditor.png")]
3{
4 //------------------------------------------------------------------------------------------------
5 static override bool GetEntitySourceBudgetCost(IEntityComponentSource editableEntitySource, out notnull array<ref SCR_EntityBudgetValue> budgetValues)
6 {
7 // Avoid fallback entityType cost
8 return true;
9 }
10
11 //------------------------------------------------------------------------------------------------
13 static bool GetGroupSourceBudgetCost(IEntityComponentSource editableEntitySource, out notnull array<ref SCR_EntityBudgetValue> budgetValues)
14 {
15 if (!editableEntitySource)
16 return false;
17
18 SCR_EditableGroupUIInfo editableEntityUIInfo = SCR_EditableGroupUIInfo.Cast(SCR_EditableGroupComponentClass.GetInfo(editableEntitySource));
19 if (editableEntityUIInfo)
20 return editableEntityUIInfo.GetGroupBudgetCost(budgetValues);
21
22 return !budgetValues.IsEmpty();
23 }
24}
25
27
30{
32
33 [RplProp(onRplName: "OnLeaderIdChanged")]
34 protected RplId m_LeaderId;
35
39
40 //~ Authority only, Forces spawned characters to be added to a specific vehicle position and will delete it if failed
41 protected ref array<ECompartmentType> m_aForceSpawnVehicleCompartments;
42
44
45 protected AIWaypointCycle m_CycleWaypoint;
46 protected bool m_bAreWaypointsCycled;
47 static ResourceName AI_WAYPOINT_CYCLE = "{35BD6541CBB8AC08}Prefabs/AI/Waypoints/AIWaypoint_Cycle.et";
48
49 //------------------------------------------------------------------------------------------------
50 override void OnDelete(IEntity owner)
51 {
52 super.OnDelete(owner);
53
54 //Check how many AI's were queued to be spawned but never did
55 const int missingAgents = m_Group.GetSpawnQueueSize();
56
57 //everything OK, all AI's got spawned
58 if(m_Group.GetSpawnQueueSize() == 0)
59 return;
60
61 //Group got deleted before all of its members got spawned
63
64 //free the budget we reserved for the AI's we did not spawn
66 if (!budgetComponent)
67 return;
68
69 SCR_EditableEntityCoreBudgetSetting aiBudget = budgetComponent.GetBudgetSetting(EEditableEntityBudget.AI);
70 if (aiBudget)
71 aiBudget.UnreserveBudget(missingAgents);
72 }
73
74 //------------------------------------------------------------------------------------------------
75 void EnableCycledWaypoints(bool enable)
76 {
77 if (enable == m_bAreWaypointsCycled || !IsServer())
78 return;
79
80 m_bAreWaypointsCycled = enable;
81 array<AIWaypoint> waypoints = {};
83 {
84 m_CycleWaypoint = AIWaypointCycle.Cast(GetGame().SpawnEntityPrefab(Resource.Load(SCR_EditableGroupComponent.AI_WAYPOINT_CYCLE)));
85
86 m_Group.GetWaypoints(waypoints);
87 m_CycleWaypoint.SetWaypoints(waypoints);
89 m_Group.AddWaypoint(m_CycleWaypoint);
90 }
91 else
92 {
93 m_CycleWaypoint.GetWaypoints(waypoints);
94 AddWaypoints(waypoints);
95 m_Group.RemoveWaypoint(m_CycleWaypoint);
96 delete m_CycleWaypoint;
97 }
98
100
102 }
103
104 //------------------------------------------------------------------------------------------------
105 protected void AddWaypoints(array<AIWaypoint> waypoints)
106 {
107 for (int i = 0, count = waypoints.Count(); i < count; i++)
108 {
109 m_Group.AddWaypoint(waypoints[i]);
110 }
111 }
112
113 //------------------------------------------------------------------------------------------------
115 {
116 array<AIWaypoint> waypoints = {};
117 m_Group.GetWaypoints(waypoints);
118 for (int i = 0, count = waypoints.Count(); i < count; i++)
119 {
120 m_Group.RemoveWaypointAt(0);
121 }
122 }
123
124 //------------------------------------------------------------------------------------------------
125 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
126 protected void EnableCycledWaypointsBroadcast(bool enable)
127 {
128 m_bAreWaypointsCycled = enable;
129 }
130
131 //------------------------------------------------------------------------------------------------
133 {
135 }
136
137
138 //------------------------------------------------------------------------------------------------
139// protected void OnEmpty()
140// {
141// }
142
143 //------------------------------------------------------------------------------------------------
144 protected void OnAgentAdded(AIAgent child)
145 {
146 if (!child)
147 return;
148
149 //--- Add newly joined soldier to group's layer
150 SCR_EditableEntityComponent editableChild = SCR_EditableEntityComponent.GetEditableEntity(child.GetControlledEntity());
151 if (editableChild)
152 editableChild.SetParentEntity(this);
153
154 //when the group gets created, we reserve budget for each of its agents
155 //when we spawn one agent, we inmediately free the budget.
156 //This is a bit sussy because if two groups merge, both of them will reserve budget
157 //but only one of them will be unreserving it.
159 if (!budgetComponent)
160 return;
161
162 SCR_EditableEntityCoreBudgetSetting aiBudget = budgetComponent.GetBudgetSetting(EEditableEntityBudget.AI);
163 if (aiBudget)
164 aiBudget.UnreserveBudget(1);
165 }
166
167 //------------------------------------------------------------------------------------------------
168 protected void OnAgentRemoved(SCR_AIGroup group, AIAgent child)
169 {
170 if (!child)
171 return;
172
173 //--- Remove the soldier who left from group's layer (only if the soldier is still this group's child)
174 SCR_EditableEntityComponent editableChild = SCR_EditableEntityComponent.GetEditableEntity(child.GetControlledEntity());
175 if (editableChild && editableChild.GetParentEntity() == this)
176 editableChild.SetParentEntity(null);
177 }
178
179 //------------------------------------------------------------------------------------------------
180 protected void OnLeaderChanged(AIAgent currentLeader, AIAgent prevLeader)
181 {
182 if (!currentLeader)
183 return;
184
185 //--- Update pointer to the leader on all clients
186 SCR_EditableEntityComponent editableLeader = SCR_EditableEntityComponent.GetEditableEntity(currentLeader.GetControlledEntity());
187 if (editableLeader)
188 {
189 m_Leader = editableLeader;
190 m_LeaderId = Replication.FindItemId(editableLeader);
191 Replication.BumpMe();
192 Refresh(); //--- Make the icon appear instantly
193 }
194 }
195
196 //------------------------------------------------------------------------------------------------
197 protected void OnCurrentWaypointChanged(AIWaypoint currentWP, AIWaypoint prevWP)
198 {
200 }
201
202 //------------------------------------------------------------------------------------------------
203 protected void OnWaypointCompleted(AIWaypoint wp)
204 {
206 }
207
208 //------------------------------------------------------------------------------------------------
209 protected void OnWaypointAdded(AIWaypoint wp)
210 {
211 if (wp != m_CycleWaypoint)
212 {
214 if (waypoint)
215 waypoint.SetParentEntity(this);
216 }
218 }
219
220 //------------------------------------------------------------------------------------------------
221 protected void OnWaypointRemoved(AIWaypoint wp)
222 {
223 if (wp != m_CycleWaypoint && !m_CycleWaypoint)
224 {
225 //--- Delete waypoints which were not assigned to another group
227 if (waypoint && waypoint.GetParentEntity() == this)
228 waypoint.Delete();
229 }
231 }
232
233 //------------------------------------------------------------------------------------------------
234 protected int GetGroupWaypoints(array<AIWaypoint> outWaypoints)
235 {
236 if (m_CycleWaypoint)
237 m_CycleWaypoint.GetWaypoints(outWaypoints);
238 else
239 m_Group.GetWaypoints(outWaypoints);
240
241 return outWaypoints.Count();
242 }
243
244 //------------------------------------------------------------------------------------------------
245 protected void ReindexWaypoints()
246 {
247 SCR_EditableWaypointComponent waypoint, currentWaypoint;
248 array<SCR_EditableWaypointComponent> waypoints = new array<SCR_EditableWaypointComponent>;
249
250 bool hasNonEditable, hasNull;
251 AIWaypoint aiWaypoint;
252 AIWaypoint currentAiWaypoint = m_Group.GetCurrentWaypoint();
253 array<AIWaypoint> aiWaypoints = {};
254 for (int i = 0, count = GetGroupWaypoints(aiWaypoints); i < count; i++)
255 {
256 aiWaypoint = aiWaypoints[i];
258 if (waypoint)
259 {
260 waypoints.Insert(waypoint);
261 if (aiWaypoint == currentAiWaypoint)
262 currentWaypoint = waypoint;
263 }
264 else if (aiWaypoint)
265 {
266 hasNonEditable = true;
267 }
268 else
269 {
270 hasNull = true;
271 }
272 }
273
274 //--- Show warning when the group mixes editable and non-editable waypoints. The latter will not be visible in the editor, potentially causing confusion.
275 if (hasNull)
276 {
277 Log("Group contains null waypoints!", true, LogLevel.WARNING);
278 }
279 else if (!waypoints.IsEmpty() && hasNonEditable)
280 {
281 Log("Group has a mix of editable and non-editable waypoints. Please use only one of those!", true, LogLevel.WARNING);
282 }
283
285 for (int i = 0, count = waypoints.Count(); i < count; i++)
286 {
287 waypoint = waypoints[i];
288 waypoint.SetWaypointIndex(i + 1, waypoint == currentWaypoint, prevWaypoint);
289 prevWaypoint = waypoint;
290 }
291 }
292
293 //------------------------------------------------------------------------------------------------
294 protected void OnLeaderIdChanged()
295 {
296 //--- Retrieve new leader from RplID
298 }
299
300 //------------------------------------------------------------------------------------------------
302 {
303 if (leader)
304 {
305 m_Leader = leader;
306 Refresh();
307 }
308 }
309
310 //------------------------------------------------------------------------------------------------
311 protected void OnFactionChanged(Faction faction)
312 {
313 Event_OnUIRefresh.Invoke();
314
315 //Call on faction changed of group children
316 if (m_Entities)
317 {
319 {
320 SCR_EditableCharacterComponent editableCharacter = SCR_EditableCharacterComponent.Cast(entity);
321 if (editableCharacter)
322 editableCharacter.OnFactionChanged();
323 }
324 }
325 }
326
327 //------------------------------------------------------------------------------------------------
329 {
330 //--- Create UI info for group instance, so we can change its symbol
331 if (!m_GroupInfo)
332 {
334 m_GroupInfo.CopyFrom(GetInfo());
336 }
337
338 m_GroupInfo.SetInstance(symbol, name);
339
340 Event_OnUIRefresh.Invoke();
341 }
342
343 //------------------------------------------------------------------------------------------------
347 {
348 return m_Group;
349 }
350
351 //------------------------------------------------------------------------------------------------
353 {
354 return Event_OnUIRefresh;
355 }
356
357 //------------------------------------------------------------------------------------------------
359 {
360 Faction faction;
361
362 if (m_Leader)
363 faction = m_Leader.GetFaction();
364
365 if (!faction)
366 faction = m_Group.GetFaction();
367
368 return faction;
369 }
370
371 //------------------------------------------------------------------------------------------------
373 {
374 return this;
375 }
376
377 //------------------------------------------------------------------------------------------------
379 {
380 return m_Leader;
381 }
382
383 //------------------------------------------------------------------------------------------------
387 {
388 if (!m_Group)
389 return 0;
390
391 return m_Group.GetPlayerAndAgentCount();
392 }
393
394 //------------------------------------------------------------------------------------------------
398 {
399 int count = 0;
400 /*set <SCR_EditableEntityComponent> groupChildren = new set <SCR_EditableEntityComponent>;
401 GetChildren(groupChildren, true);*/
402
403 if (m_Entities)
404 {
406 {
407 //--- TODO: unsure why child is null
408 if (child && child.GetEntityType() == EEditableEntityType.WAYPOINT)
409 count++;
410 }
411 }
412
413 return count;
414 }
415
416 //------------------------------------------------------------------------------------------------
419 {
420 if (!m_Group)
421 return;
422
423 array<AIWaypoint> aiWaypoints = new array<AIWaypoint>;
424 for (int i = 0, count = GetGroupWaypoints(aiWaypoints); i < count; i++)
425 {
427 if (waypoint)
428 {
429 waypoint.Delete();
430 }
431 else
432 {
433 //--- Unassign non-editable waypoint, but don't delete it (multiple groupls may be assigned to it)
434 m_Group.RemoveWaypoint(aiWaypoints[i]);
435 }
436 }
437 }
438
439 //------------------------------------------------------------------------------------------------
440 override bool GetEntityBudgetCost(out notnull array<ref SCR_EntityBudgetValue> outBudgets, IEntity owner = null)
441 {
442 return true;
443 }
444
445 // Will have the correct value only on Authority
446 //------------------------------------------------------------------------------------------------
447 void GetRuntimeBudgetCost(out notnull array<ref SCR_EntityBudgetValue> outBudgets)
448 {
449 if (!m_Group)
450 return;
451
452 array<AIAgent> agentsInGroup = {};
453 SCR_EditableCharacterComponent editableCharacter;
454 m_Group.GetAgents(agentsInGroup);
455
456 foreach (AIAgent agent : agentsInGroup)
457 {
458 IEntity controlledEntity = agent.GetControlledEntity();
459
460 if (!controlledEntity)
461 continue;
462
463 editableCharacter = SCR_EditableCharacterComponent.Cast(controlledEntity.FindComponent(SCR_EditableCharacterComponent));
464
465 array<ref SCR_EntityBudgetValue> characterBudget = {};
466 editableCharacter.GetEntityBudgetCost(characterBudget);
467
468 SCR_EntityBudgetValue.MergeBudgetCosts(outBudgets, characterBudget);
469 }
470 }
471
472 //------------------------------------------------------------------------------------------------
473 void GetPrefabBudgetCost(out notnull array<ref SCR_EntityBudgetValue> outBudgets)
474 {
475 SCR_AIGroup aiGroup = SCR_AIGroup.Cast(GetOwner());
476 if (!aiGroup)
477 return;
478
479 array<ref SCR_EntityBudgetValue> groupBudgetCosts = {};
480 ResourceName resName = GetOwner().GetPrefabData().GetPrefabName();
481 IEntityComponentSource componentSourceC;
482
483 Resource prefabResource = Resource.Load(resName);
484 if (!prefabResource)
485 return;
486
487 BaseResourceObject baseResourceC = prefabResource.GetResource();
488 if (!baseResourceC)
489 return;
490
491 IEntitySource entitySourceC = baseResourceC.ToEntitySource();
492 if (!entitySourceC)
493 return;
494
495 for (int i = 0, count = entitySourceC.GetComponentCount(); i < count; i++)
496 {
497 componentSourceC = entitySourceC.GetComponent(i);
498 if (componentSourceC.GetClassName() == ((typename)SCR_EditableGroupComponent).ToString())
499 {
500 array<ref SCR_EntityBudgetValue> gropBudgetCosts = {};
501 SCR_EditableGroupComponentClass.GetGroupSourceBudgetCost(componentSourceC, gropBudgetCosts);
502
503 SCR_EntityBudgetValue.MergeBudgetCosts(outBudgets, gropBudgetCosts);
504 }
505 }
506 }
507
508 //------------------------------------------------------------------------------------------------
509 override bool CanDuplicate(out notnull set<SCR_EditableEntityComponent> outRecipients)
510 {
511 return false;
512 }
513
514 //------------------------------------------------------------------------------------------------
516 {
517 if (!m_Leader)
518 return m_Entities[index]; //--- No leader, use default method
519 if (index == 0)
520 return m_Leader; //--- Return leader as the first item (needed for session saving - SCR_EditableEntityStruct)
521 else if (index <= m_Entities.Find(m_Leader))
522 return m_Entities[index - 1]; //--- Before leader, push by one
523 else
524 return m_Entities[index]; //--- After leader, use default method
525 }
526
527 //------------------------------------------------------------------------------------------------
528 override bool GetPos(out vector pos)
529 {
530 if (!m_Leader)
531 return false;
532
533 if (!m_Leader.GetPos(pos))
534 return false;
535
536 pos += GetIconPos();
537 return true;
538 }
539
540 //------------------------------------------------------------------------------------------------
541 override bool CanDestroy()
542 {
543 set<SCR_EditableEntityComponent> children = new set<SCR_EditableEntityComponent>();
544 GetChildren(children, true);
545
546 foreach (SCR_EditableEntityComponent child : children)
547 {
548 if (child.CanDestroy())
549 return true;
550 }
551
552 return false;
553 }
554
555 //------------------------------------------------------------------------------------------------
556 override bool IsDestroyed()
557 {
558 set<SCR_EditableEntityComponent> children = new set<SCR_EditableEntityComponent>();
559 GetChildren(children, true);
560
561 foreach (SCR_EditableEntityComponent child : children)
562 {
563 if (!child.IsDestroyed())
564 return false;
565 }
566
567 return true;
568 }
569
570 //------------------------------------------------------------------------------------------------
573 {
574 RplComponent rpl = GetRplComponent();
575 if (!m_Group || !rpl || rpl.IsProxy()) // Only the Authority has the proper data needed to determine visibility
576 return;
577
578 bool isGroupEmpty = m_Group.GetAgentsCount() == 0;
579 SetVisible(!isGroupEmpty);
580 }
581
582
583 //------------------------------------------------------------------------------------------------
584 override bool RplSave(ScriptBitWriter writer)
585 {
586 if (!super.RplSave(writer))
587 return false;
588
589 writer.WriteBool(m_bAreWaypointsCycled);
590
591 return true;
592 }
593
594 //------------------------------------------------------------------------------------------------
595 override bool RplLoad(ScriptBitReader reader)
596 {
597 if (!super.RplLoad(reader))
598 return false;
599
600 int areWaypointsCycled;
601 reader.ReadBool(areWaypointsCycled);
602 EnableCycledWaypointsBroadcast(areWaypointsCycled);
603
604 return true;
605 }
606
607 //------------------------------------------------------------------------------------------------
608 override bool Destroy(int editorPlayerID)
609 {
610 if (!IsServer())
611 return false;
612
613 set<SCR_EditableEntityComponent> children = new set<SCR_EditableEntityComponent>();
614 GetChildren(children, true);
615
616 bool isDestroyed = true;
617
618 foreach (SCR_EditableEntityComponent child : children)
619 {
620 isDestroyed &= child.Destroy(editorPlayerID);
621 }
622
623 return isDestroyed;
624 }
625
626 //------------------------------------------------------------------------------------------------
627// override bool CanSetParent(SCR_EditableEntityComponent parentEntity)
628// {
629// if (!parentEntity)
630// return true;
631//
632// EEditableEntityType type = parentEntity.GetEntityType();
633// return super.CanSetParent(parentEntity) || type == EEditableEntityType.CHARACTER || type == EEditableEntityType.GROUP || type == EEditableEntityType.VEHICLE;
634// }
635
636 //------------------------------------------------------------------------------------------------
637 //~ Authority Only. When spawned will force characters of group into vehicle position
638 override void ForceVehicleCompartments(notnull array<ECompartmentType> forceVehicleCompartments)
639 {
640 if (forceVehicleCompartments.IsEmpty())
641 return;
642
644
645 foreach (ECompartmentType compartment: forceVehicleCompartments)
646 m_aForceSpawnVehicleCompartments.Insert(compartment);
647 }
648
649 //------------------------------------------------------------------------------------------------
650 override void OnParentEntityChanged(SCR_EditableEntityComponent parentEntity, SCR_EditableEntityComponent parentEntityPrev, bool changedByUser)
651 {
652 EEditableEntityType parentType;
653 if (parentEntity) parentType = parentEntity.GetEntityType();
654
655 switch (parentType)
656 {
657 case EEditableEntityType.GROUP:
658 case EEditableEntityType.CHARACTER:
659 case EEditableEntityType.VEHICLE:
660 {
661 if (!IsServer())
662 break;
663
664 set<SCR_EditableEntityComponent> children = new set<SCR_EditableEntityComponent>;
665 GetChildren(children, true);
666 if (children.IsEmpty() && !parentEntityPrev)
667 {
668 //--- Group is still empty after placing. Wait a bit before attempting to move soldiers under another parent (to prevent endless loop, do it only once by overriding parentEntityPrev)
669 GetGame().GetCallqueue().CallLater(OnParentEntityChanged, 1, false, parentEntity, parentEntity, changedByUser);
670 }
671 else
672 {
673 foreach (SCR_EditableEntityComponent child: children)
674 {
675 if (child.GetEntityType() == EEditableEntityType.CHARACTER)
676 {
677 //~ Force children in vehicle position if any are assigned
679 child.ForceVehicleCompartments(m_aForceSpawnVehicleCompartments);
680
681 child.SetParentEntity(parentEntity);
682 }
683 }
684
685 //~ Clear force positions
688 }
689 break;
690 }
691 default:
692 {
693 super.OnParentEntityChanged(parentEntity, parentEntityPrev, changedByUser);
694 break;
695 }
696 }
697 }
698
699 //------------------------------------------------------------------------------------------------
700 override void OnCreatedServer(notnull SCR_PlacingEditorComponent placedEditorComponent)
701 {
702 super.OnCreatedServer(placedEditorComponent);
703
704 m_PlacedEditorComponent = placedEditorComponent;
705 if (m_Group == null)
706 return;
707
708 int numberOfMembersToSpawn = m_Group.GetNumberOfMembersToSpawn();
709 if (numberOfMembersToSpawn < 1)
710 return;
711
712 m_Group.GetOnAllDelayedEntitySpawned().Insert(OnAllMembersSpawned);
713 m_PlacedEditorComponent.SetPlacingBlocked(true);
714
716 if (!budgetComponent)
717 return;
718
719 SCR_EditableEntityCoreBudgetSetting aiBudget = budgetComponent.GetBudgetSetting(EEditableEntityBudget.AI);
720 if (aiBudget)
721 aiBudget.ReserveBudget(numberOfMembersToSpawn);
722 }
723
724 //------------------------------------------------------------------------------------------------
727 {
729 return;
730
732 }
733
734 //------------------------------------------------------------------------------------------------
736 {
738 m_PlacedEditorComponent.SetPlacingBlocked(false);
739
740 m_Group.GetOnAllDelayedEntitySpawned().Remove(OnAllMembersSpawned);
741 }
742
743 //------------------------------------------------------------------------------------------------
744 override void OnChildEntityChanged(SCR_EditableEntityComponent child, bool isAdded)
745 {
746 if (!IsServer())
747 {
748 if (isAdded && Replication.FindItemId(child) == m_LeaderId)
749 SetLeader(child);
750
751 return;
752 }
753
754 switch (child.GetEntityType())
755 {
756 case EEditableEntityType.CHARACTER:
757 {
758 SCR_EditableCharacterComponent childCharacter = SCR_EditableCharacterComponent.Cast(child);
759 if (!childCharacter)
760 return;
761
762 AIAgent childAgent = childCharacter.GetAgent();
763 if (!childAgent)
764 return;
765
766 if (isAdded)
767 {
768 m_Group.AddAgent(childAgent);
769
770 //--- Make sure newly joined member is on the same faction
771 Faction groupFaction = GetFaction();
772 if (groupFaction && groupFaction != childCharacter.GetFaction())
773 {
774 FactionAffiliationComponent charactedFactionComponent = FactionAffiliationComponent.Cast(childCharacter.GetOwner().FindComponent(FactionAffiliationComponent));
775 if (charactedFactionComponent)
776 charactedFactionComponent.SetAffiliatedFaction(groupFaction);
777
778 //--- ToDo: Notify player that this is sus!
779 }
780 }
781 else
782 {
783 m_Group.RemoveAgent(childAgent);
784 }
785
786 break;
787 }
788 case EEditableEntityType.WAYPOINT:
789 {
790 AIWaypoint waypoint = AIWaypoint.Cast(child.GetOwner());
791 if (!waypoint)
792 return;
793
794 array<AIWaypoint> waypoints = {};
795 if (isAdded)
796 {
797 //--- Check for duplicates, one waypoint can be added multiple times
798 if (m_CycleWaypoint)
799 {
800 m_CycleWaypoint.GetWaypoints(waypoints);
801 if (!waypoints.Contains(waypoint))
802 {
803 waypoints.Insert(waypoint);
804 m_CycleWaypoint.SetWaypoints(waypoints);
805
806 for (int i = 0, count = waypoints.Count(); i < count; i++)
807 {
808 m_Group.RemoveWaypointAt(0);
809 }
810
811 m_Group.AddWaypoint(m_CycleWaypoint);
812 }
813 }
814 else
815 {
816 m_Group.GetWaypoints(waypoints);
817 if (!waypoints.Contains(waypoint))
818 m_Group.AddWaypoint(waypoint);
819 }
820 }
821 else
822 {
823 if (m_CycleWaypoint)
824 {
825 m_CycleWaypoint.GetWaypoints(waypoints);
826 int waypointID = waypoints.Find(waypoint);
827 if (waypointID != -1)
828 {
829 waypoints.Remove(waypointID);
830 m_CycleWaypoint.SetWaypoints(waypoints);
831 }
832 }
833 else
834 {
835 m_Group.RemoveWaypoint(waypoint);
836 }
837 }
838
839 break;
840 }
841 }
842 }
843
844 //------------------------------------------------------------------------------------------------
845 override void OnPostInit(IEntity owner)
846 {
847 if (DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_ENTITIES_DISABLE))
848 return;
849
850 super.OnPostInit(owner);
851
852 if (m_Group)
853 {
854 //--- Track group's events (no need to remove them, the group gets detsroyed when the component does)
855 if (IsServer())
856 {
857 //m_Group.GetOnEmpty().Insert(OnEmpty);
858 m_Group.GetOnAgentAdded().Insert(OnAgentAdded);
859 m_Group.GetOnAgentRemoved().Insert(OnAgentRemoved);
860 m_Group.GetOnLeaderChanged().Insert(OnLeaderChanged);
861 m_Group.GetOnCurrentWaypointChanged().Insert(OnCurrentWaypointChanged);
862 m_Group.GetOnWaypointCompleted().Insert(OnWaypointCompleted);
863 m_Group.GetOnWaypointAdded().Insert(OnWaypointAdded);
864 m_Group.GetOnWaypointRemoved().Insert(OnWaypointRemoved);
865 }
866
867 //On faction changed
868 m_Group.GetOnFactionChanged().Insert(OnFactionChanged);
869
870 SCR_GroupIdentityComponent groupIdentity = SCR_GroupIdentityComponent.Cast(owner.FindComponent(SCR_GroupIdentityComponent));
871 if (groupIdentity)
872 groupIdentity.GetOnIdentityChange().Insert(OnIdentityChange);
873 }
874 }
875
876 //------------------------------------------------------------------------------------------------
877 // constructor
882 {
883 m_Group = SCR_AIGroup.Cast(ent);
884
885 if (m_CycleWaypoint)
886 delete m_CycleWaypoint;
887
888 //--- Check if attached to correct entity type. Needs to be SCR_AIGroup, not just AIGroup, because it requires certain events.
889 if (!m_Group)
890 Print("SCR_EditableGroupComponent must be on SCR_AIGroup!", LogLevel.ERROR);
891
892 //--- Check if entity type was configured correctly. Only in Workbench, no need to read sources in run-time.
893 if (SCR_Global.IsEditMode(ent) && SCR_EditableGroupComponentClass.GetEntityType(src) != EEditableEntityType.GROUP)
894 Print("SCR_EditableGroupComponent entity type must be set to GROUP!", LogLevel.ERROR);
895 }
896}
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
ECompartmentType
EEditableEntityBudget
ArmaReforgerScripted GetGame()
Definition game.c:1398
SCR_AIGroupSettingsComponentClass m_Group
void OnAgentRemoved(AIGroup group, AIAgent agent)
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
SCR_CacheNoteComponentClass ScriptComponentClass RplProp()] protected ref array< string > m_aLines
void OnFactionChanged(Faction faction)
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
override void OnParentEntityChanged(SCR_EditableEntityComponent parentEntity, SCR_EditableEntityComponent parentEntityPrev, bool changedByUser)
void GetPrefabBudgetCost(out notnull array< ref SCR_EntityBudgetValue > outBudgets)
SCR_AIGroup GetAIGroupComponent()
void RemoveAllWaypointsFromGroup()
void EnableCycledWaypointsBroadcast(bool enable)
void ReindexWaypoints()
void OnIdentityChange(SCR_MilitarySymbol symbol, LocalizedString name)
ref SCR_EditableGroupUIInfo m_GroupInfo
ref array< ECompartmentType > m_aForceSpawnVehicleCompartments
SCR_EditableEntityComponent m_Leader
void OnAfterAllMembersSpawned()
void OnWaypointRemoved(AIWaypoint wp)
int GetWaypointCount()
void AddWaypoints(array< AIWaypoint > waypoints)
AIWaypointCycle m_CycleWaypoint
bool m_bAreWaypointsCycled
SCR_PlacingEditorComponent m_PlacedEditorComponent
void OnLeaderIdChanged()
void SetLeader(SCR_EditableEntityComponent leader)
void OnAllMembersSpawned(SCR_AIGroup group)
void GetRuntimeBudgetCost(out notnull array< ref SCR_EntityBudgetValue > outBudgets)
void SCR_EditableGroupComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
void EnableCycledWaypoints(bool enable)
bool AreCycledWaypointsEnabled()
void ClearWaypoints()
Remove all waypoints from the group.
ref ScriptInvoker Event_OnUIRefresh
int GetGroupWaypoints(array< AIWaypoint > outWaypoints)
void HideIfEmpty()
void SCR_EditableWaypointComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
override SCR_UIInfo GetInfo()
ref SCR_SortedArray< SCR_EditableEntityComponent > m_Entities
void OnAgentAdded()
override void Log()
Diagnostic and developer menu system.
Definition DiagMenu.c:18
void Rpc(func method, void p0=NULL, void p1=NULL, void p2=NULL, void p3=NULL, void p4=NULL, void p5=NULL, void p6=NULL, void p7=NULL)
proto external Managed FindComponent(typename typeName)
proto external EntityPrefabData GetPrefabData()
Main replication API.
Definition Replication.c:14
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
Replication item identifier.
Definition RplId.c:14
SCR_EditableEntityCoreBudgetSetting GetBudgetSetting(EEditableEntityBudget budgetType)
void GetChildren(out notnull set< SCR_EditableEntityComponent > entities, bool onlyDirect=false, bool skipIgnored=false)
SCR_EditableEntityComponent GetChild(int index)
void ForceVehicleCompartments(notnull array< ECompartmentType > forceVehicleCompartments)
void OnParentEntityChanged(SCR_EditableEntityComponent parentEntity, SCR_EditableEntityComponent parentEntityPrev, bool changedByUser)
SCR_EditableEntityComponent GetAIEntity()
static SCR_EditableEntityComponent GetEditableEntity(IEntity owner)
EEditableEntityType GetEntityType(IEntity owner=null)
SCR_EditableEntityComponent SetParentEntity(SCR_EditableEntityComponent parentEntity, bool changedByUser=false)
override bool RplLoad(ScriptBitReader reader)
void OnChildEntityChanged(SCR_EditableEntityComponent child, bool isAdded)
bool CanDuplicate(out notnull set< SCR_EditableEntityComponent > outRecipients)
override bool RplSave(ScriptBitWriter writer)
void OnCreatedServer(notnull SCR_PlacingEditorComponent placedEditorComponent)
bool GetEntityBudgetCost(out notnull array< ref SCR_EntityBudgetValue > outBudgets, IEntity owner=null)
SCR_EditableEntityComponent GetParentEntity()
SCR_EditableEntityComponent GetAIGroup()
bool GetGroupBudgetCost(out notnull array< ref SCR_EntityBudgetValue > outBudgets)
static bool IsEditMode()
Definition Functions.c:1566
proto external GenericEntity GetOwner()
Get owner entity.
void OnAgentAdded(AIAgent agent)
void OnWaypointAdded(AIWaypoint wp)
void OnCurrentWaypointChanged(AIWaypoint _currentWp, AIWaypoint _prevWp)
void OnWaypointCompleted(AIWaypoint wp)
void OnLeaderChanged(AIAgent currentLeader, AIAgent prevLeader)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
EEditableEntityType
Defines type of SCR_EditableEntityComponent. Assigned automatically based on IEntity inheritance.
void RplRpc(RplChannel channel, RplRcver rcver, RplCondition condition=RplCondition.None, string customConditionName="")
Definition EnNetwork.c:95
RplRcver
Definition RplRcver.c:59
RplChannel
Communication channel. Reliable is guaranteed to be delivered. Unreliable not.
Definition RplChannel.c:14
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134