Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_AutoSpawnLogic.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
2 /*
3  Object responsible for handling respawn logic on the authority side.
4 */
5 [BaseContainerProps(category: "Respawn")]
7 {
8  [Attribute("", uiwidget: UIWidgets.EditBox, category: "Respawn", desc: "Default faction for players to spawn with or empty if none.")]
9  protected FactionKey m_sForcedFaction;
10 
11  [Attribute("", uiwidget: UIWidgets.EditBox, category: "Respawn", desc: "Default loadout for players to spawn with or empty if none")]
12  protected string m_sForcedLoadout;
13 
14  protected ref set<int> m_DisconnectingPlayers = new set<int>();
15 
16  //------------------------------------------------------------------------------------------------
17  protected bool GetForcedFaction(out Faction faction)
18  {
19  if (m_sForcedFaction.IsEmpty())
20  return false;
21 
22  faction = GetGame().GetFactionManager().GetFactionByKey(m_sForcedFaction);
23  if (!faction)
24  {
25  Print(string.Format("Auto spawn logic did not find faction by name: %1", m_sForcedFaction), LogLevel.WARNING);
26  return false;
27  }
28 
29  return true;
30  }
31 
32  //------------------------------------------------------------------------------------------------
33  protected bool GetForcedLoadout(out SCR_BasePlayerLoadout loadout)
34  {
35  if (m_sForcedLoadout.IsEmpty())
36  return false;
37 
38  loadout = GetGame().GetLoadoutManager().GetLoadoutByName(m_sForcedLoadout);
39  if (!loadout)
40  {
41  Print(string.Format("Auto spawn logic did not find loadout by name: %1", m_sForcedLoadout), LogLevel.WARNING);
42  return false;
43  }
44  return true;
45  }
46 
47  //------------------------------------------------------------------------------------------------
48  override void OnInit(SCR_RespawnSystemComponent owner)
49  {
50  super.OnInit(owner);
51  }
52 
53  //------------------------------------------------------------------------------------------------
54  override void OnPlayerRegistered_S(int playerId)
55  {
56  super.OnPlayerRegistered_S(playerId);
57 
58  // In cases where we pushed provided player into disconnecting ones, but never resolved it,
59  // ensure that this player is no longer marked as disconnecting
60  int indexOf = m_DisconnectingPlayers.Find(playerId);
61  if (indexOf != -1)
62  {
63  m_DisconnectingPlayers.Remove(indexOf);
64  }
65 
66  // In certain cases, the player can receive a controlled entity (e.g. spawn from camera position)
67  // during the first game tick and since our spawn operation would usually be enqueued (before this)
68  // and processed only after (the entity is given), it would result in losing the initial entity.
69  // TODO@AS: Possibly improve this on gc->script level
70  GetGame().GetCallqueue().CallLater(DoInitialSpawn, 0, false, playerId);
71  }
72 
73  //------------------------------------------------------------------------------------------------
74  override void OnPlayerDisconnected_S(int playerId, KickCauseCode cause, int timeout)
75  {
76  super.OnPlayerDisconnected_S(playerId, cause, timeout);
77  m_DisconnectingPlayers.Insert(playerId);
78  }
79 
80 
81  //------------------------------------------------------------------------------------------------
82  private void DoInitialSpawn(int playerId)
83  {
84  // Probe reconnection component first
85  IEntity returnedEntity;
86  if (ResolveReconnection(playerId, returnedEntity))
87  {
88  // User was reconnected, their entity was returned
89  return;
90  }
91 
92  // Spawn player the usual way, if no entity has been given yet
93  PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(playerId);
94  IEntity controlledEntity = playerController.GetControlledEntity();
95  if (controlledEntity)
96  return;
97 
98  Spawn(playerId);
99  }
100 
101  //------------------------------------------------------------------------------------------------
102  override void OnPlayerEntityLost_S(int playerId)
103  {
104  super.OnPlayerEntityLost_S(playerId);
105  Spawn(playerId);
106  }
107 
108  //------------------------------------------------------------------------------------------------
109  override void OnPlayerSpawnFailed_S(int playerId)
110  {
111  super.OnPlayerSpawnFailed_S(playerId);
112 
113  int delay = Math.RandomFloat(900, 1100);
114  GetGame().GetCallqueue().CallLater(Spawn, delay, false, playerId);
115  }
116 
117  //------------------------------------------------------------------------------------------------
118  protected void Spawn(int playerId)
119  {
120  // Player is disconnecting (and disappearance of controlled entity started this feedback loop).
121  // Simply ignore such requests as it would create unwanted entities.
122  int indexOf = m_DisconnectingPlayers.Find(playerId);
123  if (indexOf != -1)
124  {
125  m_DisconnectingPlayers.Remove(indexOf);
126  return;
127  }
128 
129  array<Faction> factions = {};
130  GetGame().GetFactionManager().GetFactionsList(factions);
131 
132  Faction targetFaction;
133  if (!GetForcedFaction(targetFaction))
134  targetFaction = factions.GetRandomElement();
135 
136  // Request both
137  if (!GetPlayerFactionComponent_S(playerId).RequestFaction(targetFaction))
138  {
139  // Try again later
140  }
141 
142  SCR_BasePlayerLoadout targetLoadout;
143  if (!GetForcedLoadout(targetLoadout))
144  targetLoadout = GetGame().GetLoadoutManager().GetRandomFactionLoadout(targetFaction);
145 
146  if (!GetPlayerLoadoutComponent_S(playerId).RequestLoadout(targetLoadout))
147  {
148  // Try again later
149  }
150 
151  Faction faction = GetPlayerFactionComponent_S(playerId).GetAffiliatedFaction();
152  if (!faction)
153  {
154  OnPlayerSpawnFailed_S(playerId);
155  return;
156  }
157 
158  SCR_BasePlayerLoadout loadout = GetPlayerLoadoutComponent_S(playerId).GetLoadout();
159  if (!loadout)
160  {
161  OnPlayerSpawnFailed_S(playerId);
162  return;
163  }
164 
165  SCR_SpawnPoint point = SCR_SpawnPoint.GetRandomSpawnPointForFaction(faction.GetFactionKey());
166  if (!point)
167  {
168  OnPlayerSpawnFailed_S(playerId);
169  return;
170  }
171 
172  SCR_SpawnPointSpawnData data = new SCR_SpawnPointSpawnData(loadout.GetLoadoutResource(), point.GetRplId());
173  if (GetPlayerRespawnComponent_S(playerId).CanSpawn(data))
174  DoSpawn(playerId, data);
175  else
176  OnPlayerSpawnFailed_S(playerId);
177  }
178 
179  protected void DoSpawn(int playerId, SCR_SpawnData data)
180  {
181  if (!GetPlayerRespawnComponent_S(playerId).RequestSpawn(data))
182  {
183  // Try again later
184  }
185  }
186 };
SCR_AutoSpawnLogic
Definition: SCR_AutoSpawnLogic.c:6
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
loadout
string loadout
Definition: SCR_ArsenalManagerComponent.c:2
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
SCR_SpawnPoint
Spawn point entity defines positions on which players can possibly spawn.
Definition: SCR_SpawnPoint.c:27
KickCauseCode
KickCauseCode
Definition: KickCauseCode.c:19
SCR_SpawnData
Definition: SCR_SpawnData.c:9
Attribute
typedef Attribute
Post-process effect of scripted camera.
SCR_SpawnPointSpawnData
Definition: SCR_SpawnPointSpawnData.c:2
Faction
Definition: Faction.c:12
CanSpawn
bool CanSpawn(SCR_SpawnData data)
Definition: SCR_RespawnComponent.c:392
SCR_SpawnLogic
Definition: SCR_SpawnLogic.c:11
RequestSpawn
bool RequestSpawn(SCR_SpawnData data)
Definition: SCR_RespawnComponent.c:364
data
Get all prefabs that have the spawner data
Definition: SCR_EntityCatalogManagerComponent.c:305
SCR_BasePlayerLoadout
Definition: SCR_BasePlayerLoadout.c:2
BaseContainerProps
SCR_AIGoalReaction_Follow BaseContainerProps
Handles insects that are supposed to be spawned around selected prefabs defined in prefab names array...
Definition: SCR_AIGoalReaction.c:468
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180