using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GTFO.API;
using HarmonyLib;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("TerminalGames")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TerminalGames")]
[assembly: AssemblyTitle("TerminalGames")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace TerminalGames
{
public struct CommandDescriptor
{
public TERM_Command Type;
public string Command;
public string Description;
public TERM_CommandRule Rule;
}
public class Game
{
public enum GameType
{
Tictactoe,
Connect4,
Othello
}
public enum GameMode
{
Solo,
Multi,
Local
}
public static ManualLogSource Log;
public List<int> symbols = new List<int> { 1, 2 };
private GameType type;
private GameMode mode;
private List<List<int>> board = new List<List<int>>();
private static List<Tuple<int, int>> placed_tokens = new List<Tuple<int, int>>();
private bool isActive;
private int currentPlayer = 1;
public string MakeAIMove()
{
if (!isActive)
{
return "";
}
List<(int, int)> emptySpots = GetEmptySpots();
int value = ((currentPlayer != 1) ? 1 : 2);
foreach (var item in emptySpots)
{
List<List<int>> list = CopyBoard();
list[item.Item1][item.Item2] = currentPlayer;
if (CheckForWin(list))
{
MakeMove(item.Item1, item.Item2, currentPlayer);
return $"{(ushort)(item.Item2.ToString()[0] + 49)}{item.Item1 + 1}";
}
}
foreach (var item2 in emptySpots)
{
List<List<int>> list2 = CopyBoard();
list2[item2.Item1][item2.Item2] = value;
if (CheckForWin(list2))
{
MakeMove(item2.Item1, item2.Item2, currentPlayer);
return $"{(ushort)(item2.Item2.ToString()[0] + 49)}{item2.Item1 + 1}";
}
}
int index = new Random().Next(emptySpots.Count);
var (num, column) = emptySpots[index];
MakeMove(num, column, currentPlayer);
return $"{(ushort)(column.ToString()[0] + 49)}{num + 1}";
}
private List<(int row, int col)> GetEmptySpots()
{
List<(int, int)> list = new List<(int, int)>();
for (int i = 0; i < board.Count; i++)
{
for (int j = 0; j < board[i].Count; j++)
{
if (IsValidMove(i, j))
{
list.Add((i, j));
}
}
}
return list;
}
private List<List<int>> CopyBoard()
{
List<List<int>> list = new List<List<int>>();
foreach (List<int> item2 in board)
{
List<int> item = new List<int>(item2);
list.Add(item);
}
return list;
}
public bool CheckForWin(List<List<int>>? board_used = null)
{
if (board_used == null)
{
board_used = board;
}
if (type == GameType.Connect4)
{
if (!CheckRows(4, board_used) && !CheckColumns(4, board_used))
{
return CheckDiagonals(4, board_used);
}
return true;
}
if (type == GameType.Tictactoe)
{
if (!CheckRows(3, board_used) && !CheckColumns(3, board_used))
{
return CheckDiagonals(3, board_used);
}
return true;
}
if (type == GameType.Othello)
{
bool flag = true;
foreach (List<int> item in board)
{
foreach (int item2 in item)
{
if (item2 == 0)
{
flag = false;
}
}
}
bool flag2 = false;
for (int i = 0; i < board.Count; i++)
{
for (int j = 0; j < board[0].Count; j++)
{
if (IsValidMove(i, j))
{
flag2 = true;
}
}
}
int num = CountPieces(1);
int num2 = CountPieces(2);
if (flag || !flag2)
{
return num != num2;
}
return false;
}
return false;
}
private bool CheckRows(int consecutiveSymbols, List<List<int>> board_used)
{
foreach (int symbol in symbols)
{
for (int i = 0; i < board_used.Count; i++)
{
for (int j = 0; j <= board_used[i].Count - consecutiveSymbols; j++)
{
bool flag = true;
for (int k = 0; k < consecutiveSymbols; k++)
{
if (board_used[i][j + k] != symbol)
{
flag = false;
break;
}
}
if (flag)
{
return true;
}
}
}
}
return false;
}
private bool CheckColumns(int consecutiveSymbols, List<List<int>> board_used)
{
foreach (int symbol in symbols)
{
for (int i = 0; i < board_used[0].Count; i++)
{
for (int j = 0; j <= board_used.Count - consecutiveSymbols; j++)
{
bool flag = true;
for (int k = 0; k < consecutiveSymbols; k++)
{
if (board_used[j + k][i] != symbol)
{
flag = false;
break;
}
}
if (flag)
{
return true;
}
}
}
}
return false;
}
private bool CheckDiagonals(int consecutiveSymbols, List<List<int>> board_used)
{
foreach (int symbol in symbols)
{
for (int i = 0; i <= board_used.Count - consecutiveSymbols; i++)
{
for (int j = 0; j <= board_used[i].Count - consecutiveSymbols; j++)
{
bool flag = true;
for (int k = 0; k < consecutiveSymbols; k++)
{
if (board_used[i + k][j + k] != symbol)
{
flag = false;
break;
}
}
if (flag)
{
return true;
}
}
}
for (int l = 0; l <= board_used.Count - consecutiveSymbols; l++)
{
for (int m = consecutiveSymbols - 1; m < board_used[l].Count; m++)
{
bool flag2 = true;
for (int n = 0; n < consecutiveSymbols; n++)
{
if (board_used[l + n][m - n] != symbol)
{
flag2 = false;
break;
}
}
if (flag2)
{
return true;
}
}
}
}
return false;
}
public bool CheckForDraw(List<List<int>>? board_used = null)
{
if (board_used == null)
{
board_used = board;
}
if (type == GameType.Othello)
{
bool flag = true;
foreach (List<int> item in board)
{
foreach (int item2 in item)
{
if (item2 == 0)
{
flag = false;
break;
}
}
if (!flag)
{
break;
}
}
bool flag2 = false;
for (int i = 0; i < board.Count; i++)
{
for (int j = 0; j < board[0].Count; j++)
{
if (IsValidMove(i, j))
{
flag2 = true;
break;
}
}
if (flag2)
{
break;
}
}
int num = CountPieces(1);
int num2 = CountPieces(2);
if (flag || !flag2)
{
return num == num2;
}
return false;
}
for (int k = 0; k < board_used.Count; k++)
{
for (int l = 0; l < board_used[k].Count; l++)
{
if (board_used[k][l] == 0)
{
return false;
}
}
}
return true;
}
private int CountPieces(int player)
{
int num = 0;
foreach (List<int> item in board)
{
foreach (int item2 in item)
{
if (item2 == player)
{
num++;
}
}
}
return num;
}
private void InitializeBoard(int rows, int columns)
{
board = new List<List<int>>(rows);
for (int i = 0; i < rows; i++)
{
board.Add(new List<int>(columns));
for (int j = 0; j < columns; j++)
{
board[i].Add(0);
}
}
}
public void StopGame()
{
currentPlayer = 1;
isActive = false;
}
public string SetGameType(string input, string input2)
{
if (isActive)
{
return "A game is already being played.";
}
if (Enum.TryParse<GameType>(input, ignoreCase: true, out var result))
{
type = result;
isActive = true;
switch (type)
{
case GameType.Tictactoe:
InitializeBoard(3, 3);
break;
case GameType.Connect4:
InitializeBoard(6, 7);
break;
case GameType.Othello:
InitializeBoard(8, 8);
board[3][3] = 1;
board[4][4] = 1;
board[3][4] = 2;
board[4][3] = 2;
break;
}
if (Enum.TryParse<GameMode>(input2, ignoreCase: true, out var result2))
{
mode = result2;
}
else
{
mode = GameMode.Solo;
}
return "";
}
return "Invalid Game Type input.";
}
public static string ConvertCoordinate(string coordinate, out int row, out int column)
{
row = -1;
column = -1;
if (coordinate.Length < 1 || coordinate.Length > 2)
{
return "Invalid coordinate format. Please use a format like 'a2'.";
}
char c = coordinate[0];
if (coordinate.Length == 2)
{
if (!int.TryParse(coordinate[1].ToString(), out row))
{
return "Invalid row coordinate. Please use a format like 'a2'.";
}
row--;
}
column = c - 97;
return "";
}
public List<string> MakeMove(string coordinate, int terminalPlayer)
{
if (isActive && ConvertCoordinate(coordinate, out var row, out var column) == "")
{
return MakeMove(row, column, terminalPlayer);
}
return new List<string> { "Invalid move. Please try again." };
}
public List<string> MakeMove(int row, int column, int terminalPlayer)
{
if (terminalPlayer != currentPlayer)
{
return new List<string> { "This not your turn to play." };
}
if (type == GameType.Connect4)
{
while (row < board.Count - 1 && board[row + 1][column] == 0)
{
row++;
}
}
if (IsValidMove(row, column))
{
placed_tokens = new List<Tuple<int, int>>
{
new Tuple<int, int>(row, column)
};
board[row][column] = currentPlayer;
if (type == GameType.Othello)
{
int num = ((currentPlayer != 1) ? 1 : 2);
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
if (i == 0 && j == 0)
{
continue;
}
int num2 = row + i;
int num3 = column + j;
if (num2 < 0 || num2 >= board.Count || num3 < 0 || num3 >= board[0].Count || board[num2][num3] != num)
{
continue;
}
List<(int, int)> list = new List<(int, int)>();
while (num2 >= 0 && num2 < board.Count && num3 >= 0 && num3 < board[0].Count && board[num2][num3] == num)
{
list.Add((num2, num3));
num2 += i;
num3 += j;
}
if (num2 < 0 || num2 >= board.Count || num3 < 0 || num3 >= board[0].Count || board[num2][num3] != currentPlayer)
{
continue;
}
foreach (var (num4, num5) in list)
{
board[num4][num5] = currentPlayer;
placed_tokens.Add(new Tuple<int, int>(num4, num5));
}
}
}
}
if (currentPlayer == 1)
{
currentPlayer = 2;
}
else
{
currentPlayer = 1;
}
return DisplayBoard();
}
return new List<string> { "Invalid move. Please try again." };
}
private bool IsValidMove(int row, int column)
{
bool flag = row >= 0 && row < board.Count && column >= 0 && column < board[row].Count && board[row][column] == 0;
if (type == GameType.Connect4)
{
bool flag2 = row == board.Count - 1;
bool flag3 = row < board.Count - 1 && board[row + 1][column] != 0;
flag = flag && (flag2 || flag3);
}
else if (flag && type == GameType.Othello)
{
int num = ((currentPlayer != 1) ? 1 : 2);
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
if (i == 0 && j == 0)
{
continue;
}
int num2 = row + i;
int num3 = column + j;
if (num2 >= 0 && num2 < board.Count && num3 >= 0 && num3 < board[0].Count && board[num2][num3] == num)
{
while (num2 >= 0 && num2 < board.Count && num3 >= 0 && num3 < board[0].Count && board[num2][num3] == num)
{
num2 += i;
num3 += j;
}
if (num2 >= 0 && num2 < board.Count && num3 >= 0 && num3 < board[0].Count && board[num2][num3] == currentPlayer)
{
return true;
}
}
}
}
return false;
}
return flag;
}
public bool IsGameActive()
{
return isActive;
}
public GameMode GetGameMode()
{
return mode;
}
public GameType GetGameType()
{
return type;
}
public int GetCurrentPlayer()
{
return currentPlayer;
}
public Game Copy()
{
Game game = new Game
{
type = type,
mode = mode,
isActive = isActive,
currentPlayer = currentPlayer,
board = new List<List<int>>(board.Count)
};
for (int i = 0; i < board.Count; i++)
{
game.board.Add(new List<int>(board[i]));
}
return game;
}
public List<string> DisplayBoard()
{
List<string> list = new List<string>
{
"",
" " + string.Join(" ", GetColumnLetters(board[0].Count))
};
for (int i = 0; i < board.Count; i++)
{
list.Add($"{i + 1} |{string.Join(" ", GetRowSymbols(board[i], i))}|");
}
list.Add("");
return list;
}
private static string[] GetRowSymbols(List<int> row, int rowIndex)
{
string[] array = new string[row.Count];
for (int i = 0; i < row.Count; i++)
{
string text = GetPlayerColor(row[i]);
for (int j = 0; j < placed_tokens.Count; j++)
{
if (placed_tokens[j].Item1 == rowIndex && placed_tokens[j].Item2 == i)
{
text = "<color=green>";
break;
}
}
array[i] = text + GetSymbol(row[i]) + "</color>";
}
return array;
}
private static char[] GetColumnLetters(int columnCount)
{
char[] array = new char[columnCount];
for (int i = 0; i < columnCount; i++)
{
array[i] = (char)(97 + i);
}
return array;
}
private static string GetSymbol(int player)
{
return player switch
{
1 => "X",
2 => "O",
_ => " ",
};
}
public static string GetPlayerColor(int player)
{
return player switch
{
1 => "<color=purple>",
2 => "<color=yellow>",
_ => "",
};
}
}
[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
internal class Inject_Terminal_ReceiveCmd
{
public static ManualLogSource Log;
public static event Action<LG_ComputerTerminalCommandInterpreter, TERM_Command, string, string, string> OnCmdUsed_LevelInstanced;
static Inject_Terminal_ReceiveCmd()
{
LevelAPI.OnLevelCleanup += delegate
{
Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced = null;
};
}
private static void Postfix(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, string inputLine, string param1, string param2)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced?.Invoke(__instance, cmd, inputLine, param1, param2);
}
}
internal static class Patch
{
public class MonoPatch : MonoBehaviour
{
public static ManualLogSource? Log;
public static List<EnrichedTerminal> enriched_terminals = new List<EnrichedTerminal>();
public static void Initialize()
{
List<LG_Zone> zones = Builder.Current.m_currentFloor.MainDimension.Layers[0].m_zones;
for (int i = 0; i < zones.Count; i++)
{
List<LG_ComputerTerminal> terminalsSpawnedInZone = zones[i].TerminalsSpawnedInZone;
for (int j = 0; j < terminalsSpawnedInZone.Count; j++)
{
LG_ComputerTerminal val = terminalsSpawnedInZone[j];
EnrichedTerminal enrichedTerminal = new EnrichedTerminal
{
ComputerTerminal = val,
CmdProcessor = val.m_command,
Interaction = ((Component)val).GetComponentInChildren<Interact_ComputerTerminal>(true)
};
enrichedTerminal.SetTerminalListIndex(enriched_terminals.Count);
enrichedTerminal.Setup();
enriched_terminals.Add(enrichedTerminal);
}
}
}
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("TerminalGames", "TerminalGames", "1.0.2")]
public class Plugin : BasePlugin
{
private Harmony _Harmony;
public override void Load()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
_Harmony = new Harmony("TerminalGames");
_Harmony.PatchAll();
Patch.MonoPatch.Log = ((BasePlugin)this).Log;
EnrichedTerminal.Log = ((BasePlugin)this).Log;
Game.Log = ((BasePlugin)this).Log;
((BasePlugin)this).AddComponent<Patch.MonoPatch>();
EventAPI.OnExpeditionStarted += Patch.MonoPatch.Initialize;
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(35, 0, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin TerminalGames is now loaded.");
}
log.LogInfo(val);
}
}
public class EnrichedTerminal
{
public static ManualLogSource Log;
private LocalizedText _GCTextHolder;
private Game current_game = new Game();
private int player = 1;
private int TerminalListIndex;
private int OtherTerminalListIndex = -1;
public const TERM_Command COMMAND_PLAY = 255;
public const TERM_Command COMMAND_PLACE = 254;
public const TERM_Command COMMAND_STOP = 253;
public const TERM_Command COMMAND_JOIN = 252;
public LG_ComputerTerminal ComputerTerminal { get; set; }
public LG_ComputerTerminalCommandInterpreter CmdProcessor { get; set; }
public Interact_ComputerTerminal Interaction { get; set; }
public event Action<TERM_Command, string, string, string> OnCmdUsed;
public void AddCommand(CommandDescriptor descriptor, Action<LG_ComputerTerminalCommandInterpreter, string, string>? onCommandUsed = null)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Expected O, but got Unknown
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
Action<LG_ComputerTerminalCommandInterpreter, string, string> onCommandUsed2 = onCommandUsed;
if (CmdProcessor.HasRegisteredCommand(descriptor.Type))
{
ManualLogSource log = Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Command Type: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<TERM_Command>(descriptor.Type);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is Already Added!!");
}
log.LogError(val);
return;
}
_GCTextHolder = new LocalizedText
{
UntranslatedText = descriptor.Description,
Id = 0u
};
CmdProcessor.AddCommand(descriptor.Type, descriptor.Command, _GCTextHolder, descriptor.Rule);
OnCmdUsed += delegate(TERM_Command cmdType, string cmdStr, string param1, string param2)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
if (cmdType == descriptor.Type)
{
onCommandUsed2?.Invoke(CmdProcessor, param1, param2);
}
};
}
public void AddPlayCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter>? onCommandUsed = null)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed2 = onCommandUsed;
string cmd2 = cmd;
CommandDescriptor commandDescriptor = default(CommandDescriptor);
commandDescriptor.Type = (TERM_Command)255;
commandDescriptor.Command = cmd2;
commandDescriptor.Description = helpText;
commandDescriptor.Rule = (TERM_CommandRule)0;
CommandDescriptor descriptor = commandDescriptor;
AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter, string param1, string param2)
{
onCommandUsed2?.Invoke(interpreter);
interpreter.AddOutput((TerminalLineType)0, $"Desired Action: <color=orange>{cmd2}</color> <color=yellow>{param1}</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
if (param1 != null && param1.Length > 0)
{
string text = current_game.SetGameType(param1, param2);
if (text.Length > 0)
{
interpreter.AddOutput((TerminalLineType)0, "<color=red>" + text + "</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
}
else
{
interpreter.AddOutput((TerminalLineType)4, "Preparing game..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
interpreter.AddOutput((TerminalLineType)0, "<color=green>New game created!</color> " + Game.GetPlayerColor(player) + "You</color><color=green> can start playing!</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
List<string> list = current_game.DisplayBoard();
list.Add("<color=green>PLACE {coordinates}</color> to place a move.");
foreach (string item in list)
{
interpreter.AddOutput((TerminalLineType)0, item, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
}
if (current_game.GetGameMode() == Game.GameMode.Multi)
{
OtherTerminalListIndex = -1;
interpreter.AddOutput((TerminalLineType)0, $"The other player can join the game with <color=green>JOIN Terminal_{ComputerTerminal.m_serialNumber}</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
}
}
}
else
{
interpreter.AddOutput((TerminalLineType)0, "<color=red>You have to specify a game to play.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
});
}
public void AddPlaceCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter>? onCommandUsed = null)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed2 = onCommandUsed;
string cmd2 = cmd;
CommandDescriptor commandDescriptor = default(CommandDescriptor);
commandDescriptor.Type = (TERM_Command)254;
commandDescriptor.Command = cmd2;
commandDescriptor.Description = helpText;
commandDescriptor.Rule = (TERM_CommandRule)0;
CommandDescriptor descriptor = commandDescriptor;
AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter, string param1, string param2)
{
LG_ComputerTerminalCommandInterpreter interpreter2 = interpreter;
onCommandUsed2?.Invoke(interpreter2);
if (!current_game.IsGameActive())
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>There is no active game yet.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
else if (current_game.GetGameMode() == Game.GameMode.Multi && OtherTerminalListIndex == -1)
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>You have to wait for a player to join the game.</color>", 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
}
else
{
interpreter2.AddOutput((TerminalLineType)0, $"Desired Action: <color=orange>{cmd2}</color> <color=yellow>{param1}</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
List<string> list = current_game.MakeMove(param1, player);
if (list.Count == 1)
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>" + list[0] + "</color>", 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
}
else
{
if (IsMultiJoined())
{
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].current_game.MakeMove(param1, player);
}
foreach (string item in list)
{
interpreter2.AddOutput((TerminalLineType)0, item, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
if (IsMultiJoined())
{
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)0, item, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
}
}
if (current_game.CheckForWin())
{
interpreter2.AddOutput((TerminalLineType)0, $"<color=green>Hurray! The {Game.GetPlayerColor(player)}player {player}</color> <color=green>won! </color></color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
if (IsMultiJoined())
{
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)0, $"<color=green>Hurray! The {Game.GetPlayerColor(player)}player {player}</color> <color=green>won! </color></color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
StopMultiGame();
}
player = 1;
current_game.StopGame();
}
else if (current_game.CheckForDraw())
{
interpreter2.AddOutput((TerminalLineType)0, "<color=orange>No one won... Game's over.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
if (IsMultiJoined())
{
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)0, "<color=orange>No one won... Game's over.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
StopMultiGame();
}
player = 1;
current_game.StopGame();
}
else
{
if (current_game.GetGameMode() == Game.GameMode.Local)
{
SetEndOfQueue(delegate
{
interpreter2.AddOutput((TerminalLineType)5, Game.GetPlayerColor(player) + "Player " + player + "</color>'s turn.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
});
}
else if (IsMultiJoined())
{
SetEndOfQueue(delegate
{
interpreter2.AddOutput((TerminalLineType)5, Game.GetPlayerColor(current_game.GetCurrentPlayer()) + "Other player</color>'s turn.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
});
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].SetEndOfQueue(delegate
{
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)5, Game.GetPlayerColor(current_game.GetCurrentPlayer()) + "Your turn</color>.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
});
}
if (current_game.GetGameMode() == Game.GameMode.Solo)
{
Random random = new Random();
interpreter2.AddOutput((TerminalLineType)4, Game.GetPlayerColor((player != 1) ? 1 : 2) + "AI</color> is thinking..", (float)(0.4 + random.NextDouble()), (TerminalSoundType)0, (TerminalSoundType)0);
string text = current_game.MakeAIMove().ToUpper();
interpreter2.AddOutput((TerminalLineType)0, Game.GetPlayerColor((player != 1) ? 1 : 2) + "AI placed on</color> <color=orange>" + text + "</color>", 0.1f, (TerminalSoundType)0, (TerminalSoundType)0);
foreach (string item2 in current_game.DisplayBoard())
{
interpreter2.AddOutput((TerminalLineType)0, item2, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
}
interpreter2.AddOutput((TerminalLineType)0, Game.GetPlayerColor(player) + "Your turn.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
if (current_game.CheckForWin())
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>The AI won.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
player = 1;
current_game.StopGame();
}
else if (current_game.CheckForDraw())
{
interpreter2.AddOutput((TerminalLineType)0, "<color=orange>No one won... Game's over.</color>", 0.7f, (TerminalSoundType)0, (TerminalSoundType)0);
player = 1;
current_game.StopGame();
}
}
if (current_game.GetGameMode() == Game.GameMode.Local)
{
if (player == 1)
{
player = 2;
}
else
{
player = 1;
}
}
}
}
}
});
}
public void AddStopCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter>? onCommandUsed = null)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed2 = onCommandUsed;
string cmd2 = cmd;
CommandDescriptor commandDescriptor = default(CommandDescriptor);
commandDescriptor.Type = (TERM_Command)253;
commandDescriptor.Command = cmd2;
commandDescriptor.Description = helpText;
commandDescriptor.Rule = (TERM_CommandRule)0;
CommandDescriptor descriptor = commandDescriptor;
AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter, string param1, string param2)
{
onCommandUsed2?.Invoke(interpreter);
interpreter.AddOutput((TerminalLineType)0, "Desired Action: <color=orange>" + cmd2 + "</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
if (current_game.IsGameActive())
{
if (IsMultiJoined())
{
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)4, "Stopping game from remote terminal..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].CmdProcessor.AddOutput((TerminalLineType)0, "<color=orange>The game has been stopped.</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
StopMultiGame();
}
interpreter.AddOutput((TerminalLineType)4, "Stopping game..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
interpreter.AddOutput((TerminalLineType)0, "<color=orange>The game has been stopped.</color>", 0.65f, (TerminalSoundType)0, (TerminalSoundType)0);
player = 1;
current_game.StopGame();
}
else
{
interpreter.AddOutput((TerminalLineType)0, "<color=red>There is no game currently played.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
});
}
public void AddJoinCommand(string cmd, string helpText, Action<LG_ComputerTerminalCommandInterpreter>? onCommandUsed = null)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
Action<LG_ComputerTerminalCommandInterpreter> onCommandUsed2 = onCommandUsed;
string cmd2 = cmd;
CommandDescriptor commandDescriptor = default(CommandDescriptor);
commandDescriptor.Type = (TERM_Command)252;
commandDescriptor.Command = cmd2;
commandDescriptor.Description = helpText;
commandDescriptor.Rule = (TERM_CommandRule)0;
CommandDescriptor descriptor = commandDescriptor;
AddCommand(descriptor, delegate(LG_ComputerTerminalCommandInterpreter interpreter, string param1, string param2)
{
LG_ComputerTerminalCommandInterpreter interpreter2 = interpreter;
onCommandUsed2?.Invoke(interpreter2);
interpreter2.AddOutput((TerminalLineType)0, "Desired Action: <color=orange>" + cmd2 + "</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
if (current_game.IsGameActive())
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>There is already a game currently being played.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
else
{
interpreter2.AddOutput((TerminalLineType)4, "Finding game..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
if (param1 != null)
{
param1 = param1.ToLower();
}
if (param1 != null && param1.Length > 0 && param1.Contains("terminal_"))
{
param1 = param1.Split("terminal_")[1];
if (param1 == ComputerTerminal.m_serialNumber.ToString())
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>You cannot play as the other player on the same terminal.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
else
{
OtherTerminalListIndex = -1;
for (int i = 0; i < Patch.MonoPatch.enriched_terminals.Count; i++)
{
EnrichedTerminal enrichedTerminal = Patch.MonoPatch.enriched_terminals[i];
if (i != TerminalListIndex && enrichedTerminal.ComputerTerminal.m_serialNumber.ToString() == param1)
{
if (enrichedTerminal.OtherTerminalListIndex != -1)
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>A player has already joined the game on this terminal.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
else
{
if (enrichedTerminal.current_game.IsGameActive() && enrichedTerminal.current_game.GetGameMode() == Game.GameMode.Multi)
{
current_game = enrichedTerminal.current_game.Copy();
if (enrichedTerminal.player == 1)
{
player = 2;
}
else
{
player = 2;
}
OtherTerminalListIndex = i;
enrichedTerminal.OtherTerminalListIndex = TerminalListIndex;
enrichedTerminal.CmdProcessor.AddOutput((TerminalLineType)0, $"<color=orange>A player has joined you from </color><color=green>Terminal_{ComputerTerminal.m_serialNumber}</color><color=orange>!</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
enrichedTerminal.CmdProcessor.AddOutput((TerminalLineType)5, Game.GetPlayerColor(current_game.GetCurrentPlayer()) + "Your turn</color>.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
break;
}
interpreter2.AddOutput((TerminalLineType)0, "<color=red>No multiplayer game found on that terminal.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
return;
}
}
if (OtherTerminalListIndex == -1)
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>No other terminal found with that ID.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
else
{
interpreter2.AddOutput((TerminalLineType)4, "Fetching board..", 0.85f, (TerminalSoundType)0, (TerminalSoundType)0);
foreach (string item in current_game.DisplayBoard())
{
interpreter2.AddOutput((TerminalLineType)0, item, 0.02f, (TerminalSoundType)0, (TerminalSoundType)0);
}
SetEndOfQueue(delegate
{
interpreter2.AddOutput((TerminalLineType)5, Game.GetPlayerColor(current_game.GetCurrentPlayer()) + "Other player</color>'s turn.", 1.2f, (TerminalSoundType)0, (TerminalSoundType)0);
});
}
}
}
else
{
interpreter2.AddOutput((TerminalLineType)0, "<color=red>Wrong syntax for JOIN command.</color>", 0.5f, (TerminalSoundType)0, (TerminalSoundType)0);
}
}
});
}
public void Setup()
{
Inject_Terminal_ReceiveCmd.OnCmdUsed_LevelInstanced += OnReceiveCommand;
AddPlayCommand("play", "{<color=orange>TICTACTOE</color>, <color=orange>CONNECT4</color>, <color=orange>OTHELLO</color>}</color> {<color=green>SOLO</color>, <color=green>MULTI</color>, <color=green>LOCAL</color>}");
AddPlaceCommand("place", "Once a game is started, place on given <color=orange>{coordinates}</color>. <color=blue> Ex: PLACE A2</color>");
AddStopCommand("stop", "Once a game is started, <color=red>stops</color> the current game");
AddJoinCommand("join", "Joins the game from its {<color=orange>Terminal ID</color>}. <color=blue> Ex: JOIN Terminal_284</color>");
}
private void OnReceiveCommand(LG_ComputerTerminalCommandInterpreter interpreter, TERM_Command cmd, string inputLine, string param1, string param2)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
if (interpreter.m_terminal.m_syncID == ComputerTerminal.m_syncID)
{
this.OnCmdUsed?.Invoke(cmd, inputLine, param1, param2);
}
}
public void SetEndOfQueue(Action onEndOfQueue)
{
CmdProcessor.OnEndOfQueue = Action.op_Implicit(onEndOfQueue);
}
public bool IsMultiJoined()
{
if (OtherTerminalListIndex != -1)
{
return current_game.GetGameMode() == Game.GameMode.Multi;
}
return false;
}
public void StopMultiGame()
{
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].current_game.StopGame();
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].OtherTerminalListIndex = -1;
Patch.MonoPatch.enriched_terminals[OtherTerminalListIndex].player = 1;
OtherTerminalListIndex = -1;
}
public void SetTerminalListIndex(int index)
{
TerminalListIndex = index;
}
}
[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
[CompilerGenerated]
internal static class VersionInfo
{
public const string RootNamespace = "TerminalGames";
public const string Version = "1.0.0";
public const string VersionPrerelease = null;
public const string VersionMetadata = null;
public const string SemVer = "1.0.0";
public const string GitRevShort = null;
public const string GitRevLong = null;
public const string GitBranch = null;
public const string GitTag = null;
public const bool GitIsDirty = false;
}
}