14 static int GetMembers(IEntitySource entitySource, out array<ResourceName> outPrefabs, out array<vector> outOffsets)
17 if (!entitySource || !entitySource.GetClassName().ToType().IsInherited(
SCR_AIGroup))
return false;
19 ArmaReforgerScripted game =
GetGame();
22 AIWorld aiWorld = game.GetAIWorld();
23 if (!aiWorld)
return 0;
26 AIFormationDefinition formation;
27 IEntityComponentSource componentSource;
28 for (
int i = 0, count = entitySource.GetComponentCount(); i < count; i++)
30 componentSource = entitySource.GetComponent(i);
31 if (componentSource.GetClassName().ToType().IsInherited(AIFormationComponent))
34 componentSource.Get(
"DefaultFormation", formationName);
35 formation = aiWorld.GetFormation(formationName);
39 if (!formation)
return 0;
42 entitySource.Get(
"m_aUnitPrefabSlots", outPrefabs);
46 int count = outPrefabs.Count();
47 for (
int i = 0; i < count; i++)
49 outOffsets.Insert(formation.GetOffsetPosition(i));
60 ResourceName resourceName;
73 [
Attribute(uiwidget: UIWidgets.ResourceAssignArray,
desc:
"Entities in group non-ai included",
params:
"et",
category:
"Group Members")]
74 ref array<ResourceName> m_aUnitPrefabSlots;
76 [
Attribute(defvalue:
"1",
desc:
"When true, group members will be spawned above terrain, offset by group's ATL height.\nWhen false, group members will be levelled horizontally with the group.",
category:
"Group Members")]
77 private bool m_bSnapToTerrain;
79 [
Attribute(
"", UIWidgets.EditBox,
"List of Waypoint names found in the level",
category:
"Group Waypoints")]
80 ref array<string> m_aStaticWaypoints;
82 [
Attribute(defvalue:
"", UIWidgets.Object,
desc:
"Waypoints that should be spawned from prefabs",
category:
"Group Waypoints")]
83 ref array<ref SCR_WaypointPrefabLocation> m_aSpawnedWaypoints;
85 [
Attribute(defvalue:
"", UIWidgets.EditBox,
desc:
"List of vehicles to use for movement",
category:
"Group Vehicles")]
86 ref array<string> m_aStaticVehicles;
88 [
Attribute(defvalue:
"1",
desc:
"When true, group members will be spawned durin OnInit, if false spawning must be called manually calling SpawnUnits()",
category:
"Group Members")]
89 private bool m_bSpawnImmediately;
91 [
Attribute(defvalue:
"0", UIWidgets.EditBox,
desc:
"Delay between spawns of individual members (ms)",
category:
"Group Members")]
92 protected int m_fMemberSpawnDelay;
94 [
Attribute(defvalue:
"1", UIWidgets.EditBox,
desc:
"When enabled, the group will be deleted when its last member dies or is deleted.\nThis will *not* delete the group when it starts empty.",
category:
"Group")]
95 protected bool m_bDeleteWhenEmpty;
97 protected static bool s_bIgnoreSnapToTerrain;
98 protected static bool s_bIgnoreSpawning;
100 protected ref array<IEntity> m_aSceneGroupUnitInstances;
101 protected ref array<IEntity> m_aSceneWaypointInstances;
102 protected ref array<IEntity> m_aUsableVehicles;
103 protected ref array<BaseCompartmentSlot> m_aAllocatedCompartments;
105 protected int m_iMaxUnitsToSpawn =
int.MAX;
106 protected ref ScriptInvoker Event_OnInit =
new ScriptInvoker;
108 protected ref ScriptInvoker Event_OnAgentAdded =
new ScriptInvoker;
109 protected ref ScriptInvoker Event_OnAgentRemoved =
new ScriptInvoker;
110 protected ref ScriptInvoker Event_OnLeaderChanged =
new ScriptInvoker;
111 protected ref ScriptInvoker Event_OnCurrentWaypointChanged =
new ScriptInvoker;
112 protected ref ScriptInvoker Event_OnWaypointCompleted =
new ScriptInvoker;
113 protected ref ScriptInvoker Event_OnWaypointAdded =
new ScriptInvoker;
114 protected ref ScriptInvoker Event_OnWaypointRemoved =
new ScriptInvoker;
115 protected ref ScriptInvoker Event_OnFactionChanged =
new ScriptInvoker;
117 protected ref ScriptInvoker m_OnGroupMemberStateChange =
new ScriptInvoker();
119 protected int m_iNumOfMembersToSpawn;
121 protected ref array<int> m_aAgentIDQueue = {};
125 protected int m_iGroupRadioFrequency;
128 protected int m_iMaxMembers;
131 protected bool m_bPlayable, m_bPrivate;
134 protected bool m_bDeleteIfNoPlayer;
136 protected int m_iGroupID = -1;
137 protected int m_iLeaderID = -1;
141 protected int m_iDescriptionAuthorID = 0;
142 protected int m_iNameAuthorID = 0;
145 protected string m_sCustomName =
"";
146 protected string m_sCustomDescription =
"";
147 protected ref array<int> m_aPlayerIDs = {};
148 protected ref array<int> m_aDisconnectedPlayerIDs;
149 protected static ref ScriptInvoker s_OnPlayerAdded =
new ScriptInvoker();
150 protected static ref ScriptInvoker s_OnPlayerRemoved =
new ScriptInvoker();
151 protected static ref ScriptInvoker<int, int> s_OnPlayerLeaderChanged =
new ScriptInvoker();
152 protected static ref ScriptInvoker s_OnPrivateGroupChanged =
new ScriptInvoker();
153 protected static ref ScriptInvoker<SCR_AIGroup> s_OnCustomNameChanged =
new ScriptInvoker();
154 protected static ref ScriptInvoker s_OnFrequencyChanged =
new ScriptInvoker();
155 protected static ref ScriptInvoker s_OnMaxMembersChanged =
new ScriptInvoker();
156 protected static ref ScriptInvoker s_OnCustomDescChanged =
new ScriptInvoker();
157 protected static ref ScriptInvoker s_OnFlagSelected =
new ScriptInvoker();
158 protected static ref ScriptInvoker s_OnJoinPrivateGroupRequest =
new ScriptInvoker();
159 protected static ref ScriptInvoker s_OnJoinPrivateGroupConfirm =
new ScriptInvoker();
160 protected static ref ScriptInvoker s_OnJoinPrivateGroupCancel =
new ScriptInvoker();
162 protected ref array<int> m_aRequesterIDs = {};
163 protected ref array<int> m_aDeniedRequesters = {};
166 protected int m_iDeployedRadioCount = 0;
171 protected ref array<SCR_ChimeraCharacter> m_aAIMembers = {};
174 protected ref array<ref SCR_AIGroup_DelayedSpawn> m_delayedSpawnList = {};
175 protected ref ScriptInvokerBase<ScriptInvokerAIGroup> Event_OnAllDelayedEntitySpawned;
178 int GetNumberOfMembersToSpawn()
180 return m_iNumOfMembersToSpawn;
184 void SetNumberOfMembersToSpawn(
int number)
186 m_iNumOfMembersToSpawn = number;
190 protected override void EOnFrame(IEntity owner,
float timeSlice)
193 if (m_delayedSpawnList.IsEmpty())
200 int spawnIndex = m_delayedSpawnList.Count() - 1;
201 if (SpawnDelayedGroupMember(spawnIndex))
202 m_delayedSpawnList.Remove(spawnIndex);
205 if (m_delayedSpawnList.IsEmpty() && Event_OnAllDelayedEntitySpawned)
206 Event_OnAllDelayedEntitySpawned.Invoke(
this);
214 bool SpawnDelayedGroupMember(
int spawnIndex)
216 return SpawnGroupMember(
217 m_delayedSpawnList.Get(spawnIndex).snapToTerrain,
218 m_delayedSpawnList.Get(spawnIndex).index,
219 m_delayedSpawnList.Get(spawnIndex).resourceName,
220 m_delayedSpawnList.Get(spawnIndex).editMode,
226 void SpawnAllImmediately()
228 for (
int spawnIndex = m_delayedSpawnList.Count() - 1; spawnIndex >= 0; spawnIndex--)
229 SpawnDelayedGroupMember(spawnIndex);
231 m_delayedSpawnList.Clear();
235 void BeginDelayedSpawn()
237 SetEventMask(EntityEvent.FRAME);
242 world.RegisterEntityToBeUpdatedWhileGameIsPaused(
this);
246 void EndDelayedSpawn()
248 ClearEventMask(EntityEvent.FRAME);
252 world.UnregisterEntityToBeUpdatedWhileGameIsPaused(
this);
256 bool HasRequesterID(
int id)
258 return m_aRequesterIDs.Contains(
id);
262 void RemoveRequester(
int playerID)
264 if (!m_aRequesterIDs.Contains(playerID))
267 RPC_DoRemoveRequester(playerID);
268 Rpc(RPC_DoRemoveRequester, playerID);
272 int GetDeniedRequesters(out array<int> valueArray)
274 return valueArray.Copy(m_aDeniedRequesters);
278 void AddDeniedRequester(
int playerID)
280 if (m_aDeniedRequesters.Contains(playerID))
283 RPC_DoAddDeniedRequester(playerID);
284 Rpc(RPC_DoAddDeniedRequester, playerID);
288 void ClearRequesters()
290 RPC_DoClearRequesterIDs();
291 Rpc(RPC_DoClearRequesterIDs);
295 void ClearDeniedRequester()
297 RPC_DoClearDeniedRequester();
298 Rpc(RPC_DoClearDeniedRequester);
302 int GetRequesterIDs(out array<int> valueArray)
304 return valueArray.Copy(m_aRequesterIDs);
308 void AddRequester(
int playerID)
310 if (m_aRequesterIDs.Contains(playerID))
313 RPC_DoAddRequester(playerID);
314 Rpc(RPC_DoAddRequester, playerID);
318 void SetFlagIsFromImageSet(
bool value)
323 m_UiInfo.SetFlagIsFromImageSet(value);
327 void SetCustomGroupFlag(ResourceName flag)
332 m_UiInfo.SetGroupFlag(flag);
336 bool GetFlagIsFromImageSet()
341 bool flagIsFromSet = m_UiInfo.GetFlagIsFromImageSet();
342 return flagIsFromSet;
346 ResourceName GetGroupFlag()
351 ResourceName name = m_UiInfo.GetGroupFlag();
356 static ScriptInvoker GetOnFlagSelected()
358 return s_OnFlagSelected;
362 static ScriptInvoker GetOnJoinPrivateGroupRequest()
364 return s_OnJoinPrivateGroupRequest;
368 static ScriptInvoker GetOnJoinPrivateGroupConfirm()
370 return s_OnJoinPrivateGroupConfirm;
374 static ScriptInvoker GetOnJoinPrivateGroupCancel()
376 return s_OnJoinPrivateGroupCancel;
380 bool IsPlayerInGroup(
int playerID)
386 bool IsPlayerLeader(
int playerID)
388 return playerID == m_iLeaderID;
399 void SetPrivate(
bool isPrivate)
401 RPC_SetPrivate(isPrivate);
402 Rpc(RPC_SetPrivate, isPrivate);
413 bool GetDeleteIfNoPlayer()
415 return m_bDeleteIfNoPlayer;
420 void SetCanDeleteIfNoPlayer(
bool deleteEmpty)
422 m_bDeleteIfNoPlayer = deleteEmpty;
445 int GetPlayerAndAgentCount(
bool checkMasterAndSlaves =
false)
447 if (!checkMasterAndSlaves)
448 return GetPlayerCount() + GetAgentsCount();
451 return GetPlayerCount(
true) + GetAgentCountIncludingMasterAndSlaves();
458 int GetAgentCountIncludingMasterAndSlaves()
460 int totalAgentCount = GetAgentsCount();
464 totalAgentCount += aiGroup.GetAgentsCount();
466 aiGroup = GetMaster();
468 totalAgentCount += aiGroup.GetAgentsCount();
470 return totalAgentCount;
478 int GetTotalAgentCount()
480 int totalGroupCount = GetAgentsCount();
484 totalGroupCount += aiGroup.GetAgentsCount();
486 aiGroup = GetMaster();
488 totalGroupCount += aiGroup.GetAgentsCount();
490 return totalGroupCount;
498 int GetTotalPlayerCount()
500 int totalGroupCount = GetPlayerCount();
504 totalGroupCount += aiGroup.GetPlayerCount();
506 aiGroup = GetMaster();
508 totalGroupCount += aiGroup.GetPlayerCount();
510 return totalGroupCount;
515 void SetGroupFlag(
int flagIndex,
bool isFromImageset)
520 RPC_DoSetGroupFlag(flagIndex, isFromImageset);
521 Rpc(RPC_DoSetGroupFlag, flagIndex, isFromImageset);
525 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
526 void RPC_DoSetGroupFlag(
int flagIndex,
bool isFromImageset)
536 m_UiInfo.SetFlagIsFromImageSet(isFromImageset);
541 m_UiInfo.SetGroupFlag(scrFaction.GetFlagName(flagIndex));
545 array<ResourceName> textures = {};
546 scrFaction.GetGroupFlagTextures(textures);
548 if (textures.IsIndexValid(flagIndex))
549 m_UiInfo.SetGroupFlag(textures[flagIndex]);
552 s_OnFlagSelected.Invoke();
556 void SetCustomName(
string name,
int authorID)
558 RPC_DoSetCustomName(name, authorID);
559 Rpc(RPC_DoSetCustomName, name, authorID);
563 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
564 void RPC_DoSetCustomName(
string name,
int authorID)
567 m_iNameAuthorID = authorID;
568 s_OnCustomNameChanged.Invoke(
this);
573 void SetCustomDescription(
string desc,
int authorID)
575 RPC_DoSetCustomDescription(
desc, authorID);
576 Rpc(RPC_DoSetCustomDescription,
desc, authorID);
580 void SetMaxGroupMembers(
int value)
582 RPC_DoSetMaxGroupMembers(value);
583 Rpc(RPC_DoSetMaxGroupMembers, value);
587 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
588 void RPC_DoSetMaxGroupMembers(
int value)
590 m_iMaxMembers = value;
594 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
595 void RPC_DoSetCustomDescription(
string desc,
int authorID)
597 m_sCustomDescription =
desc;
598 m_iDescriptionAuthorID = authorID;
599 s_OnCustomDescChanged.Invoke();
603 string GetCustomDescription()
605 bool canViewContentBy =
true;
607 if (m_iDescriptionAuthorID > 0)
608 canViewContentBy =
GetGame().GetPlayerController().CanViewContentCreatedBy(m_iDescriptionAuthorID);
610 if (m_sCustomDescription.IsEmpty() || !canViewContentBy)
613 return m_sCustomDescription;
617 string GetCustomName()
619 bool canViewContentBy =
true;
621 if (m_iNameAuthorID > 0)
622 canViewContentBy =
GetGame().GetPlayerController().CanViewContentCreatedBy(m_iNameAuthorID);
631 int GetDescriptionAuthorID()
633 return m_iDescriptionAuthorID;
637 int GetNameAuthorID()
639 return m_iNameAuthorID;
643 string GetCustomNameWithOriginal()
645 string company, platoon, squad, character, format;
646 GetCallsigns(company, platoon, squad, character, format);
647 string originalName, newName;
648 originalName =
string.Format(format, company, platoon, squad, character);
663 void SetGroupID(
int id)
671 return m_iMaxMembers;
676 void SetMaxMembers(
int maxMembers)
678 if (maxMembers == GetMaxMembers() || maxMembers < 0)
681 RPC_DoSetMaxMembers(maxMembers);
682 Rpc(RPC_DoSetMaxMembers, maxMembers);
686 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
687 void RPC_DoSetMaxMembers(
int maxMembers)
689 m_iMaxMembers = maxMembers;
690 s_OnMaxMembersChanged.Invoke();
694 array<int> GetPlayerIDs()
705 int GetPlayerCount(
bool checkMasterAndSlaves =
false)
707 if (!checkMasterAndSlaves)
710 int totalPlayerCount = GetPlayerCount();
713 totalPlayerCount += aiGroup.GetPlayerCount();
715 aiGroup = GetMaster();
717 totalPlayerCount += aiGroup.GetPlayerCount();
719 return totalPlayerCount;
723 ScriptInvoker GetOnMemberStateChange()
725 return m_OnGroupMemberStateChange;
729 static ScriptInvoker GetOnPlayerAdded()
731 return s_OnPlayerAdded;
735 static ScriptInvoker GetOnPlayerRemoved()
737 return s_OnPlayerRemoved;
741 static ScriptInvoker GetOnPlayerLeaderChanged()
743 return s_OnPlayerLeaderChanged;
747 static ScriptInvoker GetOnPrivateGroupChanged()
749 return s_OnPrivateGroupChanged;
753 static ScriptInvoker GetOnCustomNameChanged()
755 return s_OnCustomNameChanged;
759 static ScriptInvoker GetOnFrequencyChanged()
761 return s_OnFrequencyChanged;
765 static ScriptInvoker GetOnCustomDescriptionChanged()
767 return s_OnCustomDescChanged;
771 bool BelongedToGroup(
int playerID)
773 return m_aDisconnectedPlayerIDs !=
null && m_aDisconnectedPlayerIDs.Contains(playerID);
777 void AddAgentFromControlledEntity(notnull IEntity controlledEntity)
779 AIControlComponent aiControlComponent = AIControlComponent.Cast(controlledEntity.FindComponent(AIControlComponent));
780 if (!aiControlComponent)
783 AIAgent agent = aiControlComponent.GetAIAgent();
791 NotificateGroupAIChange(controlledEntity,
ENotification.GROUPS_AI_JOINED);
793 OnGroupMemberStateChange();
797 void RemoveAgentFromControlledEntity(notnull IEntity controlledEntity)
799 AIControlComponent aiControlComponent = AIControlComponent.Cast(controlledEntity.FindComponent(AIControlComponent));
800 if (!aiControlComponent)
803 AIAgent agent = aiControlComponent.GetAIAgent();
810 NotificateGroupAIChange(controlledEntity,
ENotification.GROUPS_AI_LEFT);
812 OnGroupMemberStateChange();
816 void NotificateGroupAIChange(IEntity controlledEntity,
ENotification notificationType)
820 if (editableEntityComp)
821 rplId = Replication.FindId(editableEntityComp);
824 SCR_NotificationsComponent.SendToGroup(GetMaster().GetGroupID(), notificationType, rplId);
829 void OnPlayerDisconnected(
int playerID)
837 if (!m_aDisconnectedPlayerIDs)
838 m_aDisconnectedPlayerIDs = {};
840 RemovePlayer(playerID);
841 m_aDisconnectedPlayerIDs.Insert(playerID);
846 void OnPlayerConnected(
int playerID)
849 int index = m_aDisconnectedPlayerIDs.Find(playerID);
853 m_aDisconnectedPlayerIDs.Remove(
index);
860 if (m_aDisconnectedPlayerIDs.Count() == 0)
864 gameMode.GetOnPlayerConnected().Remove(OnPlayerConnected);
869 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
870 void RPC_DoOnGroupMemberStateChange()
872 GetGame().GetCallqueue().CallLater(m_OnGroupMemberStateChange.Invoke, 1,
false,
null,
null,
null,
null,
null,
null,
null,
null,
null);
877 void OnGroupMemberStateChange()
879 RPC_DoOnGroupMemberStateChange();
880 Rpc(RPC_DoOnGroupMemberStateChange);
887 int playerID =
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(memberController.GetCharacter());
888 QueueAddAgent(playerID);
889 RemovePlayerAgent(playerID);
890 OnGroupMemberStateChange();
894 void ListenToMemberDeath(notnull IEntity groupMember)
897 if (!characterController)
900 characterController.GetOnPlayerDeathWithParam().Insert(OnMemberDeath);
904 void AddOnGadgetsLoadedListener(
int playerID, notnull IEntity controlledEntity)
910 gameMode.GetOnPlayerSpawned().Remove(AddOnGadgetsLoadedListener);
916 if (!controlledEntity)
919 int playerID =
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(controlledEntity);
923 int index = m_aAgentIDQueue.Find(playerID);
927 ListenToMemberDeath(controlledEntity);
928 AddAgentFromControlledEntity(controlledEntity);
929 m_aAgentIDQueue.Remove(
index);
931 if (!m_aAgentIDQueue.IsEmpty())
938 void QueueAddAgent(
int playerID)
941 m_aAgentIDQueue.Insert(playerID);
942 if (m_aAgentIDQueue.Count() != 1)
950 gameMode.GetOnPlayerSpawned().Insert(AddOnGadgetsLoadedListener);
954 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
955 void RPC_DoAddPlayer(
int playerID)
958 s_OnPlayerAdded.Invoke(
this, playerID);
964 void CheckForLeader(
int playerID,
bool noLeaderAllowed)
967 if (!IsPlayerInGroup(GetLeaderID()) && !noLeaderAllowed && playerID == -1)
971 s_OnPlayerLeaderChanged.Invoke(m_iGroupID, -1);
979 if (GetLeaderID() != -1)
984 SetGroupLeader(playerID);
991 void SetGroupLeader(
int playerID)
993 SCR_NotificationsComponent.SendToGroup(m_iGroupID,
ENotification.GROUPS_PLAYER_PROMOTED_LEADER, playerID);
994 RPC_SetLeaderID(playerID);
995 Rpc(RPC_SetLeaderID, playerID);
999 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1000 void RPC_SetLeaderID(
int playerID)
1002 if (playerID == m_iLeaderID)
1004 m_iLeaderID = playerID;
1005 s_OnPlayerLeaderChanged.Invoke(m_iGroupID, playerID);
1009 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1010 void RPC_SetPrivate(
bool isPrivate)
1012 m_bPrivate = isPrivate;
1013 s_OnPrivateGroupChanged.Invoke(m_iGroupID, isPrivate);
1018 ClearDeniedRequester();
1024 void AddPlayer(
int playerID)
1030 SCR_NotificationsComponent.SendToGroup(m_iGroupID,
ENotification.GROUPS_PLAYER_JOINED, playerID);
1031 RPC_DoAddPlayer(playerID);
1032 Rpc(RPC_DoAddPlayer, playerID);
1034 if (m_aDisconnectedPlayerIDs)
1036 int index = m_aDisconnectedPlayerIDs.Find(playerID);
1038 m_aDisconnectedPlayerIDs.Remove(
index);
1046 gameMode.GetOnPlayerDisconnected().Insert(OnPlayerDisconnected);
1049 IEntity controlledEntity =
GetGame().GetPlayerManager().GetPlayerControlledEntity(playerID);
1050 if (!controlledEntity)
1051 QueueAddAgent(playerID);
1053 AddAgentFromControlledEntity(controlledEntity);
1055 GetGame().GetCallqueue().CallLater(CheckForLeader, 0,
false, playerID,
false);
1059 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1060 void RPC_DoAddRequester(
int playerID)
1062 m_aRequesterIDs.Insert(playerID);
1063 s_OnJoinPrivateGroupRequest.Invoke();
1067 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1068 void RPC_DoRemoveRequester(
int playerID)
1070 m_aRequesterIDs.RemoveItem(playerID);
1074 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1075 void RPC_DoClearDeniedRequester()
1077 m_aDeniedRequesters.Clear();
1081 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1082 void RPC_DoClearRequesterIDs()
1084 m_aRequesterIDs.Clear();
1088 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1089 void RPC_DoAddDeniedRequester(
int playerID)
1091 m_aDeniedRequesters.Insert(playerID);
1096 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1097 void RPC_DoRemovePlayer(
int playerID)
1100 if (m_iLeaderID == playerID)
1103 s_OnPlayerRemoved.Invoke(
this, playerID);
1107 void RemovePlayerAgent(
int playerID)
1109 IEntity controlledEntity =
GetGame().GetPlayerManager().GetPlayerControlledEntity(playerID);
1110 if (!controlledEntity)
1113 AIControlComponent aiControlComponent = AIControlComponent.Cast(controlledEntity.FindComponent(AIControlComponent));
1114 if (!aiControlComponent)
1117 AIAgent agent = aiControlComponent.GetAIAgent();
1126 void RemovePlayer(
int playerID)
1131 RPC_DoRemovePlayer(playerID);
1132 Rpc(RPC_DoRemovePlayer, playerID);
1133 CheckForLeader(-1,
false);
1134 RemovePlayerAgent(playerID);
1135 SCR_NotificationsComponent.SendToGroup(m_iGroupID,
ENotification.GROUPS_PLAYER_LEFT, playerID);
1139 void GetCallsigns(out
string company, out
string platoon, out
string squad, out
string character, out
string format)
1141 SCR_CallsignGroupComponent callsignComponent = SCR_CallsignGroupComponent.Cast(FindComponent(SCR_CallsignGroupComponent));
1142 if (!callsignComponent)
1145 callsignComponent.GetCallsignNames(company, platoon, squad, character, format);
1149 void SetRadioFrequency(
int frequency)
1151 if (frequency == GetRadioFrequency() || frequency <= 0)
1154 RPC_DoSetFrequency(frequency);
1155 Rpc(RPC_DoSetFrequency, frequency);
1159 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1160 void RPC_DoSetFrequency(
int frequency)
1162 m_iGroupRadioFrequency = frequency;
1163 s_OnFrequencyChanged.Invoke();
1167 int GetRadioFrequency()
1169 return m_iGroupRadioFrequency;
1179 protected void CreateUnitEntities(
bool editMode, array<ResourceName> entityResourceNames)
1183 Print(
string.Format(
"Cannot spawn team members of group %1, AIWorld is missing in the world!",
this), LogLevel.WARNING);
1191 AIFormationComponent AIFormation = AIFormationComponent.Cast(FindComponent(AIFormationComponent));
1194 Print(
string.Format(
"Group %1 does not have AIFormationComponent! Team members will not be spawned.",
this), LogLevel.WARNING);
1197 AIFormationDefinition formationDefinition = AIFormation.GetFormation();
1198 if (!formationDefinition)
1199 Print(
string.Format(
"Formation of group %1 not found in SCR_AIWorld! Team members will not be spawned.",
this), LogLevel.WARNING);
1204 bool snapToTerrain = m_bSnapToTerrain;
1205 if (s_bIgnoreSnapToTerrain)
1207 snapToTerrain =
false;
1208 s_bIgnoreSnapToTerrain =
false;
1210 if (Replication.IsClient())
1214 if (editMode && !m_aSceneGroupUnitInstances)
1215 m_aSceneGroupUnitInstances =
new array<IEntity>;
1217 m_iNumOfMembersToSpawn = Math.Min(entityResourceNames.Count(), m_iMaxUnitsToSpawn);
1219 for (
int i = m_iNumOfMembersToSpawn-1; i >= 0; i--)
1223 delaySpawn.snapToTerrain = snapToTerrain;
1224 delaySpawn.index = i;
1225 delaySpawn.resourceName = entityResourceNames[i];
1226 delaySpawn.editMode = editMode;
1228 m_delayedSpawnList.Insert(delaySpawn);
1234 SpawnAllImmediately();
1239 BeginDelayedSpawn();
1243 if (m_iNumOfMembersToSpawn == 0)
1244 Event_OnInit.Invoke(
this);
1250 protected bool SpawnGroupMember(
bool snapToTerrain,
int index, ResourceName res,
bool editMode,
bool isLast)
1252 if (!
GetGame().GetAIWorld().CanLimitedAIBeAdded())
1255 Event_OnInit.Invoke(
this);
1261 BaseWorld world = GetWorld();
1262 AIFormationDefinition formationDefinition;
1263 AIFormationComponent formationComponent = AIFormationComponent.Cast(this.FindComponent(AIFormationComponent));
1264 if (formationComponent)
1265 formationDefinition = formationComponent.GetFormation();
1266 EntitySpawnParams spawnParams =
new EntitySpawnParams;
1267 spawnParams.TransformMode = ETransformMode.WORLD;
1268 GetWorldTransform(spawnParams.Transform);
1269 vector pos = spawnParams.Transform[3];
1271 if (formationDefinition)
1272 pos = CoordToParent(formationDefinition.GetOffsetPosition(
index));
1274 pos = CoordToParent(Vector(
index, 0, 0));
1278 float surfaceY = world.GetSurfaceY(pos[0], pos[2]);
1284 AIPathfindingComponent pathFindindingComponent = AIPathfindingComponent.Cast(this.FindComponent(AIPathfindingComponent));
1288 NavmeshWorldComponent navmesh = pathFindindingComponent.GetNavmeshComponent();
1291 if (navmesh.IsTileRequested(pos))
1295 if (!navmesh.IsTileLoaded(pos))
1297 navmesh.LoadTileIn(pos);
1303 if (pathFindindingComponent && pathFindindingComponent.GetClosestPositionOnNavmesh(pos,
"10 10 10", pos))
1305 float groundHeight = world.GetSurfaceY(pos[0], pos[2]);
1306 if (pos[1] < groundHeight)
1307 pos[1] = groundHeight;
1308 vector outWaterSurfacePoint;
1310 vector transformWS[4];
1312 if (
ChimeraWorldUtils.TryGetWaterSurface(GetWorld(), pos, outWaterSurfacePoint, waterSurfaceType, transformWS, obbExtents))
1314 pos = outWaterSurfacePoint;
1318 spawnParams.Transform[3] = pos;
1320 IEntity member =
GetGame().SpawnEntityPrefab(Resource.Load(res), world, spawnParams);
1329 m_aSceneGroupUnitInstances.Insert(member);
1335 AddAIEntityToGroup(member);
1337 FactionAffiliationComponent factionAffiliation = FactionAffiliationComponent.Cast(member.FindComponent(FactionAffiliationComponent));
1339 if (factionAffiliation)
1340 factionAffiliation.SetAffiliatedFactionByKey(m_faction);
1343 Event_OnInit.Invoke(
this);
1348 void SetWaypointParams(out AIWaypoint wp, SCR_WaypointPrefabLocation prefabParams)
1350 if (
SCR_TimedWaypoint.Cast(wp) && !
float.AlmostEqual(prefabParams.m_WPTimeOverride,0.0))
1352 if ( !
float.AlmostEqual(prefabParams.m_WPRadiusOverride,0.0) )
1353 wp.SetCompletionRadius(prefabParams.m_WPRadiusOverride);
1354 wp.SetName(prefabParams.m_WPInstanceName);
1358 void AddWaypointsDynamic(out array<IEntity> entityInstanceList, array<ref SCR_WaypointPrefabLocation> prefabs)
1360 entityInstanceList =
new array<IEntity>;
1361 EntitySpawnParams spawnParams =
new EntitySpawnParams;
1362 spawnParams.TransformMode = ETransformMode.WORLD;
1364 Math3D.MatrixIdentity4(mat);
1365 for (
int i = 0, length = prefabs.Count(); i < length; i++)
1369 mat[3] = prefabs[i].m_WPWorldLocation;
1370 spawnParams.Transform = mat;
1372 #ifdef WORKBENCH //includes game mode run from WB
1373 WorldEditorAPI m_API = _WB_GetEditorAPI();
1376 Print(prefabs[i].m_WPPrefabName);
1377 entity =
GetGame().SpawnEntityPrefab(Resource.Load(prefabs[i].m_WPPrefabName), m_API.GetWorld(), spawnParams);
1378 entityInstanceList.Insert(entity);
1379 wp = AIWaypoint.Cast(entity);
1383 entity =
GetGame().SpawnEntityPrefab(Resource.Load(prefabs[i].m_WPPrefabName),
GetGame().GetWorld(), spawnParams);
1384 wp = AIWaypoint.Cast(entity);
1387 #else // game run from build
1388 entity =
GetGame().SpawnEntityPrefab(Resource.Load(prefabs[i].m_WPPrefabName),
GetGame().GetWorld(), spawnParams);
1389 wp = AIWaypoint.Cast(entity);
1393 SetWaypointParams(wp,prefabs[i]);
1398 void AddWaypointsStatic(array<string> aWaypointNames)
1400 for (
int i = 0, length = aWaypointNames.Count(); i < length; i++)
1403 WorldEditorAPI m_API = _WB_GetEditorAPI();
1406 AddWaypoint(AIWaypoint.Cast(m_API.GetWorld().FindEntityByName(aWaypointNames[i])));
1419 void AddVehiclesStatic(array<string> aVehicleNames)
1421 for (
int i = 0, length = aVehicleNames.Count(); i < length; i++)
1424 WorldEditorAPI m_API = _WB_GetEditorAPI();
1427 AddUsableVehicle(m_API.GetWorld().FindEntityByName(aVehicleNames[i]));
1440 protected void DestroyEntities(out array<IEntity> entityList)
1445 for (
int i=0, length = entityList.Count(); i < length; i++)
1447 if ( AIWaypoint.Cast(entityList[i]) )
1448 RemoveWaypointFromGroup(AIWaypoint.Cast(entityList[i]));
1450 RemoveAIEntityFromGroup(entityList[i]);
1451 delete entityList[i];
1458 void RemoveStaticWaypointRefs(array<string> aWaypointNames)
1460 if (!aWaypointNames)
1463 for (
int i=0, length = aWaypointNames.Count(); i < length; i++)
1466 WorldEditorAPI m_API = _WB_GetEditorAPI();
1469 RemoveWaypointFromGroup(AIWaypoint.Cast(m_API.GetWorld().FindEntityByName(aWaypointNames[i])));
1482 void ClearRefs(out array<IEntity> entityList)
1490 bool AddAIEntityToGroup(IEntity entity)
1492 if (!entity)
return false;
1494 AIControlComponent control = AIControlComponent.Cast(entity.FindComponent(AIControlComponent));
1495 if (!control)
return false;
1497 AIAgent agent = control.GetControlAIAgent();
1498 if (!agent)
return false;
1500 control.ActivateAI();
1502 if (!agent.GetParentGroup())
1509 bool RemoveAIEntityFromGroup(IEntity entity)
1512 WorldEditorAPI m_API = _WB_GetEditorAPI();
1513 if ( !m_API && entity && entity.FindComponent(AIControlComponent))
1515 ref AIAgent agent = AIControlComponent.Cast(entity.FindComponent(AIControlComponent)).GetControlAIAgent();
1520 if ( entity && entity.FindComponent(AIControlComponent))
1522 ref AIAgent agent = AIControlComponent.Cast(entity.FindComponent(AIControlComponent)).GetControlAIAgent();
1531 void AddWaypointToGroup(AIWaypoint waypoint)
1535 AddWaypoint(waypoint);
1540 void RemoveWaypointFromGroup(AIWaypoint waypoint)
1544 RemoveWaypoint(waypoint)
1549 void AddUsableVehicle(IEntity vehicle)
1551 if (Vehicle.Cast(vehicle) && m_aUsableVehicles.Find(vehicle) < 0)
1552 m_aUsableVehicles.Insert(vehicle);
1556 void RemoveUsableVehicle(IEntity vehicle)
1558 if (Vehicle.Cast(vehicle) && m_aUsableVehicles.Find(vehicle) > -1)
1559 m_aUsableVehicles.RemoveItem(vehicle);
1563 bool IsUsableVehicle(IEntity vehicle)
1565 return m_aUsableVehicles.Contains(vehicle);
1569 int GetUsableVehicles(out array<IEntity> usableVehicles)
1571 return usableVehicles.Copy(m_aUsableVehicles);
1575 int GetUsableVehiclesCount()
1577 return m_aUsableVehicles.Count();
1581 void GetAllocatedCompartments(out array<BaseCompartmentSlot> allocatedCompartments)
1583 allocatedCompartments = m_aAllocatedCompartments;
1587 void AllocateCompartment(BaseCompartmentSlot compartment)
1591 if (m_aAllocatedCompartments.Find(compartment) > -1)
1593 Print(
"Trying to allocate same compartment twice!", LogLevel.WARNING);
1596 m_aAllocatedCompartments.Insert(compartment);
1597 compartment.SetCompartmentAccessible(
false);
1601 void ReleaseCompartment(BaseCompartmentSlot compartment)
1603 int index = m_aAllocatedCompartments.Find(compartment);
1605 m_aAllocatedCompartments.Remove(
index);
1607 Print(
"Trying to remove compartment that is not allocated!", LogLevel.WARNING);
1611 void ReleaseCompartments()
1613 foreach (BaseCompartmentSlot comp : m_aAllocatedCompartments)
1616 comp.SetCompartmentAccessible(
true);
1618 m_aAllocatedCompartments.Clear();
1627 bool InitFactionKey(
string factionKey)
1629 if (m_faction !=
"")
return false;
1630 m_faction = factionKey;
1641 bool SetFaction(
Faction faction)
1643 if (Replication.IsClient())
1647 if (m_bPlayable && m_faction)
1653 m_faction = faction.GetFactionKey();
1655 array<AIAgent> agents =
new array<AIAgent>;
1657 array<IEntity> updatedVehicles =
new array<IEntity>;
1662 foreach (AIAgent agent: agents)
1664 charEntity = agent.GetControlledEntity();
1669 FactionAffiliationComponent factionAffiliation = FactionAffiliationComponent.Cast(charEntity.FindComponent(FactionAffiliationComponent));
1670 if (factionAffiliation)
1671 factionAffiliation.SetAffiliatedFaction(faction);
1675 Event_OnFactionChanged.Invoke(faction);
1677 FactionManager factionManager =
GetGame().GetFactionManager();
1678 int factionIndex = factionManager.GetFactionIndex(faction);
1680 GetGame().GetCallqueue().CallLater(SetFactionDelayed, 1,
false, factionIndex);
1686 protected void SetFactionDelayed(
int factionIndex)
1688 Rpc(BroadCastSetFaction, factionIndex);
1693 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
1694 protected void BroadCastSetFaction(
int factionIndex)
1696 FactionManager factionManager =
GetGame().GetFactionManager();
1697 if (!factionManager)
1700 Faction faction = factionManager.GetFactionByIndex(factionIndex);
1701 m_faction = faction.GetFactionKey();
1702 Event_OnFactionChanged.Invoke(faction);
1710 string GetFactionName()
1722 ArmaReforgerScripted game =
GetGame();
1723 if (!game)
return null;
1725 FactionManager factionManager = game.GetFactionManager();
1726 if (!factionManager)
return null;
1728 return factionManager.GetFactionByKey(m_faction);
1735 int GetFactionIndex()
1737 FactionManager factionManager =
GetGame().GetFactionManager();
1738 if (!factionManager)
1741 return factionManager.GetFactionIndex(GetFaction());
1751 static void IgnoreSnapToTerrain(
bool ignore)
1753 s_bIgnoreSnapToTerrain = ignore;
1761 static void IgnoreSpawning(
bool ignore)
1773 ScriptInvoker GetOnInit()
1775 return Event_OnInit;
1786 return Event_OnEmpty;
1796 ScriptInvoker GetOnAgentAdded()
1798 return Event_OnAgentAdded;
1808 ScriptInvoker GetOnAgentRemoved()
1810 return Event_OnAgentRemoved;
1820 ScriptInvoker GetOnLeaderChanged()
1822 return Event_OnLeaderChanged;
1832 ScriptInvoker GetOnCurrentWaypointChanged()
1834 return Event_OnCurrentWaypointChanged;
1844 ScriptInvoker GetOnWaypointCompleted()
1846 return Event_OnWaypointCompleted;
1856 ScriptInvoker GetOnWaypointAdded()
1858 return Event_OnWaypointAdded;
1868 ScriptInvoker GetOnWaypointRemoved()
1870 return Event_OnWaypointRemoved;
1878 ScriptInvoker GetOnFactionChanged()
1880 return Event_OnFactionChanged;
1884 ScriptInvokerBase<ScriptInvokerAIGroup> GetOnAllDelayedEntitySpawned()
1886 if (!Event_OnAllDelayedEntitySpawned)
1887 Event_OnAllDelayedEntitySpawned =
new ScriptInvokerBase<ScriptInvokerAIGroup>();
1889 return Event_OnAllDelayedEntitySpawned;
1893 override void OnEmpty()
1895 Event_OnEmpty.Invoke(
this);
1898 if (m_bDeleteWhenEmpty)
1903 override void OnAgentAdded(AIAgent child)
1905 Event_OnAgentAdded.Invoke(child);
1910 agent.OnGroupWaypointChanged(GetCurrentWaypoint());
1915 override void OnAgentRemoved(AIAgent child)
1917 Event_OnAgentRemoved.Invoke(
this, child);
1921 override void OnLeaderChanged(AIAgent currentLeader, AIAgent prevLeader)
1923 Event_OnLeaderChanged.Invoke(currentLeader, prevLeader);
1927 ChimeraCharacter character = ChimeraCharacter.Cast(currentLeader.GetControlledEntity());
1932 controller.m_OnLifeStateChanged.Insert(LeaderLifeStateChanged);
1939 ChimeraCharacter character = ChimeraCharacter.Cast(prevLeader.GetControlledEntity());
1944 controller.m_OnLifeStateChanged.Remove(LeaderLifeStateChanged);
1949 override void OnCurrentWaypointChanged(AIWaypoint currentWP, AIWaypoint prevWP)
1951 InvokeSubagentsOnWaypointChanged(currentWP);
1953 Event_OnCurrentWaypointChanged.Invoke(currentWP, prevWP);
1957 override void OnWaypointCompleted(AIWaypoint wp)
1959 InvokeSubagentsOnWaypointChanged(
null);
1961 Event_OnWaypointCompleted.Invoke(wp);
1965 override void OnWaypointAdded(AIWaypoint wp)
1967 Event_OnWaypointAdded.Invoke(wp);
1971 override void OnWaypointRemoved(AIWaypoint wp,
bool isCurrentWaypoint)
1973 InvokeSubagentsOnWaypointChanged(
null);
1975 Event_OnWaypointRemoved.Invoke(wp, isCurrentWaypoint);
1981 protected void InvokeSubagentsOnWaypointChanged(AIWaypoint newWaypoint)
1983 array<AIAgent> agents = {};
1985 foreach (AIAgent agent : agents)
1989 _agent.OnGroupWaypointChanged(newWaypoint);
1995 override bool _WB_OnKeyChanged(BaseContainer src,
string key, BaseContainerList ownerContainers, IEntity parent)
1997 if (key ==
"coords")
1999 DestroyEntities(m_aSceneGroupUnitInstances);
2000 CreateUnitEntities(
true,m_aUnitPrefabSlots);
2007 override void EOnInit(IEntity owner)
2009 m_aUsableVehicles =
new array<IEntity>;
2010 m_aAllocatedCompartments =
new array<BaseCompartmentSlot>;
2012 if (s_bIgnoreSpawning)
2015 Event_OnInit.Invoke(
this);
2017 else if (m_bSpawnImmediately)
2026 bool GetSpawnImmediately()
2028 return m_bSpawnImmediately;
2032 void SetSpawnImmediately(
bool spawnImmediately)
2034 m_bSpawnImmediately = spawnImmediately;
2038 void SetMaxUnitsToSpawn(
int cnt)
2040 m_iMaxUnitsToSpawn = cnt;
2049 void SetMemberSpawnDelay(
int memberSpawnDelay)
2051 m_fMemberSpawnDelay = memberSpawnDelay;
2059 CreateUnitEntities(
true, m_aUnitPrefabSlots);
2060 AddVehiclesStatic(m_aStaticVehicles);
2061 AddWaypointsStatic(m_aStaticWaypoints);
2062 AddWaypointsDynamic(m_aSceneWaypointInstances, m_aSpawnedWaypoints);
2067 CreateUnitEntities(
false, m_aUnitPrefabSlots);
2068 AddVehiclesStatic(m_aStaticVehicles);
2069 AddWaypointsStatic(m_aStaticWaypoints);
2070 AddWaypointsDynamic(
null, m_aSpawnedWaypoints);
2080 return m_SlaveGroup;
2089 m_SlaveGroup = group;
2090 group.SetMaster(
this);
2112 array<SCR_ChimeraCharacter> GetAIMembers()
2114 return m_aAIMembers;
2121 bool IsAIControlledCharacterMember(SCR_ChimeraCharacter character)
2128 return m_SlaveGroup.m_aAIMembers.Find(character) != -1;
2132 override bool RplSave(ScriptBitWriter writer)
2137 int factionIndex = -1;
2138 FactionManager factionManager =
GetGame().GetFactionManager();
2140 factionIndex = factionManager.GetFactionIndex(GetFaction());
2142 writer.WriteInt(factionIndex);
2143 writer.WriteInt(m_iGroupRadioFrequency);
2144 writer.WriteInt(m_iGroupID);
2147 writer.WriteInt(count);
2148 for (
int i = count - 1; i >= 0; i--)
2150 writer.WriteInt(m_aPlayerIDs[i]);
2152 writer.WriteInt(m_iLeaderID);
2153 writer.WriteBool(m_bPrivate);
2155 writer.WriteString(m_sCustomDescription);
2156 writer.WriteString(m_sCustomName);
2158 writer.WriteString(m_UiInfo.GetGroupFlag());
2159 writer.WriteBool(m_UiInfo.GetFlagIsFromImageSet());
2162 groupID = Replication.FindId(m_MasterGroup);
2163 writer.WriteRplId(groupID);
2164 groupID = Replication.FindId(m_SlaveGroup);
2165 writer.WriteRplId(groupID);
2167 writer.WriteInt(m_iDescriptionAuthorID);
2168 writer.WriteInt(m_iNameAuthorID);
2169 writer.WriteInt(m_iMaxMembers);
2178 override bool RplLoad(ScriptBitReader reader)
2181 reader.ReadInt(factionIndex);
2182 if (factionIndex >= 0)
2183 BroadCastSetFaction(factionIndex);
2185 reader.ReadInt(m_iGroupRadioFrequency);
2186 reader.ReadInt(m_iGroupID);
2188 int count, playerID;
2189 reader.ReadInt(count);
2190 for (
int i = count - 1; i >= 0; i--)
2192 reader.ReadInt(playerID);
2201 groupsManager.RegisterGroup(
this);
2202 groupsManager.ClaimFrequency(GetRadioFrequency(), GetFaction());
2203 groupsManager.OnGroupCreated(
this);
2208 reader.ReadInt(temp);
2209 RPC_SetLeaderID(temp);
2211 reader.ReadBool(m_bPrivate);
2213 reader.ReadString(m_sCustomDescription);
2214 reader.ReadString(m_sCustomName);
2220 reader.ReadString(flag);
2221 m_UiInfo.SetGroupFlag(flag);
2223 bool isFromImageSet;
2224 reader.ReadBool(isFromImageSet);
2225 m_UiInfo.SetFlagIsFromImageSet(isFromImageSet);
2228 reader.ReadRplId(groupID);
2230 reader.ReadRplId(groupID);
2231 m_SlaveGroup =
SCR_AIGroup.Cast(Replication.FindItem(groupID));
2233 reader.ReadInt(m_iDescriptionAuthorID);
2234 reader.ReadInt(m_iNameAuthorID);
2235 reader.ReadInt(m_iMaxMembers);
2244 SetNewConsciousLeader();
2248 void SetNewConsciousLeader()
2250 array<AIAgent> groupAgents = {};
2251 GetAgents(groupAgents);
2253 for (
int i = 1; i < groupAgents.Count(); i++)
2255 ChimeraCharacter character = ChimeraCharacter.Cast(groupAgents.Get(i).GetControlledEntity());
2259 CharacterControllerComponent charController = character.GetCharacterController();
2260 if (!charController)
2263 if (!charController.IsUnconscious())
2265 SetNewLeader(groupAgents.Get(i));
2272 void IncreaseDeployedRadioCount()
2274 m_iDeployedRadioCount++;
2275 Replication.BumpMe();
2279 void DecreaseDeployedRadioCount()
2281 if(m_iDeployedRadioCount < 1)
2284 m_iDeployedRadioCount--;
2285 Replication.BumpMe();
2289 int GetDeployedRadioCount()
2291 return m_iDeployedRadioCount;
2295 void SCR_AIGroup(IEntitySource src, IEntity parent)
2297 SetEventMask(EntityEvent.INIT);
2309 groupsManager.UnregisterGroup(
this);
2310 groupsManager.GetOnPlayableGroupRemoved().Invoke(
this);
2314 DestroyEntities(m_aSceneGroupUnitInstances);
2315 DestroyEntities(m_aSceneWaypointInstances);
2316 RemoveStaticWaypointRefs(m_aStaticWaypoints);
2317 ClearRefs(m_aUsableVehicles);
2347 class SCR_WaypointPrefabLocation
2349 [
Attribute(
"{750A8D1695BD6998}AI/Entities/Waypoints/AIWaypoint.et", UIWidgets.ResourceAssignArray,
"Prefab for the waypoint")]
2350 ResourceName m_WPPrefabName;
2352 [
Attribute(
"", UIWidgets.EditBox,
"Waypoint name")]
2353 string m_WPInstanceName;
2355 [
Attribute(
"", UIWidgets.EditBox,
"Waypoint location")]
2356 vector m_WPWorldLocation;
2358 [
Attribute(
"0", UIWidgets.EditBox,
"Waypoint completion radius (-1 dont override default)")]
2359 float m_WPRadiusOverride;
2361 [
Attribute(
"0", UIWidgets.EditBox,
"Waypoint completion time (-1 dont override default)")]
2362 float m_WPTimeOverride;