public void Run(GameFlags flags = GameFlags.None, string[] args = null) { if (instance != null) { throw new InvalidOperationException("Cannot run a game while one instance is already running. If you wish to run multiple game instances - use AssemblyLoadContexts to isolate engine & same game assemblies from each other."); } instance = this; Flags = flags; StartArguments = Array.AsReadOnly(args); NoWindow = Flags.HasFlag(GameFlags.NoWindow); NoGraphics = Flags.HasFlag(GameFlags.NoGraphics); NoAudio = Flags.HasFlag(GameFlags.NoAudio); DllResolver.Init(); AssemblyCache.Init(); InitializeModules(); Debug.Log("Loading engine..."); //TODO: Move this. assetsPath = "Assets" + Path.DirectorySeparatorChar; if (args != null) { string joinedArgs = string.Join(" ", args); var matches = RegexCache.commandArguments.Matches(joinedArgs); var dict = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase); foreach (Match match in matches) { dict[match.Groups[1].Value] = match.Groups[2].Value; } if (dict.TryGetValue("assetspath", out string path)) { assetsPath = path ?? throw new ArgumentException("Expected a directory path after command line argument 'assetspath'."); } } assetsPath = Path.GetFullPath(assetsPath); AppDomain.CurrentDomain.ProcessExit += ApplicationQuit; moduleHooks.PreInit?.Invoke(); PreInit(); preInitDone = true; Init(); if (!Flags.HasFlag(GameFlags.ManualUpdate)) { UpdateLoop(); Dispose(); } }
protected override void OnPlayerTeamChanged(BasePlayer player, Team prevTeam, Team newTeam) { Console.Print(OutputLevel.Debug, "game", $"team join player={player.ClientId}:{Server.ClientName(player.ClientId)} team={newTeam}"); if (prevTeam != Team.Spectators || newTeam != Team.Spectators) { UnbalancedTick = BalanceCheck; } if (prevTeam != Team.Spectators) { TeamSize[(int)prevTeam]--; } if (newTeam != Team.Spectators) { TeamSize[(int)newTeam]++; if (GameState == GameState.WarmupGame && HasEnoughPlayers()) { SetGameState(GameState.WarmupGame, 0); } player.IsReadyToPlay = !IsPlayerReadyMode(); if (GameFlags.HasFlag(GameFlags.Survival)) { player.RespawnDisabled = GetRespawnDisabled(player); } } CheckReadyStates(); }
protected override void WincheckMatch() { if (IsTeamplay()) { if (GameInfo.ScoreLimit > 0 && ( TeamScore[(int)Team.Red] >= GameInfo.ScoreLimit || TeamScore[(int)Team.Blue] >= GameInfo.ScoreLimit) || GameInfo.TimeLimit > 0 && (Server.Tick - GameStartTick) >= GameInfo.TimeLimit * Server.TickSpeed * 60) { if (TeamScore[(int)Team.Red] != TeamScore[(int)Team.Blue] || GameFlags.HasFlag(GameFlags.Survival)) { EndMatch(); } else { SuddenDeath = true; } } } else { var topScore = 0; var topScoreCount = 0; for (var i = 0; i < GameContext.Players.Length; i++) { if (GameContext.Players[i] == null) { continue; } if (Score(i) > topScore) { topScore = Score(i); topScoreCount = 1; } else if (Score(i) == topScore) { topScoreCount++; } } if (GameInfo.ScoreLimit > 0 && topScore >= GameInfo.ScoreLimit || GameInfo.TimeLimit > 0 && Server.Tick - GameStartTick >= GameInfo.TimeLimit * Server.TickSpeed * 60) { if (topScoreCount == 1) { EndMatch(); } else { SuddenDeath = true; } } } }
public override bool GetRespawnDisabled(BasePlayer player) { if (GameFlags.HasFlag(GameFlags.Survival)) { if (GameState == GameState.WarmupGame || GameState == GameState.WarmupUser || GameState == GameState.StartCountdown && GameStartTick == Server.Tick) { return(false); } return(true); } return(false); }
protected override void OnCharacterDied(BaseCharacter victim, BasePlayer killer, Weapon weapon, ref int modespecial) { victim.Died -= OnCharacterDied; if (killer == null || weapon == BasePlayer.WeaponGame) { return; } if (killer == victim.Player) { Scores[killer.ClientId]--; } else { if (IsTeamplay() && victim.Player.Team == killer.Team) { Scores[killer.ClientId]--; } else { Scores[killer.ClientId]++; } } if (weapon == BasePlayer.WeaponSelf) { victim.Player.RespawnTick = Server.Tick + Server.TickSpeed * 3; } if (GameFlags.HasFlag(GameFlags.Survival)) { for (var i = 0; i < GameContext.Players.Length; i++) { if (GameContext.Players[i] != null && GameContext.Players[i].DeadSpectatorMode) { GameContext.Players[i].UpdateDeadSpecMode(); } } } }
protected override void OnCharacterSpawn(BasePlayer player, BaseCharacter character) { character.Died += OnCharacterDied; if (GameFlags.HasFlag(GameFlags.Survival)) { character.IncreaseHealth(10); character.IncreaseArmor(5); character.GiveWeapon(Weapon.Gun, 10); character.GiveWeapon(Weapon.Grenade, 10); character.GiveWeapon(Weapon.Shotgun, 10); character.GiveWeapon(Weapon.Laser, 5); player.RespawnDisabled = GetRespawnDisabled(player); } else { character.IncreaseHealth(10); character.GiveWeapon(Weapon.Gun, 10); } }
public override void Tick() { if (GamePaused) { for (var i = 0; i < ScoresStartTick.Length; i++) { ScoresStartTick[i]++; } } if (GameState != GameState.GameRunning) { if (GameStateTimer > 0) { GameStateTimer--; } if (GameStateTimer == 0) { switch (GameState) { case GameState.WarmupUser: SetGameState(GameState.WarmupUser, 0); break; case GameState.StartCountdown: SetGameState(GameState.GameRunning, 0); break; case GameState.GamePaused: SetGameState(GameState.GamePaused, 0); break; case GameState.EndRound: StartRound(); break; case GameState.EndMatch: if (MatchCount >= GameInfo.MatchNum - 1) { CycleMap(); } if (Config["SvMatchSwap"]) { SwapTeams(); } MatchCount++; StartMatch(); break; } } else { switch (GameState) { case GameState.WarmupUser: if (!Config["SvPlayerReadyMode"] && GameStateTimer == TimerInfinite) { SetGameState(GameState.WarmupUser, 0); } else if (GameStateTimer == 3 * Server.TickSpeed) { StartMatch(); } break; case GameState.StartCountdown: case GameState.GamePaused: GameStartTick++; break; } } } if (IsTeamplay() && !GameFlags.HasFlag(GameFlags.Survival)) { switch (UnbalancedTick) { case BalanceCheck: CheckTeamBalance(); break; case BalanceOk: break; default: if (Server.Tick > UnbalancedTick + Config["SvTeambalanceTime"] * Server.TickSpeed * 60) { DoTeamBalance(); } break; } } DoActivityCheck(); if (!World.ResetRequested && ( GameState == GameState.GameRunning || GameState == GameState.GamePaused)) { if (GameFlags.HasFlag(GameFlags.Survival)) { WincheckRound(); } else { WincheckMatch(); } } }
public override bool IsTeamplay() { return(GameFlags.HasFlag(GameFlags.Teams)); }
protected override void SetGameState(GameState state, int timer) { void CheckGameFlagsSurvival() { if (GameFlags.HasFlag(GameFlags.Survival)) { for (var i = 0; i < GameContext.Players.Length; i++) { if (GameContext.Players[i] != null) { GameContext.Players[i].RespawnDisabled = false; } } } } switch (state) { case GameState.WarmupGame: { if (GameState != GameState.GameRunning && GameState != GameState.WarmupGame && GameState != GameState.WarmupUser) { return; } if (timer == TimerInfinite) { GameState = state; GameStateTimer = timer; CheckGameFlagsSurvival(); } else if (timer == 0) { StartMatch(); } } break; case GameState.WarmupUser: { if (GameState != GameState.GameRunning && GameState != GameState.WarmupUser) { return; } if (timer == 0) { StartMatch(); return; } if (timer < 0) { GameStateTimer = TimerInfinite; if (Config["SvPlayerReadyMode"]) { SetPlayersReadyState(false); } } else { GameStateTimer = timer * Server.TickSpeed; } GameState = state; CheckGameFlagsSurvival(); } break; case GameState.StartCountdown: { if (GameState != GameState.GameRunning && GameState != GameState.GamePaused && GameState != GameState.StartCountdown) { return; } GameState = state; GameStateTimer = Server.TickSpeed * 3; World.Paused = true; } break; case GameState.GameRunning: { GameState = state; GameStateTimer = TimerInfinite; World.Paused = false; SetPlayersReadyState(true); } break; case GameState.GamePaused: { if (GameState != GameState.GameRunning && GameState != GameState.GamePaused) { return; } if (timer == 0) { SetGameState(GameState.StartCountdown, 0); return; } if (timer < 0) { GameStateTimer = TimerInfinite; SetPlayersReadyState(false); } else { GameStateTimer = timer * Server.TickSpeed; } GameState = state; World.Paused = true; } break; case GameState.EndRound: case GameState.EndMatch: { if (state == GameState.EndRound) { WincheckMatch(); } if (GameState == GameState.EndMatch) { break; } if (GameState != GameState.GameRunning && GameState != GameState.EndRound && GameState != GameState.EndMatch && GameState != GameState.GamePaused) { return; } GameState = state; GameStateTimer = timer * Server.TickSpeed; SuddenDeath = false; World.Paused = true; } break; } }
protected virtual void StartRound() { ResetGame(); RoundStartTick = Server.Tick; SuddenDeath = 0; GameOverTick = -1; GameWorld.IsPaused = false; TeamScores[(int)Team.RED] = 0; TeamScores[(int)Team.BLUE] = 0; ForceBalanced = false; GameContext.Console.Print(OutputLevel.DEBUG, "game", $"start round type='{GameType}' teamplay='{GameFlags.HasFlag(GameFlags.TEAMS)}'"); }