8 [
Attribute(
"90",
desc:
"Time at which Group Cohesion will be evaluated in seconds")]
9 protected float m_fGroupCohesionCheck;
11 [
Attribute(
"100",
desc:
"Distance between players at which they are considered part of the same group")]
12 protected float m_fGroupCohesionRadius;
14 [
Attribute(
"2",
desc:
"XP increment per player on the group")]
15 protected float m_fGroupCohesionXpIncreasePerPlayer;
17 [
Attribute(
"3",
desc:
"Amount of times the XP awarded will be increased in every check where the group is together")]
18 protected int m_iMaxGroupCohesionLevel;
20 [
Attribute(
"false",
desc:
"Activate/Deactivate debug draws with information about cohesion level and XP awarded")]
21 protected bool m_bDebugActive;
23 protected int m_iGroupCohesionLevel = 0;
28 private int m_iLastAwardedXP = 0;
29 private int m_iLastGroupCount = 0;
32 protected float GetGroupCohesionCheckTimeInMs()
34 return m_fGroupCohesionCheck * 1000;
40 RplComponent rplComponent = RplComponent.Cast(owner.
FindComponent(RplComponent));
47 if (!rplComponent || !rplComponent.IsMaster())
86 DbgUI.Begin(
"Cohesion Debug");
87 DbgUI.Text(
"Cohesion Time: " + m_iGroupCohesionLevel * m_fGroupCohesionCheck +
"s");
88 DbgUI.Text(
"Last Player Count on Group: " + m_iLastGroupCount +
"/" +
m_Group.GetPlayerCount());
89 DbgUI.Text(
"Last awarded XP: " + m_iLastAwardedXP +
"xp");
96 playerGraph.Reserve(playerCount);
98 for (
int i = 0; i < playerCount; ++i)
100 playerGraph.Insert({});
103 float cohesionRadiusSq = m_fGroupCohesionRadius * m_fGroupCohesionRadius;
105 for (
int player1Index = 0; player1Index < playerCount - 1; ++player1Index)
107 IEntity player1 =
GetGame().GetPlayerManager().GetPlayerControlledEntity(players[player1Index]);
111 for (
int player2Index = 0; player2Index < playerCount; ++player2Index)
113 if (player1Index == player2Index)
116 IEntity player2 =
GetGame().GetPlayerManager().GetPlayerControlledEntity(players[player2Index]);
125 playerGraph[player1Index].Insert(player2Index);
126 playerGraph[player2Index].Insert(player1Index);
132 private void FindUnusedAdjacentAgentGraph(
int agent, array< ref array<int>> playerGraph, out array<int> group, out array<int> usedAgents)
134 usedAgents.Insert(agent);
137 array<int> currentAgentGraph = playerGraph[agent];
139 foreach (
int adjacentAgent : currentAgentGraph)
141 if (usedAgents.Find(adjacentAgent) < 0)
142 FindUnusedAdjacentAgentGraph(adjacentAgent, playerGraph, group, usedAgents);
149 array<int> usedAgents = {};
150 usedAgents.Reserve(playerCount);
152 for (
int agentToCheck = 0; agentToCheck < playerCount - 1; ++agentToCheck)
154 array<int> group = {};
156 FindUnusedAdjacentAgentGraph(agentToCheck, playerGraph, group, usedAgents);
158 if (group.Count() >= groupMinSize)
160 biggestGroup = group;
164 if (group.Count() > biggestGroup.Count())
165 biggestGroup = group;
167 if (biggestGroup.Count() > playerCount - usedAgents.Count())
175 players =
m_Group.GetPlayerIDs();
176 int playerCount = players.Count();
178 if (playerCount <= 1)
181 groupMinSize = (playerCount / 2) + 1;
183 array<ref array<int>> playerGraph = {};
192 protected void AwardXPToGroup(array<int> playerGroup, array<int> players,
int groupMinSize)
194 if (playerGroup.Count() >= groupMinSize)
198 m_iGroupCohesionLevel =
Math.ClampInt(m_iGroupCohesionLevel + 1, 0, m_iMaxGroupCohesionLevel);
200 int XPToAward = m_fGroupCohesionXpIncreasePerPlayer * (playerGroup.Count()) * m_iGroupCohesionLevel;
202 m_iLastAwardedXP = XPToAward;
204 foreach (
int playerIndex : playerGroup)
206 compXP.AwardXP(players[playerIndex],
SCR_EXPRewards.GROUP_COHESION, 1.0,
false, XPToAward);
211 m_iGroupCohesionLevel = 0;
212 m_iLastAwardedXP = 0;
219 array<int> playerGroup = {};
220 array<int> players = {};
226 m_iLastGroupCount = playerGroup.Count();
232 array<int> playerGroup = {};
233 array<int> players = {};
239 if (playerGroup.Count() < groupMinSize)
242 foreach (
int playerIndex : playerGroup)
244 playersInCohesion.Insert(players[playerIndex]);
247 return playersInCohesion.Count();
ArmaReforgerScripted GetGame()
void CreateAgentDistanceGraph(out array< ref array< int > > playerGraph, array< int > players, int playerCount)
void OnPlayerAddedToGroup(SCR_AIGroup aiGroup, int playerID)
void AwardXPToGroup(array< int > playerGroup, array< int > players, int groupMinSize)
bool GetGroupOfPlayersInCohesion(out notnull array< int > playerGroup, out notnull array< int > players, out int groupMinSize)
void FindGroupFromAgentDistanceGraph(out array< int > biggestGroup, const array< ref array< int > > playerGraph, int playerCount, int groupMinSize)
void CheckGroupCohesion()
void OnPlayerRemovedFromGroup(SCR_AIGroup aiGroup, int playerID)
int GetPlayersInCohesion(out notnull array< int > playersInCohesion)
SCR_AIGroupSettingsComponentClass m_Group
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
SCR_BaseGameMode GetGameMode()
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
proto external GenericComponent FindComponent(typename typeName)
proto external Managed FindComponent(typename typeName)
proto external vector GetOrigin()
int GetPlayerCount(bool checkMasterAndSlaves=false)
static ScriptInvoker GetOnPlayerRemoved()
static ScriptInvoker GetOnPlayerAdded()
SCR_FieldOfViewSettings Attribute