9 const int INVALID_AREA_INDEX = -1;
10 const string ENEMY_PRESENCE_ELIMINATED_TEXT =
"Enemy presence eliminated!\nNew area is being selected.\nPlease wait.";
19 float m_fAiGroupsPerPlayer;
21 [
Attribute(
"", UIWidgets.ResourceNamePicker,
"What group type should spawn")]
22 ResourceName m_GroupType;
24 [
Attribute(defvalue:
"{EBD2A7DA0A3C6E17}UI/layouts/Menus/CleanSweep/CleanSweepAreaSelection.layout",
desc:
"Layout for area selection")]
25 ResourceName m_AreaSelectionLayout;
31 Widget m_wAreaSelectionWidget;
34 ref array<IEntity> m_aEnemySoldiers =
new array<IEntity>;
35 ref array<SCR_AIGroup> m_aGroups;
36 ref array<SCR_SpawnPoint> m_aEnemySpawnPoints;
37 ref array<SCR_SpawnPoint> m_aPlayerSpawnPoints;
38 AIWaypoint m_AttackWP;
40 int m_iGameMasterID = -1;
42 [
RplProp(onRplName:
"OnAreaChanged")]
43 int areaID = INVALID_AREA_INDEX;
48 if (m_wAreaSelectionWidget)
49 m_wAreaSelectionWidget.RemoveFromHierarchy();
51 if (!m_aEnemySpawnPoints)
52 m_aEnemySpawnPoints =
new array<SCR_SpawnPoint>();
54 m_aEnemySpawnPoints.Clear();
56 if (!m_aPlayerSpawnPoints)
57 m_aPlayerSpawnPoints =
new array<SCR_SpawnPoint>();
59 m_aPlayerSpawnPoints.Clear();
67 ref array<SCR_CleanSweepArea> activeAreas =
new array<SCR_CleanSweepArea>();
69 int activeAreasCount = GetActiveAreas(activeAreas);
71 if (activeAreasCount < 1)
73 Print(
"CleanSweeup has not enough active playable areas. GameMode will not function.", LogLevel.ERROR);
84 wp.SetOrigin(area.GetOrigin());
86 vector centerPos = area.GetOrigin();
87 float rangeSq = area.m_Range * area.m_Range;
88 array<IEntity> entities =
new array<IEntity>();
89 array<SCR_SpawnPoint> spawnPoints =
SCR_SpawnPoint.GetSpawnPoints();
90 GetWorld().GetActiveEntities(entities);
92 for (
int i = spawnPoints.Count() - 1; i >= 0; i--)
95 if (vector.DistanceSqXZ(centerPos, spawnPoint.GetOrigin()) < rangeSq)
97 FactionKey faction = spawnPoint.GetFactionKey();
98 if (faction ==
"USSR")
101 m_aEnemySpawnPoints.Insert(spawnPoint);
103 m_aPlayerSpawnPoints.Insert(spawnPoint);
108 m_aPlayerSpawnPoints.Insert(spawnPoint);
110 m_aEnemySpawnPoints.Insert(spawnPoint);
115 for (
int i = entities.Count() - 1; i >= 0; i--)
122 if (vector.DistanceSqXZ(centerPos, entities[i].GetOrigin()) < rangeSq)
123 vehicleSpawner.PerformSpawn();
127 m_bAutoPlayerRespawn =
true;
133 void RespawnPlayers()
135 array<int> players =
new array<int>();
136 int count =
GetGame().GetPlayerManager().GetPlayers(players);
137 for (
int i = count - 1; i >= 0; i--)
139 PlayerController playerController =
GetGame().GetPlayerManager().GetPlayerController(players[i]);
141 if (!playerController)
145 if (!networkComponent)
148 networkComponent.CommitSuicide();
153 void SetSwapSides(
bool swapSides)
155 m_bSwapSides = swapSides;
159 void SetArea(
int targetAreaID )
161 areaID = targetAreaID;
163 Replication.BumpMe();
166 GetGame().GetCallqueue().CallLater(CheckActiveAreaState, 1,
true);
170 void CheckActiveAreaState()
172 ChimeraCharacter character;
174 for (
int i = m_aEnemySoldiers.Count() -1; i >= 0; i--)
176 if (!m_aEnemySoldiers[i])
177 m_aEnemySoldiers.Remove(i);
180 character = ChimeraCharacter.Cast(m_aEnemySoldiers[i]);
183 m_aEnemySoldiers.Remove(i);
187 damageManager = character.GetDamageManager();
198 ReplicatedShowHint(0, 5);
200 if (RplSession.Mode() != RplMode.Dedicated)
203 areaID = INVALID_AREA_INDEX;
204 Replication.BumpMe();
205 GetGame().GetCallqueue().Remove(CheckActiveAreaState);
206 ShowAreaSelectionToGameMaster();
211 override void EOnFrame(IEntity owner,
float timeSlice)
213 super.EOnFrame(owner, timeSlice);
215 if (RplSession.Mode() != RplMode.Dedicated && areaID == INVALID_AREA_INDEX && m_wAreaSelectionWidget)
217 InputManager inputManager =
GetGame().GetInputManager();
218 inputManager.ActivateContext(
"MenuContext");
223 void ReplicatedShowHint(
int hintID,
float showTime)
225 Rpc(RPC_ShowHint, hintID, showTime);
229 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
230 protected void RPC_ShowHint(
int hintID,
float time)
232 ShowHint(hintID, time);
236 void ShowHint(
int hintID,
float showTime)
245 m_wText.SetText(ENEMY_PRESENCE_ELIMINATED_TEXT);
250 AnimateWidget.Opacity(
m_wRoot, 1, 1);
252 ScriptCallQueue queue =
GetGame().GetCallqueue();
253 queue.CallLater(this.HideHint, showTime * 1000);
260 AnimateWidget.Opacity(
m_wRoot, 0, 1);
269 if (m_aEnemySpawnPoints.Count() == 0)
273 for (
int i = m_aGroups.Count() - 1; i >= 0; i--)
278 m_aEnemySoldiers.Clear();
280 int enemyGroupsCount = Math.ClampInt((Math.Ceil(
GetGame().GetPlayerManager().
GetPlayerCount() * m_fAiGroupsPerPlayer)), m_iMinAiGroups, m_iMaxAiGroups);
281 for (
int i = 0; i < enemyGroupsCount; i++)
283 RandomGenerator generator =
new RandomGenerator;
284 generator.SetSeed(Math.RandomInt(0,100));
286 SCR_SpawnPoint spawnPoint = m_aEnemySpawnPoints.GetRandomElement();
290 vector
position = generator.GenerateRandomPointInRadius(0, 2, spawnPoint.GetOrigin());
291 position[1] = spawnPoint.GetOrigin()[1];
292 EntitySpawnParams
params = EntitySpawnParams();
293 params.TransformMode = ETransformMode.WORLD;
296 Resource res = Resource.Load(m_GroupType);
300 m_aGroups.Insert(newGrp);
302 array<AIAgent> agents =
new array<AIAgent>;
304 newGrp.GetAgents(agents);
305 foreach (AIAgent agent : agents)
308 m_aEnemySoldiers.Insert(agent.GetControlledEntity());
312 newGrp.AddWaypoint(m_AttackWP);
324 protected override void OnPlayerKilled(
int playerId, IEntity playerEntity, IEntity killerEntity, notnull
Instigator killer)
326 super.OnPlayerKilled(playerId, playerEntity, killerEntity, killer);
327 m_aEnemySoldiers.RemoveItemOrdered(playerEntity);
331 vector GetPlayersCenter()
333 array<int> players =
new array<int>();
334 int count =
GetGame().GetPlayerManager().GetPlayers(players);
336 vector center = vector.Zero;
337 int countedEntities = 0;
339 for (
int i = count - 1; i >= 0; i--)
341 IEntity controlledEntity = SCR_PossessingManagerComponent.GetPlayerMainEntity(players[i]);
342 if (!controlledEntity)
345 vector entityPosition = controlledEntity.GetOrigin();
346 center[0] = center[0] + entityPosition[0];
347 center[1] = center[1] + entityPosition[1];
348 center[2] = center[2] + entityPosition[2];
353 if (countedEntities != 0)
355 center[0] = center[0] / countedEntities;
356 center[1] = center[1] / countedEntities;
357 center[2] = center[2] / countedEntities;
364 int GetActiveAreas(array<SCR_CleanSweepArea> activeAreas)
372 int areasCount = areas.Count();
373 for (
int i = 0; i < areasCount; i++)
382 activeAreas.Insert(area);
390 void InitializeServer()
393 m_aGroups =
new array<SCR_AIGroup>;
394 m_aPlayerSpawnPoints =
new array<SCR_SpawnPoint>;
395 m_aEnemySpawnPoints =
new array<SCR_SpawnPoint>;
399 PlayerController GetGameMaster()
401 PlayerController playerController =
GetGame().GetPlayerManager().GetPlayerController(m_iGameMasterID);
402 if (!playerController)
403 return PickNewGameMaster();
405 return playerController;
409 PlayerController PickNewGameMaster(
int exclude = -1)
411 PlayerController playerController;
413 array<int> players = {};
414 int count =
GetGame().GetPlayerManager().GetPlayers(players);
415 for (
int i = 0; i < count; i++)
417 if (players[i] == exclude)
420 playerController =
GetGame().GetPlayerManager().GetPlayerController(players[i]);
421 if (playerController)
423 m_iGameMasterID = players[i];
428 return playerController;
432 void ShowAreaSelectionToGameMaster()
434 PlayerController playerController = GetGameMaster();
435 if (!playerController)
439 if (!networkComponent)
442 networkComponent.ShowAreaSelectionScreen();
447 void ShowAreaSelectionUI()
449 if (areaID != INVALID_AREA_INDEX || m_AreaSelectionLayout.GetPath() ==
string.Empty)
452 if (!m_wAreaSelectionWidget)
453 m_wAreaSelectionWidget =
GetGame().GetWorkspace().CreateWidgets(m_AreaSelectionLayout);
455 XComboBoxWidget selectionBox = XComboBoxWidget.Cast(m_wAreaSelectionWidget.FindAnyWidget(
"SelectionBox"));
459 array<SCR_CleanSweepArea> activeAreas = {};
461 int count = GetActiveAreas(activeAreas);
463 for (
int i = 0; i < count; i++)
465 selectionBox.AddItem(activeAreas[i].
GetName());
468 selectionBox.SetCurrentItem(0);
472 override void OnPlayerRegistered(
int playerId)
474 super.OnPlayerRegistered(playerId);
475 Replication.BumpMe();
476 if (areaID != INVALID_AREA_INDEX)
479 ShowAreaSelectionToGameMaster();
484 override void OnPlayerDisconnected(
int playerId,
KickCauseCode cause,
int timeout)
486 super.OnPlayerDisconnected(playerId, cause, timeout);
488 Replication.BumpMe();
489 if (areaID != INVALID_AREA_INDEX || m_iGameMasterID != playerId)
492 PickNewGameMaster(m_iGameMasterID);
493 ShowAreaSelectionToGameMaster();
497 override void EOnInit(IEntity owner)
499 super.EOnInit(owner);
500 m_bAutoPlayerRespawn =
false;
506 gameMode.GetOnPlayerRegistered().Insert(OnPlayerRegistered);
509 m_wRoot =
GetGame().GetWorkspace().CreateWidgets(
"{DE9F713BE2C5D190}UI/layouts/HUD/HintFrame.layout");
510 m_wText = TextWidget.Cast(
m_wRoot.FindAnyWidget(
"MessageText"));
511 TextWidget title = TextWidget.Cast(
m_wRoot.FindAnyWidget(
"TitleText"));
513 title.SetText(
"CLEAN SWEEP");