140 #define GAME_MODE_DEBUG
143 #ifdef GAME_MODE_DEBUG
144 static bool s_DebugRegistered =
false;
147 const static string WB_GAME_MODE_CATEGORY =
"Game Mode";
149 protected ref ScriptInvoker Event_OnGameStart =
new ScriptInvoker();
150 protected ref ScriptInvoker m_OnGameEnd =
new ScriptInvoker();
153 protected ref ScriptInvokerBase<SCR_BaseGameMode_PlayerId> m_OnPlayerAuditSuccess =
new ScriptInvokerBase<SCR_BaseGameMode_PlayerId>();
154 protected ref ScriptInvokerBase<SCR_BaseGameMode_PlayerId> m_OnPlayerAuditFail =
new ScriptInvokerBase<SCR_BaseGameMode_PlayerId>();
155 protected ref ScriptInvokerBase<SCR_BaseGameMode_PlayerId> m_OnPlayerAuditTimeouted =
new ScriptInvokerBase<SCR_BaseGameMode_PlayerId>();
156 protected ref ScriptInvokerBase<SCR_BaseGameMode_PlayerId> m_OnPlayerAuditRevived =
new ScriptInvokerBase<SCR_BaseGameMode_PlayerId>();
157 protected ref ScriptInvokerBase<SCR_BaseGameMode_PlayerId> m_OnPlayerConnected =
new ScriptInvokerBase<SCR_BaseGameMode_PlayerId>();
158 protected ref ScriptInvokerBase<SCR_BaseGameMode_PlayerId> m_OnPlayerRegistered =
new ScriptInvokerBase<SCR_BaseGameMode_PlayerId>();
159 protected ref ScriptInvokerBase<SCR_BaseGameMode_OnPlayerDisconnected> m_OnPlayerDisconnected =
new ScriptInvokerBase<SCR_BaseGameMode_OnPlayerDisconnected>();
160 protected ref ScriptInvokerBase<SCR_BaseGameMode_OnPlayerDisconnected> m_OnPostCompPlayerDisconnected =
new ScriptInvokerBase<SCR_BaseGameMode_OnPlayerDisconnected>();
161 protected ref ScriptInvokerBase<SCR_BaseGameMode_PlayerIdAndEntity> m_OnPlayerSpawned =
new ScriptInvokerBase<SCR_BaseGameMode_PlayerIdAndEntity>();
162 protected ref ScriptInvokerBase<SCR_BaseGameMode_OnPlayerKilled> m_OnPlayerKilled =
new ScriptInvokerBase<SCR_BaseGameMode_OnPlayerKilled>();
163 protected ref ScriptInvokerBase<SCR_BaseGameMode_PlayerIdAndEntity> m_OnPlayerDeleted =
new ScriptInvokerBase<SCR_BaseGameMode_PlayerIdAndEntity>();
164 protected ref ScriptInvokerBase<SCR_BaseGameMode_OnPlayerRoleChanged> m_OnPlayerRoleChange =
new ScriptInvokerBase<SCR_BaseGameMode_OnPlayerRoleChanged>();
166 protected ref ScriptInvoker m_OnWorldPostProcess =
new ScriptInvoker();
167 protected ref ScriptInvoker m_OnControllableSpawned =
new ScriptInvoker();
168 protected ref ScriptInvoker m_OnControllableDestroyed =
new ScriptInvoker();
169 protected ref ScriptInvoker m_OnControllableDeleted =
new ScriptInvoker();
170 protected ref ScriptInvoker m_OnGameModeEnd =
new ScriptInvoker();
172 protected ref ScriptInvokerBase<SCR_BaseGameMode_OnResourceEnabledChanged> m_OnResourceTypeEnabledChanged;
178 [
Attribute(
"0", uiwidget: UIWidgets.Flags,
"Test Game Flags for when you run mission via WE.",
"", ParamEnumArray.FromEnum(
EGameFlags), WB_GAME_MODE_CATEGORY)]
181 [
Attribute(
"1", uiwidget: UIWidgets.CheckBox,
"When false, then Game mode need to handle its very own spawning. If true, then simple default logic is used to spawn and respawn automatically.",
category: WB_GAME_MODE_CATEGORY)]
182 protected bool m_bAutoPlayerRespawn;
184 [
Attribute(
"1", uiwidget: UIWidgets.CheckBox,
"When true, allows players to freely swap their faction after initial assignment.",
category: WB_GAME_MODE_CATEGORY)]
185 protected bool m_bAllowFactionChange;
187 [
Attribute(
"30", UIWidgets.Slider,
params:
"0 600 1",
desc:
"Time in seconds after which the mission is reloaded upon completion or 0 to disable it.",
category: WB_GAME_MODE_CATEGORY)]
188 private float m_fAutoReloadTime;
196 [
RplProp(onRplName:
"OnGameStateChanged")]
203 [
Attribute(
"1", uiwidget: UIWidgets.CheckBox,
"If checked the elapsed time will only advance if at least one player is present on the server.",
category: WB_GAME_MODE_CATEGORY)]
204 protected bool m_bAdvanceTimeRequiresPlayers;
210 [
RplProp(condition: RplCondition.NoOwner)]
211 protected float m_fTimeElapsed;
215 protected bool m_bAllowControls =
true;
218 protected float m_fTimeCorrectionInterval = 10.0;
221 protected float m_fLastTimeCorrection;
225 protected bool m_bIsHosted;
231 protected RplComponent m_RplComponent;
232 protected SCR_GameModeHealthSettings m_pGameModeHealthSettings;
233 protected SCR_RespawnSystemComponent m_pRespawnSystemComponent;
240 protected ref array<SCR_BaseGameModeComponent> m_aAdditionalGamemodeComponents =
new array<SCR_BaseGameModeComponent>();
243 protected ref map<int, vector> m_mPlayerSpawnPosition =
new map<int, vector>();
246 protected ref map<SCR_EGameModeState, SCR_BaseGameModeStateComponent> m_mStateComponents =
new map<SCR_EGameModeState, SCR_BaseGameModeStateComponent>();
250 protected bool m_bUseSpawnPreload;
256 [
Attribute(
desc:
"List of disabled Resource Types in the GameMode.", uiwidget: UIWidgets.SearchComboBox, enums: ParamEnumArray.FromEnum(
EResourceType),
category:
"Game Mode"),
RplProp(onRplName:
"OnResourceTypeEnabledChanged")]
257 protected ref array<EResourceType> m_aDisabledResourceTypes;
260 protected WorldTimestamp m_GameEndTimeStamp =
null;
272 int GetDisabledResourceTypes(inout notnull array<EResourceType> disabledResourceTypes)
275 return disabledResourceTypes.Count();;
288 if ((
index < 0) == enable)
296 Replication.BumpMe();
300 OnResourceTypeEnabledChanged();
305 SCR_NotificationsComponent.SendToEveryone(
ENotification.EDITOR_ATTRIBUTES_ENABLE_GLOBAL_SUPPLY_USAGE, playerID);
307 SCR_NotificationsComponent.SendToEveryone(
ENotification.EDITOR_ATTRIBUTES_DISABLE_GLOBAL_SUPPLY_USAGE, playerID);
313 protected void OnResourceTypeEnabledChanged()
321 ScriptInvokerBase<SCR_BaseGameMode_OnResourceEnabledChanged> GetOnResourceTypeEnabledChanged()
330 bool CanStartSpawnPreload()
333 return (!world.IsGameTimePaused() && m_bUseSpawnPreload);
360 sealed
bool IsMaster()
370 float GetElapsedTime()
382 SCR_BaseGameModeStateComponent stateComponent = GetStateComponent(
SCR_EGameModeState.GAME);
384 return stateComponent.GetDuration();
394 float GetRemainingTime()
396 float timeLimit = GetTimeLimit();
397 if (!IsRunning() || timeLimit <= 0)
400 float time = timeLimit - GetElapsedTime();
421 protected void OnGameStateChanged()
432 OnGameModeEnd(m_pGameEndData);
435 component.OnGameModeEnd(m_pGameEndData);
443 component.OnGameModeStart();
451 component.OnGameStateChanged(newState);
456 void CachePlayerSpawnPosition(
int playerID, vector
position)
458 m_mPlayerSpawnPosition.Set(playerID,
position);
466 SCR_RespawnSystemComponent GetRespawnSystemComponent()
468 return m_pRespawnSystemComponent;
472 SCR_GameModeHealthSettings GetGameModeHealthSettings()
474 return m_pGameModeHealthSettings;
484 return m_ScoringSystemComponent;
499 Print(
"Trying to start a gamemode that is already running.", LogLevel.WARNING);
505 Replication.BumpMe();
508 OnGameStateChanged();
521 protected bool CanStartGameMode()
523 SCR_BaseGameModeStateComponent pregame = GetStateComponent(
SCR_EGameModeState.PREGAME);
546 Print(
"Trying to end a gamemode that is not running.", LogLevel.WARNING);
553 m_pGameEndData = endData;
555 Replication.BumpMe();
558 OnGameStateChanged();
570 return m_pGameEndData;
573 ScriptInvoker GetOnGameStart()
575 return Event_OnGameStart;
577 ScriptInvoker GetOnGameEnd()
581 ScriptInvokerBase<SCR_BaseGameMode_PlayerId> GetOnPlayerAuditSuccess()
583 return m_OnPlayerAuditSuccess;
585 ScriptInvokerBase<SCR_BaseGameMode_PlayerId> GetOnPlayerAuditFail()
587 return m_OnPlayerAuditFail;
589 ScriptInvokerBase<SCR_BaseGameMode_PlayerId> GetOnPlayerAuditTimeouted()
591 return m_OnPlayerAuditTimeouted;
593 ScriptInvokerBase<SCR_BaseGameMode_PlayerId> GetOnPlayerAuditRevived()
595 return m_OnPlayerAuditRevived;
597 ScriptInvokerBase<SCR_BaseGameMode_PlayerId> GetOnPlayerConnected()
599 return m_OnPlayerConnected;
601 ScriptInvokerBase<SCR_BaseGameMode_PlayerId> GetOnPlayerRegistered()
603 return m_OnPlayerRegistered;
605 ScriptInvokerBase<SCR_BaseGameMode_OnPlayerDisconnected> GetOnPlayerDisconnected()
607 return m_OnPlayerDisconnected;
613 ScriptInvokerBase<SCR_BaseGameMode_OnPlayerDisconnected> GetOnPostCompPlayerDisconnected()
615 return m_OnPostCompPlayerDisconnected;
617 ScriptInvokerBase<SCR_BaseGameMode_PlayerIdAndEntity> GetOnPlayerSpawned()
619 return m_OnPlayerSpawned;
621 ScriptInvokerBase<SCR_BaseGameMode_OnPlayerKilled> GetOnPlayerKilled()
623 return m_OnPlayerKilled;
625 ScriptInvokerBase<SCR_BaseGameMode_PlayerIdAndEntity> GetOnPlayerDeleted()
627 return m_OnPlayerDeleted;
629 ScriptInvokerBase<SCR_BaseGameMode_OnPlayerRoleChanged> GetOnPlayerRoleChange()
631 return m_OnPlayerRoleChange;
633 ScriptInvoker GetOnWorldPostProcess()
635 return m_OnWorldPostProcess;
637 ScriptInvoker GetOnControllableSpawned()
639 return m_OnControllableSpawned;
641 ScriptInvoker GetOnControllableDestroyed()
643 return m_OnControllableDestroyed;
645 ScriptInvoker GetOnControllableDeleted()
647 return m_OnControllableDeleted;
653 ScriptInvoker GetOnGameModeEnd()
655 return m_OnGameModeEnd;
664 protected void OnGameModeStart()
667 if (IsGameModeStatisticsEnabled())
669 if (!SCR_GameModeStatistics.IsRecording())
670 SCR_GameModeStatistics.StartRecording();
686 m_GameEndTimeStamp = world.GetLocalTimestamp();
688 m_OnGameModeEnd.Invoke(endData);
691 if (IsGameModeStatisticsEnabled())
693 if (SCR_GameModeStatistics.IsRecording())
694 SCR_GameModeStatistics.StopRecording();
699 float reloadTime = GetAutoReloadDelay();
701 GetGame().GetCallqueue().CallLater(RestartSession, reloadTime * 1000.0,
false);
708 WorldTimestamp GetGameEndTimeStamp()
710 return m_GameEndTimeStamp;
717 float GetAutoReloadDelay()
720 string autoReloadTimeString;
721 if (System.GetCLIParam(
"autoreload", autoReloadTimeString))
722 return Math.Clamp(autoReloadTimeString.ToFloat(), 0.0, 600.0);
724 return m_fAutoReloadTime;
730 protected void RestartSession()
735 Print(
"SCR_BaseGameMode::RequestScenarioRestart()", LogLevel.DEBUG);
738 Print(
"SCR_BaseGameMode::RequestScenarioRestart() successfull server reload requested!", LogLevel.DEBUG);
743 protected override void OnGameStart()
745 BackendApi backendApi =
GetGame().GetBackendApi();
748 backendApi.NewSession();
751 Event_OnGameStart.Invoke();
757 m_OnGameEnd.Invoke();
766 bool IsFactionChangeAllowed()
768 return m_bAllowFactionChange;
772 override void OnPlayerAuditSuccess(
int iPlayerID)
774 #ifdef RESPAWN_COMPONENT_VERBOSE
775 Print(
"SCR_BaseGameMode::OnPlayerAuditSuccess - playerId: " + iPlayerID, LogLevel.DEBUG);
778 super.OnPlayerAuditSuccess(iPlayerID);
779 m_OnPlayerAuditSuccess.Invoke(iPlayerID);
784 comp.OnPlayerAuditSuccess(iPlayerID);
789 override void OnPlayerAuditFail(
int iPlayerID)
791 #ifdef RESPAWN_COMPONENT_VERBOSE
792 Print(
"SCR_BaseGameMode::OnPlayerAuditFail - playerId: " + iPlayerID, LogLevel.DEBUG);
795 super.OnPlayerAuditFail(iPlayerID);
796 m_OnPlayerAuditFail.Invoke(iPlayerID);
801 comp.OnPlayerAuditFail(iPlayerID);
806 override void OnPlayerAuditTimeouted(
int iPlayerID)
808 super.OnPlayerAuditTimeouted(iPlayerID);
809 m_OnPlayerAuditTimeouted.Invoke(iPlayerID);
814 comp.OnPlayerAuditTimeouted(iPlayerID);
819 override void OnPlayerAuditRevived(
int iPlayerID)
821 super.OnPlayerAuditRevived(iPlayerID);
822 m_OnPlayerAuditRevived.Invoke(iPlayerID);
827 comp.OnPlayerAuditRevived(iPlayerID);
836 override void OnPlayerConnected(
int playerId)
840 m_bIsHosted =
GetGame().GetPlayerManager().GetPlayerController(playerId).GetRplIdentity() == RplIdentity.Local();
841 Replication.BumpMe();
844 super.OnPlayerConnected(playerId);
845 m_OnPlayerConnected.Invoke(playerId);
849 if (m_pRespawnSystemComponent && (RplSession.Mode() != RplMode.Dedicated || System.IsCLIParam(
"nobackend")))
851 #ifdef RESPAWN_COMPONENT_VERBOSE
852 Print(
"SCR_BaseGameMode::OnPlayerConnected - playerId: " + playerId, LogLevel.DEBUG);
859 comp.OnPlayerConnected(playerId);
865 #ifdef TREE_DESTRUCTION
866 int count = SCR_DestructibleTree.DestructibleTrees.Count();
867 for (
int i = 0; i < count; i++)
869 SCR_DestructibleTree.DestructibleTrees[i].OnPlayerConnected();
879 protected override void OnPlayerDisconnected(
int playerId,
KickCauseCode cause,
int timeout)
881 super.OnPlayerDisconnected(playerId, cause, timeout);
882 m_OnPlayerDisconnected.Invoke(playerId, cause, timeout);
887 m_pRespawnSystemComponent.OnPlayerDisconnected_S(playerId, cause, timeout);
891 comp.OnPlayerDisconnected(playerId, cause, timeout);
894 m_OnPostCompPlayerDisconnected.Invoke(playerId, cause, timeout);
898 IEntity controlledEntity =
GetGame().GetPlayerManager().GetPlayerControlledEntity(playerId);
899 if (controlledEntity)
905 CharacterControllerComponent charController = CharacterControllerComponent.Cast(controlledEntity.FindComponent(CharacterControllerComponent));
908 charController.SetMovement(0, vector.Forward);
911 CompartmentAccessComponent compAccess = CompartmentAccessComponent.Cast(controlledEntity.FindComponent(CompartmentAccessComponent));
914 BaseCompartmentSlot compartment = compAccess.GetCompartment();
919 CarControllerComponent carController = CarControllerComponent.Cast(compartment.GetVehicle().FindComponent(CarControllerComponent));
922 carController.Shutdown();
923 carController.StopEngine(
false);
928 CarControllerComponent_SA carController = CarControllerComponent_SA.Cast(compartment.GetVehicle().FindComponent(CarControllerComponent_SA));
931 carController.Shutdown();
932 carController.StopEngine(
false);
942 RplComponent.DeleteRplEntity(controlledEntity,
false);
952 protected override void OnPlayerRegistered(
int playerId)
954 super.OnPlayerRegistered(playerId);
955 m_OnPlayerRegistered.Invoke(playerId);
960 m_pRespawnSystemComponent.OnPlayerRegistered_S(playerId);
964 comp.OnPlayerRegistered(playerId);
968 if (IsGameModeStatisticsEnabled())
969 SCR_GameModeStatistics.RecordConnection(playerId,
GetGame().GetPlayerManager().GetPlayerName(playerId));
979 [
Obsolete(
"Use SCR_BaseGameMode.OnPlayerSpawnFinalize_S")]
980 protected override void OnPlayerSpawned(
int playerId, IEntity controlledEntity)
982 super.OnPlayerSpawned(playerId, controlledEntity);
983 m_OnPlayerSpawned.Invoke(playerId, controlledEntity);
987 comp.OnPlayerSpawned(playerId, controlledEntity);
991 if (IsGameModeStatisticsEnabled())
993 FactionAffiliationComponent fac = FactionAffiliationComponent.Cast(controlledEntity.FindComponent(FactionAffiliationComponent));
994 SCR_GameModeStatistics.RecordSpawn(playerId, fac.GetAffiliatedFaction().GetFactionColor().PackToInt());
1000 protected override bool HandlePlayerKilled(
int playerId, IEntity playerEntity, IEntity killerEntity, notnull
Instigator killer)
1006 if (!comp.HandlePlayerKilled(playerId, playerEntity, killerEntity, killer))
1008 OnPlayerKilledHandled(playerId, playerEntity, killerEntity, killer);
1019 protected override void OnPlayerKilled(
int playerId, IEntity playerEntity, IEntity killerEntity, notnull
Instigator killer)
1021 super.OnPlayerKilled(playerId, playerEntity, killerEntity, killer);
1023 m_OnPlayerKilled.Invoke(playerId, playerEntity, killerEntity, killer);
1028 m_pRespawnSystemComponent.OnPlayerKilled_S(playerId, playerEntity, killerEntity, killer);
1033 comp.OnPlayerKilled(playerId, playerEntity, killerEntity, killer);
1037 if (IsGameModeStatisticsEnabled())
1038 SCR_GameModeStatistics.RecordDeath(playerId, playerEntity, killerEntity, killer);
1044 protected void OnPlayerKilledHandled(
int playerId, IEntity playerEntity, IEntity killerEntity, notnull
Instigator killer)
1047 comp.OnPlayerKilledHandled(playerId, playerEntity, killerEntity, killer);
1051 protected void OnPlayerDeleted(
int playerId, IEntity player)
1056 m_pRespawnSystemComponent.OnPlayerDeleted_S(playerId);
1059 m_OnPlayerDeleted.Invoke(playerId, player);
1064 comp.OnPlayerDeleted(playerId, player);
1074 protected override void OnPlayerRoleChange(
int playerId,
EPlayerRole roleFlags)
1076 super.OnPlayerRoleChange(playerId, roleFlags);
1077 m_OnPlayerRoleChange.Invoke(playerId, roleFlags);
1082 comp.OnPlayerRoleChange(playerId, roleFlags);
1091 override event void OnWorldPostProcess(World world)
1093 super.OnWorldPostProcess(world);
1094 m_OnWorldPostProcess.Invoke(world);
1098 comp.OnWorldPostProcess(world);
1107 protected override void OnControllableSpawned(IEntity entity)
1109 super.OnControllableSpawned(entity);
1110 m_OnControllableSpawned.Invoke(entity);
1114 comp.OnControllableSpawned(entity);
1125 protected override void OnControllableDestroyed(IEntity entity, IEntity killerEntity, notnull
Instigator instigator)
1127 super.OnControllableDestroyed(entity, killerEntity, instigator);
1128 m_OnControllableDestroyed.Invoke(entity, killerEntity, instigator);
1132 comp.OnControllableDestroyed(entity, killerEntity, instigator);
1143 protected override void OnControllableDeleted(IEntity entity)
1145 super.OnControllableDeleted(entity);
1146 m_OnControllableDeleted.Invoke(entity);
1150 comp.OnControllableDeleted(entity);
1154 int playerId =
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(entity);
1156 OnPlayerDeleted(playerId, entity);
1168 void OnSpawnPlayerEntityFailure_S(SCR_SpawnRequestComponent requestComponent, SCR_SpawnHandlerComponent handlerComponent, IEntity entity,
SCR_SpawnData data,
SCR_ESpawnResult reason)
1171 component.OnSpawnPlayerEntityFailure_S(requestComponent, handlerComponent, entity,
data, reason);
1179 void OnPlayerEntityChanged_S(
int playerId, IEntity previousEntity, IEntity newEntity)
1196 bool PreparePlayerEntity_S(SCR_SpawnRequestComponent requestComponent, SCR_SpawnHandlerComponent handlerComponent,
SCR_SpawnData data, IEntity entity)
1205 if (!component.PreparePlayerEntity_S(requestComponent, handlerComponent,
data, entity))
1224 void OnPlayerSpawnFinalize_S(SCR_SpawnRequestComponent requestComponent, SCR_SpawnHandlerComponent handlerComponent,
SCR_SpawnData data, IEntity entity)
1229 OnPlayerSpawnOnPoint_S(requestComponent, handlerComponent, entity, spawnPointData);
1233 component.OnPlayerSpawnFinalize_S(requestComponent, handlerComponent,
data, entity);
1237 && loadoutComp && loadoutComp.GetLoadout())
1238 loadoutComp.GetLoadout().OnLoadoutSpawned(
GenericEntity.Cast(entity), requestComponent.GetPlayerId());
1240 m_OnPlayerSpawned.Invoke(requestComponent.GetPlayerId(), entity);
1249 void OnPlayerSpawnOnPoint_S(SCR_SpawnRequestComponent requestComponent, SCR_SpawnHandlerComponent handlerComponent, IEntity entity,
SCR_SpawnPointSpawnData spawnPointData)
1283 if (m_RespawnTimerComponent)
1285 int playerId = requestComponent.GetPlayerId();
1288 if (m_RespawnTimerComponent.IsPlayerEnqueued(playerId))
1290 float spawnPointTime = 0;
1294 spawnPointTime = spData.GetSpawnPoint().GetRespawnTime();
1297 if (!m_RespawnTimerComponent.GetCanPlayerSpawn(playerId, spawnPointTime))
1311 int GetPlayerRemainingRespawnTime(
int playerID)
1314 if (m_RespawnTimerComponent)
1315 return m_RespawnTimerComponent.GetPlayerRemainingTime(playerID);
1321 override bool RplSave(ScriptBitWriter writer)
1324 writer.WriteIntRange(gameFlags, 0, (
EGameFlags.Last<<1)-1);
1330 override bool RplLoad(ScriptBitReader reader)
1333 reader.ReadIntRange(gameFlags, 0, (
EGameFlags.Last<<1)-1);
1335 GetGame().SetGameFlags(gameFlags,
true);
1340 #ifdef GAME_MODE_DEBUG
1344 void Diag_DrawPlayersWindow()
1347 array<int> connectedPlayers = {};
1348 GetGame().GetPlayerManager().GetPlayers(connectedPlayers);
1350 array<int> disconnectedPlayers = {};
1351 GetGame().GetPlayerManager().GetDisconnectedPlayers(disconnectedPlayers);
1353 DbgUI.Begin(
"SCR_BaseGameMode: Connected players");
1355 for (
int i = 0, cnt = connectedPlayers.Count(); i < cnt; i++)
1357 int playerId = connectedPlayers[i];
1358 Diag_DrawPlayerInfo(playerId);
1362 DbgUI.Begin(
"SCR_BaseGameMode: Disconnected players");
1364 for (
int i = 0, cnt = disconnectedPlayers.Count(); i < cnt; i++)
1366 int playerId = disconnectedPlayers[i];
1367 Diag_DrawPlayerInfo(playerId);
1376 void Diag_DrawPlayerInfo(
int playerId)
1378 string tmp =
string.Format(
"Player %1: (name: %2)", playerId,
GetGame().GetPlayerManager().GetPlayerName(playerId));
1379 array<string> extra = {};
1385 string factionKey =
"None";
1386 Faction faction = factionManager.GetPlayerFaction(playerId);
1389 factionKey = faction.GetFactionKey();
1392 extra.Insert(
string.Format(
"Faction: %1", factionKey));
1399 string loadoutKey =
"None";
1403 loadoutKey =
loadout.GetLoadoutName();
1406 extra.Insert(
string.Format(
"Loadout: %1", loadoutKey));
1410 if (!extra.IsEmpty())
1412 const string separator =
"\n ";
1413 for (
int i = 0, count = extra.Count(); i < count; i++)
1415 tmp +=
string.Format(
"%1%2", separator, extra[i] );
1424 void Diag_DrawControlledEntitiesWindow()
1426 array<int> allPlayers = {};
1427 GetGame().GetPlayerManager().GetAllPlayers(allPlayers);
1429 DbgUI.Begin(
"SCR_BaseGameMode: Controlled Entities");
1431 for (
int i = 0, cnt = allPlayers.Count(); i < cnt; i++)
1433 int playerId = allPlayers[i];
1434 Diag_DrawControlledEntityInfo(playerId);
1443 void Diag_DrawControlledEntityInfo(
int playerId)
1445 string tmp =
string.Format(
"Player %1: (name: %2)", playerId,
GetGame().GetPlayerManager().GetPlayerName(playerId));
1446 array<string> extra = {};
1449 if (
GetGame().GetPlayerManager().IsPlayerConnected(playerId))
1451 extra.Insert(
"IsConnected: True");
1454 extra.Insert(
"IsConnected: False");
1457 IEntity controlledEntity =
GetGame().GetPlayerManager().GetPlayerControlledEntity(playerId);
1458 if (controlledEntity)
1460 extra.Insert(
string.Format(
"Entity: %1", controlledEntity));
1462 RplComponent rplComponent = RplComponent.Cast(controlledEntity.FindComponent(RplComponent));
1465 extra.Insert(
string.Format(
"RplId: %1", rplComponent.Id()));
1470 extra.Insert(
"Entity: None");
1475 if (!extra.IsEmpty())
1477 const string separator =
"\n ";
1478 for (
int i = 0, count = extra.Count(); i < count; i++)
1480 tmp +=
string.Format(
"%1%2", separator, extra[i] );
1489 void Diag_DrawComponentsWindow()
1491 DbgUI.Begin(
"SCR_BaseGameMode: Components");
1493 int numComponents = m_aAdditionalGamemodeComponents.Count();
1494 DbgUI.Text(
string.Format(
"NumComponents: %1", numComponents));
1496 for (
int i = 0; i < numComponents; i++)
1498 Diag_DrawComponentInfo(i, m_aAdditionalGamemodeComponents[i]);
1508 DbgUI.Text(
string.Format(
"%1: %2",
index, component));
1513 void Diag_DrawGameModeWindow()
1515 DbgUI.Begin(
"SCR_BaseGameMode");
1517 string elapsedTime =
string.Format(
"Elapsed time: %1 s", GetElapsedTime());
1518 DbgUI.Text(elapsedTime);
1520 string running =
string.Format(
"IsRunning: %1", IsRunning());
1521 DbgUI.Text(running);
1526 string flags =
string.Format(
"TestFlags: %1 (%2)",
SCR_Enum.FlagsToString(
EGameFlags, m_eGameState), m_eGameState);
1532 DbgUI.Text(
"Authority details:");
1534 float autoReloadDelay = GetAutoReloadDelay();
1535 if (autoReloadDelay > 0)
1537 DbgUI.Text(
string.Format(
"Auto reload: %1 seconds.", autoReloadDelay));
1541 DbgUI.Text(
"Auto reload: Disabled.");
1546 if (DbgUI.Button(
"End Session"))
1549 if (DbgUI.Button(
"Restart Session"))
1559 void HandleOnTasksInitialized();
1564 protected void SetLocalControls(
bool enabled)
1566 PlayerController playerController =
GetGame().GetPlayerController();
1567 if (playerController)
1569 IEntity controlledEntity = playerController.GetControlledEntity();
1570 if (controlledEntity)
1572 ChimeraCharacter character = ChimeraCharacter.Cast(controlledEntity);
1575 CharacterControllerComponent controller = character.GetCharacterController();
1578 bool doDisable = !enabled;
1579 controller.SetDisableWeaponControls(doDisable);
1580 controller.SetDisableMovementControls(doDisable);
1588 private float m_fLastRecordTime;
1590 private float m_fLastFlushTime;
1591 private float m_fFlushRecordInterval = 10000;
1594 private void UpdateStatistics(IEntity owner)
1597 float timeStamp = owner.GetWorld().GetWorldTime();
1598 if (timeStamp > m_fLastRecordTime + SCR_GameModeStatistics.RECORD_INTERVAL_MS)
1600 m_fLastRecordTime = timeStamp;
1604 array<int> players = {};
1605 pm.GetPlayers(players);
1607 foreach (
int pid : players)
1609 IEntity ctrlEnt = pm.GetPlayerControlledEntity(pid);
1613 SCR_GameModeStatistics.RecordMovement(ctrlEnt, pid);
1620 array<AIAgent> aiAgents = {};
1621 aiWorld.GetAIAgents(aiAgents);
1622 foreach (AIAgent agent : aiAgents)
1624 SCR_GameModeStatistics.RecordAILOD(agent);
1631 if (timeStamp > m_fLastFlushTime + m_fFlushRecordInterval)
1633 m_fLastFlushTime = timeStamp;
1634 if (IsGameModeStatisticsEnabled())
1636 if (SCR_GameModeStatistics.IsRecording())
1637 SCR_GameModeStatistics.Flush();
1646 bool GetAllowControls()
1648 return m_bAllowControls;
1654 protected bool GetAllowControlsTarget()
1656 SCR_BaseGameModeStateComponent stateComponent = GetStateComponent(GetState());
1658 return stateComponent.GetAllowControls();
1667 SCR_BaseGameModeStateComponent stateComponent;
1668 if (m_mStateComponents.Find(state, stateComponent))
1669 return stateComponent;
1677 override void EOnFrame(IEntity owner,
float timeSlice)
1680 if (IsGameModeStatisticsEnabled())
1681 UpdateStatistics(owner);
1684 if (m_bUseSpawnPreload && m_SpawnPreload)
1685 HandleSpawnPreload(timeSlice);
1688 SCR_BaseGameModeStateComponent pregameComponent = GetStateComponent(
SCR_EGameModeState.PREGAME);
1691 bool isRunning = IsRunning();
1692 if (isRunning || isPregame)
1694 bool canAdvanceTime =
true;
1700 if (m_bAdvanceTimeRequiresPlayers)
1702 int playerCount =
GetGame().GetPlayerManager().GetPlayerCount();
1703 if (playerCount == 0)
1704 canAdvanceTime =
false;
1714 if (
m_fTimeElapsed >= m_fLastTimeCorrection + m_fTimeCorrectionInterval)
1716 Replication.BumpMe();
1723 if (isPregame && (!pregameComponent || pregameComponent.CanAdvanceState(
SCR_EGameModeState.GAME)))
1725 if (CanStartGameMode())
1733 SCR_BaseGameModeStateComponent gameState = GetStateComponent(
SCR_EGameModeState.GAME);
1747 bool shouldAllowControls = GetAllowControlsTarget();
1748 if (shouldAllowControls != m_bAllowControls)
1750 m_bAllowControls = shouldAllowControls;
1751 Replication.BumpMe();
1757 bool allowControls = GetAllowControls();
1758 SetLocalControls(allowControls);
1760 #ifdef GAME_MODE_DEBUG
1763 Diag_DrawGameModeWindow();
1764 Diag_DrawComponentsWindow();
1765 Diag_DrawPlayersWindow();
1766 Diag_DrawControlledEntitiesWindow();
1772 override void EOnInit(IEntity owner)
1778 GetGame().SetGameFlags(m_eTestGameFlags,
false);
1787 set<EResourceType> duplicateRemoveSet =
new set<EResourceType>();
1791 duplicateRemoveSet.Insert(resourceType);
1802 m_RplComponent = RplComponent.Cast(owner.FindComponent(RplComponent));
1803 m_pRespawnSystemComponent = SCR_RespawnSystemComponent.Cast(owner.FindComponent(SCR_RespawnSystemComponent));
1806 m_pGameModeHealthSettings = SCR_GameModeHealthSettings.Cast(owner.FindComponent(SCR_GameModeHealthSettings));
1809 Print(
"SCR_BaseGameMode is missing RplComponent!", LogLevel.ERROR);
1810 if (!m_pRespawnSystemComponent)
1811 Print(
"SCR_BaseGameMode is missing SCR_RespawnSystemComponent!", LogLevel.WARNING);
1813 if (!m_aAdditionalGamemodeComponents)
1814 m_aAdditionalGamemodeComponents =
new array<SCR_BaseGameModeComponent>();
1816 array<Managed> additionalComponents =
new array<Managed>();
1819 m_aAdditionalGamemodeComponents.Clear();
1820 for (
int i = 0; i < count; i++)
1823 m_aAdditionalGamemodeComponents.Insert(comp);
1827 array<Managed> stateComponents =
new array<Managed>();
1828 int stateCount = owner.FindComponents(SCR_BaseGameModeStateComponent, stateComponents);
1829 for (
int i = 0; i < stateCount; i++)
1831 SCR_BaseGameModeStateComponent stateComponent = SCR_BaseGameModeStateComponent.Cast(stateComponents[i]);
1836 Print(
"Skipping one of SCR_BaseGameStateComponent(s), invalid affiliated state!", LogLevel.ERROR);
1840 if (m_mStateComponents.Contains(state))
1843 Print(
"Skipping one of SCR_BaseGameStateComponent(s), duplicate component for state: " + stateName +
"!", LogLevel.ERROR);
1847 m_mStateComponents.Insert(state, stateComponent);
1858 if (!m_OnPreloadFinished)
1861 return m_OnPreloadFinished;
1867 void StartSpawnPreload(vector
position)
1870 if (!m_SpawnPreload && m_OnPreloadFinished)
1871 m_OnPreloadFinished.Invoke();
1876 protected void HandleSpawnPreload(
float timeSlice)
1878 bool finished = m_SpawnPreload.Update(timeSlice);
1881 m_SpawnPreload =
null;
1882 if (m_OnPreloadFinished)
1883 m_OnPreloadFinished.Invoke();
1891 #ifdef GAME_MODE_DEBUG
1892 if (!s_DebugRegistered)
1894 DiagMenu.RegisterMenu(
SCR_DebugMenuID.DEBUGUI_GAME_MODE_MENU,
"GameMode",
"");
1895 DiagMenu.RegisterBool(
SCR_DebugMenuID.DEBUGUI_GAME_MODE,
"",
"Game Mode",
"GameMode");
1896 s_DebugRegistered =
true;
1901 SetEventMask(EntityEvent.INIT | EntityEvent.FRAME);
1908 #ifdef GAME_MODE_DEBUG
1910 s_DebugRegistered =
false;
1914 if (SCR_GameModeStatistics.IsRecording())
1915 SCR_GameModeStatistics.StopRecording();
1922 private bool IsGameModeStatisticsEnabled()
1928 return GetGame().InPlayMode();