bool ProcessGameData() { // Make sure the game is loaded. var gameInfo = ReadGameInfo(); if (gameInfo == null) { return(false); } CreateReaders(); // A brand new character has been started. // The extra wasInTitleScreen check prevents DI from splitting // when it was started AFTER Diablo 2, but the char is still a new char bool isNewChar; try { isNewChar = wasInTitleScreen && Character.DetermineIfNewChar( gameInfo.Player, unitReader, inventoryReader, skillReader ); } catch (Exception e) { Logger.Error($"Unable to determine if new char {e.Message}", e); return(false); } byte area; try { area = reader.ReadByte(memory.Area); } catch (Exception e) { Logger.Error($"Unable to read area at {memory.Area}: {e.Message}", e); return(false); } // Make sure game is in a valid state. if (!IsValidState(isNewChar, gameInfo, area)) { Logger.Info("Not in valid state"); return(false); } Character character; try { character = ReadCharacterData(gameInfo, isNewChar); } catch (Exception e) { Logger.Error($"Error reading character: {e.Message}", e); return(false); } Quests quests; try { quests = ReadQuests(gameInfo); } catch (Exception e) { Logger.Error($"Error reading quests: {e.Message}", e); return(false); } byte inventoryTab; try { inventoryTab = reader.ReadByte(memory.InventoryTab); } catch (Exception e) { Logger.Error($"Error reading inventoryTab at {memory.InventoryTab}: {e.Message}", e); return(false); } int playersX; try { playersX = Math.Max(reader.ReadByte(memory.PlayersX), (byte)1); } catch (Exception e) { Logger.Error($"Error reading playersX at {memory.PlayersX}: {e.Message}", e); return(false); } // Finished reading all mandatory data // TODO: fix bug with not increasing gameCount (maybe use some more info from D2Game obj) // Note: gameId can be the same across D2 restarts // - launch d2 // - start game (counter increases) // - close d2 // - launch d2 // - start game (counter doesnt increase) if (gameInfo.GameId != 0 && (lastGameId != gameInfo.GameId)) { gameCount++; lastGameId = gameInfo.GameId; } List <Monster> killedMonsters = null; try { killedMonsters = ReadKilledMonsters(gameInfo); } catch (Exception e) { Logger.Error($"Error reading killed monsters: {e.Message}", e); } Hireling hireling = null; try { hireling = ReadHirelingData(gameInfo); } catch (Exception e) { Logger.Error($"Error reading hireling: {e.Message}", e); } if (isNewChar) { charCount++; Logger.Info($"A new character was created: {character.Name} (Char {charCount})"); } var g = new Game(); g.Area = area; g.InventoryTab = inventoryTab; g.PlayersX = playersX; g.Difficulty = (GameDifficulty)gameInfo.Game.Difficulty; g.Seed = gameInfo.Game.InitSeed; // todo: maybe improve the check, if needed... g.SeedIsArg = reader.ProcessInfo.CommandLineArgs.Contains("-seed"); g.GameCount = gameCount; g.CharCount = charCount; g.Quests = quests; g.Character = character; g.Hireling = hireling; Game = g; OnDataRead(new DataReadEventArgs(reader.ProcessInfo, Game, killedMonsters)); return(true); }
void ProcessGameData() { // Make sure the game is loaded. var gameInfo = ReadGameInfo(); if (gameInfo == null) { wasInTitleScreen = true; return; } CreateReaders(); var isNewChar = wasInTitleScreen && Character.DetermineIfNewChar( gameInfo.Player, unitReader, inventoryReader, skillReader ); var area = reader.ReadByte(memory.Area, AddressingMode.Relative); var character = ReadCharacterData(gameInfo); // A brand new character has been started. // The extra wasInTitleScreen check prevents DI from splitting // when it was started AFTER Diablo 2, but the char is still a new char if (isNewChar) { // disable IsNewChar from the other chars created so far foreach (var pair in characters) { pair.Value.IsNewChar = false; } character.Deaths = 0; character.IsNewChar = true; Logger.Info($"A new chararacter was created: {character.Name}"); charCount++; OnCharacterCreated(new CharacterCreatedEventArgs(character)); // When a new player is created, the game area is not updated immediately. // That means the game is in a kind of invalid state. // Instead of waiting for the next loop, we use the area that we know // the char starts in and set it manually, no matter what the game tells us switch (gameInfo.Player.actNo) { case 0: area = (byte)Area.ROGUE_ENCAMPMENT; break; case 1: area = (byte)Area.LUT_GHOLEIN; break; case 2: area = (byte)Area.KURAST_DOCKTOWN; break; case 3: area = (byte)Area.PANDEMONIUM_FORTRESS; break; case 4: area = (byte)Area.HARROGATH; break; default: break; } } var g = new Game(); g.Area = area; g.InventoryTab = reader.ReadByte(memory.InventoryTab, AddressingMode.Relative); g.PlayersX = Math.Max(reader.ReadByte(memory.PlayersX, AddressingMode.Relative), (byte)1); g.Difficulty = (GameDifficulty)gameInfo.Game.Difficulty; g.Seed = gameInfo.Game.InitSeed; g.GameCount = gameCount; g.CharCount = charCount; g.Quests = ReadQuests(gameInfo); g.Character = character; Game = g; OnDataRead(new DataReadEventArgs(Game)); wasInTitleScreen = false; }