public static (GameObjectContainer, float) ReadSavegameFile(string fileName, string jsonFileName) { if (new FileInfo(fileName).Length > int.MaxValue) { throw new Exception("Input file is too large."); } Stream stream = new MemoryStream(File.ReadAllBytes(fileName)); ArkSavegame arkSavegame = new ArkSavegame(); // We're actually converting to json so we don't want to eliminate everything besides dinos. //bool PredicateCreatures(GameObject o) => !o.IsItem && (o.Parent != null || o.Components.Any()); //bool PredicateCreaturesAndCryopods(GameObject o) => (!o.IsItem && (o.Parent != null || o.Components.Any())) || o.ClassString.Contains("Cryopod") || o.ClassString.Contains("SoulTrap_"); using (ArkArchive archive = new ArkArchive(stream)) { arkSavegame.ReadBinary(archive, ReadingOptions.Create() .WithDataFiles(false) .WithEmbeddedData(false) .WithDataFilesObjectMap(false) //.WithObjectFilter(new Predicate<GameObject>(PredicateCreaturesAndCryopods)) .WithBuildComponentTree(true)); } // Jenny's addition - immediately write the json format for any binary file we read in. using (StreamWriter file = File.CreateText(jsonFileName)) using (JsonTextWriter writer = new JsonTextWriter(file)) { writer.Formatting = Formatting.Indented; arkSavegame.WriteJson(writer, WritingOptions.Create()); } // End of Jenny's addition. if (!arkSavegame.HibernationEntries.Any()) { return(arkSavegame, arkSavegame.GameTime); } List <GameObject> combinedObjects = arkSavegame.Objects; foreach (HibernationEntry entry in arkSavegame.HibernationEntries) { ObjectCollector collector = new ObjectCollector(entry, 1); combinedObjects.AddRange(collector.Remap(combinedObjects.Count)); } return(new GameObjectContainer(combinedObjects), arkSavegame.GameTime); }
private static async Task <(GameObjectContainer, float)> ReadSavegameFile(string fileName) { return(await Task.Run(() => { if (new FileInfo(fileName).Length > int.MaxValue) { throw new Exception("Input file is too large."); } Stream stream = new MemoryStream(File.ReadAllBytes(fileName)); ArkSavegame arkSavegame = new ArkSavegame(); bool PredicateCreatures(GameObject o) => !o.IsItem && (o.Parent != null || o.Components.Any()); bool PredicateCreaturesAndCryopods(GameObject o) => (!o.IsItem && (o.Parent != null || o.Components.Any())) || o.ClassString.Contains("Cryopod") || o.ClassString.Contains("SoulTrap_"); using (ArkArchive archive = new ArkArchive(stream)) { arkSavegame.ReadBinary(archive, ReadingOptions.Create() .WithDataFiles(false) .WithEmbeddedData(false) .WithDataFilesObjectMap(false) .WithObjectFilter(Properties.Settings.Default.SaveImportCryo ? new Predicate <GameObject>(PredicateCreaturesAndCryopods) : new Predicate <GameObject>(PredicateCreatures)) .WithBuildComponentTree(true)); } if (!arkSavegame.HibernationEntries.Any()) { return (arkSavegame, arkSavegame.GameTime); } List <GameObject> combinedObjects = arkSavegame.Objects; foreach (HibernationEntry entry in arkSavegame.HibernationEntries) { ObjectCollector collector = new ObjectCollector(entry, 1); combinedObjects.AddRange(collector.Remap(combinedObjects.Count)); } return (new GameObjectContainer(combinedObjects), arkSavegame.GameTime); })); }
private static Task <GameObjectContainer> ReadSavegameFile(string fileName) { return(Task.Run(() => { if (new FileInfo(fileName).Length > int.MaxValue) { throw new Exception("Input file is too large."); } var arkSavegame = new ArkSavegame(); using (var stream = new MemoryStream(File.ReadAllBytes(fileName))) using (var archive = new ArkArchive(stream)) { arkSavegame.ReadBinary(archive, ReadingOptions.Create() .WithDataFiles(false) .WithEmbeddedData(false) .WithDataFilesObjectMap(false) .WithObjectFilter(o => !o.IsItem && (o.Parent != null || o.Components.Any())) .WithBuildComponentTree(true)); } if (!arkSavegame.HibernationEntries.Any()) { return (arkSavegame); } var combinedObjects = arkSavegame.Objects; foreach (var entry in arkSavegame.HibernationEntries) { var collector = new ObjectCollector(entry, 1); combinedObjects.AddRange(collector.Remap(combinedObjects.Count)); } return new GameObjectContainer(combinedObjects); })); }
private void writeAnimalLists(Func <GameObject, bool> filter) { if (arkSavegame.HibernationEntries.Any()) { List <GameObject> combinedObjects = arkSavegame.Objects; foreach (HibernationEntry entry in arkSavegame.HibernationEntries) { ObjectCollector collector = new ObjectCollector(entry, 1); combinedObjects.AddRange(collector.Remap(combinedObjects.Count)); } container = new GameObjectContainer(combinedObjects); } else { container = arkSavegame; } IEnumerable <GameObject> objectStream = container.Where(o => o.IsCreature()); if (filter != null) { objectStream = objectStream.Where(filter); } if (!untameable) { IEnumerable <string> untameableClasses = GlobalOptions.ArkToolsConfiguration.UntameableClasses?.Split(",").Select(s => s.Trim()) ?? Enumerable.Empty <string>(); objectStream = objectStream.Where(gameObject => !gameObject.GetPropertyValue <bool>("bForceDisablingTaming")); objectStream = objectStream.Where(gameObject => !untameableClasses.Contains(gameObject.ClassString)); } if (cleanFolder) { foreach (string path in Directory.EnumerateFiles(outputDirectory, "*.json")) { File.Delete(path); } } Dictionary <string, List <GameObject> > dinoLists = objectStream.GroupBy(o => o.ClassString) .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList()); if (!withoutIndex) { Dictionary <string, string> classNames = readClassNames(); //Func<string, string> fetchName = key => ArkDataManager.GetCreature(key)?.Name ?? key; //foreach (string dinoClass in dinoLists.Keys.Where(dinoClass => !classNames.ContainsKey(dinoClass) || classNames[dinoClass] == null)) { foreach (string dinoClass in dinoLists.Keys.Where(dinoClass => !classNames.TryGetValue(dinoClass, out string value) || value == null)) { //string name = fetchName(dinoClass); string name = ArkDataManager.GetCreature(dinoClass)?.Name ?? dinoClass; if (name != null) { classNames.Add(dinoClass, name); } } writeClassNames(classNames); foreach (string s in classNames.Keys.Where(s => !dinoLists.ContainsKey(s))) { writeEmpty(s); } } foreach (KeyValuePair <string, List <GameObject> > dinoList in dinoLists) { writeList(dinoList); } }
protected override void RunCommand(IEnumerable <string> args) { List <string> argsList = args.ToList(); if (showCommandHelp(argsList)) { return; } if (withNames) { DataManager.ArkDataManager.LoadData(GlobalOptions.Language); } string savePath = argsList[0]; Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch); // Don't load any properties, we don't need them ArkSavegame savegame = new ArkSavegame().ReadBinary <ArkSavegame>(savePath, ReadingOptions.Create() .WithObjectFilter(o => false) .WithBuildComponentTree(withoutDuplicates)); stopwatch.Stop("Loading"); List <GameObject> objects; //Dictionary<int, Dictionary<List<ArkName>, GameObject>> objectMap; Dictionary <int, Dictionary <int, GameObject> > objectMap; if (savegame.HibernationEntries.Any()) { objects = new List <GameObject>(savegame.Objects); if (withoutDuplicates) { objectMap = new Dictionary <int, Dictionary <int, GameObject> >(); foreach (KeyValuePair <int, Dictionary <int, GameObject> > pair in savegame.ObjectMap) { objectMap[pair.Key] = new Dictionary <int, GameObject>(pair.Value); } } else { objectMap = null; } foreach (HibernationEntry entry in savegame.HibernationEntries) { ObjectCollector collector = new ObjectCollector(entry, 1); objects.AddRange(collector.Remap(objects.Count)); if (withoutDuplicates) { foreach (GameObject gameObject in collector) { int key = gameObject.FromDataFile ? gameObject.DataFileIndex : -1; if (!objectMap.ContainsKey(key)) { objectMap[key] = new Dictionary <int, GameObject>(); } if (!objectMap[key].ContainsKey(gameObject.Names.HashCode())) { objectMap[key][gameObject.Names.HashCode()] = gameObject; } } } } } else { objects = savegame.Objects; objectMap = savegame.ObjectMap; } if (withoutDuplicates) { //objects.removeIf((GameObject gameObject) => { // int key = gameObject.IsFromDataFile ? gameObject.DataFileIndex : -1; // return objectMap[key]?[gameObject.Names.HashCode()] != gameObject; //}); objects = objects.Where(gameObject => { int key = gameObject.FromDataFile ? gameObject.DataFileIndex : -1; return(objectMap[key]?[gameObject.Names.HashCode()] == gameObject); }).ToList(); } Dictionary <string, List <GameObject> > map = objects.GroupBy(o => o.ClassString) .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList()); stopwatch.Stop("Grouping"); WriteJsonCallback writer = (generator, writingOptions) => { generator.WriteStartObject(); generator.WriteField("_count", objects.Count); foreach (KeyValuePair <string, List <GameObject> > entry in map.OrderByDescending(e => e.Value.Count)) { string name = entry.Key; if (withNames) { if (entry.Value[0].IsItem) { if (DataManager.ArkDataManager.HasItem(name)) { name = DataManager.ArkDataManager.GetItem(name).Name; } } else { if (DataManager.ArkDataManager.HasCreature(name)) { name = DataManager.ArkDataManager.GetCreature(name).Name; } else if (DataManager.ArkDataManager.HasStructure(name)) { name = DataManager.ArkDataManager.GetStructure(name).Name; } } } generator.WriteField(name, entry.Value.Count); } generator.WriteEndObject(); }; if (argsList.Count > 1) { CommonFunctions.WriteJson(argsList[1], writer, writingOptions); } else { CommonFunctions.WriteJson(Console.OpenStandardOutput(), writer, writingOptions); } stopwatch.Stop("Writing"); stopwatch.Print(); }
protected override void RunCommand(IEnumerable <string> args) { List <string> argsList = args.ToList(); if (showCommandHelp(argsList)) { return; } bool itemsLong = withItems == "long"; bool inventoryLong = withInventory == "long"; bool tamedLong = tamed == "long"; bool structuresLong = withStructures == "long"; Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch); bool mapNeeded = withItems != null || tamed != null || withStructures != null || withInventory != null; if (!GlobalOptions.Quiet && mapNeeded) { Console.WriteLine("Need to load map, this may take some time..."); } string saveGame = argsList.Count > 0 ? argsList[0] : Path.Combine(GlobalOptions.ArkToolsConfiguration.BasePath, GlobalOptions.ArkToolsConfiguration.ArkSavegameFilename); string outputDirectory = argsList.Count > 1 ? argsList[1] : Path.Combine(GlobalOptions.ArkToolsConfiguration.BasePath, GlobalOptions.ArkToolsConfiguration.TribesPath); string saveDir = Path.GetDirectoryName(saveGame); Dictionary <int, HashSet <TribeBase> > baseMap; CustomDataContext context = new CustomDataContext(); if (mapNeeded) { ArkDataManager.LoadData(GlobalOptions.Language); ArkSavegame mapSave = new ArkSavegame().ReadBinary <ArkSavegame>(saveGame, ReadingOptions.Create().WithBuildComponentTree(true)); context.Savegame = mapSave; context.MapData = LatLonCalculator.ForSave(context.Savegame); stopwatch.Stop("Loading map data"); if (withBases) { baseMap = new Dictionary <int, HashSet <TribeBase> >(); foreach (GameObject gameObject in mapSave) { // Skip items and stuff without a location if (gameObject.IsItem || gameObject.Location == null) { continue; } string signText = gameObject.GetPropertyValue <string>("SignText"); long? targetingTeam = gameObject.GetPropertyValue <long?>("TargetingTeam"); if (signText != null && targetingTeam != null) { // Might be a 'Base' sign MatchCollection matcher = basePattern.Matches(signText); if (matcher.Any()) { // Found a base sign, add it to the set, automatically replacing duplicates int tribeId = (int)targetingTeam; LocationData location = gameObject.Location; string baseName = matcher[1].Value; float size = float.Parse(matcher[2].Value); TribeBase tribeBase = new TribeBase(baseName, location.X, location.Y, location.Z, size); if (!baseMap.ContainsKey(tribeId)) { baseMap[tribeId] = new HashSet <TribeBase>(); } baseMap[tribeId].Add(tribeBase); } } } stopwatch.Stop("Collecting bases"); } else { baseMap = null; } if (mapSave.HibernationEntries.Any() && tamed != null) { List <GameObject> combinedObjects = context.Savegame.Objects.ToList(); foreach (HibernationEntry entry in context.Savegame.HibernationEntries) { ObjectCollector collector = new ObjectCollector(entry, 1); combinedObjects.AddRange(collector.Remap(combinedObjects.Count)); } context.ObjectContainer = new GameObjectContainer(combinedObjects); } else { context.ObjectContainer = mapSave; } } else { baseMap = null; } List <Action> tasks = GlobalOptions.Parallel ? new List <Action>() : null; void mapWriter(JsonTextWriter generator, int tribeId) { if (!mapNeeded) { return; } List <GameObject> structures = new List <GameObject>(); List <GameObject> creatures = new List <GameObject>(); List <Item> items = new List <Item>(); List <Item> blueprints = new List <Item>(); List <DroppedItem> droppedItems = new List <DroppedItem>(); // Apparently there is a behavior in ARK causing certain structures to exist twice within a save HashSet <ArkName> processedList = new HashSet <ArkName>(); // Bases HashSet <TribeBase> bases = withBases ? baseMap[tribeId] : null; foreach (GameObject gameObject in context.ObjectContainer) { if (gameObject.IsItem) { continue; } int targetingTeam = gameObject.GetPropertyValue <int>("TargetingTeam", defaultValue: -1); if (targetingTeam == -1) { continue; } TeamType teamType = TeamTypes.ForTeam(targetingTeam); if (tribeId == -1 && teamType != TeamType.Player) { continue; } if (tribeId == 0 && teamType != TeamType.NonPlayer) { continue; } if (tribeId > 0 && tribeId != targetingTeam) { continue; } // Determine base if we have bases TribeBase tribeBase; if (bases != null && gameObject.Location != null) { TribeBase matchedBase = null; foreach (TribeBase potentialBase in bases) { if (potentialBase.InsideBounds(gameObject.Location)) { matchedBase = potentialBase; break; } } tribeBase = matchedBase; } else { tribeBase = null; } if (gameObject.IsCreature()) { if (!processedList.Contains(gameObject.Names[0])) { if (tribeBase != null) { tribeBase.Creatures.Add(gameObject); } else { creatures.Add(gameObject); } processedList.Add(gameObject.Names[0]); } else { // Duped Creature continue; } } else if (!gameObject.IsPlayer() && !gameObject.IsWeapon() && !gameObject.IsDroppedItem()) { // LinkedPlayerDataID: Players ain't structures // AssociatedPrimalItem: Items equipped by sleeping players // MyItem: dropped item if (!processedList.Contains(gameObject.Names[0])) { if (tribeBase != null) { tribeBase.Structures.Add(gameObject); } else { structures.Add(gameObject); } processedList.Add(gameObject.Names[0]); } else { // Duped Structure continue; } } else { if (!processedList.Contains(gameObject.Names[0])) { processedList.Add(gameObject.Names[0]); } else { // Duped Player or dropped Item or weapon continue; } } void itemHandler(ObjectReference itemReference) { GameObject item = itemReference.GetObject(context.Savegame); if (item != null && !Item.isDefaultItem(item)) { if (processedList.Contains(item.Names[0])) { // happens for players having items in their quick bar return; } processedList.Add(item.Names[0]); if (item.HasAnyProperty("bIsBlueprint")) { if (tribeBase != null) { tribeBase.Blueprints.Add(new Item(item)); } else { blueprints.Add(new Item(item)); } } else { if (tribeBase != null) { tribeBase.Items.Add(new Item(item)); } else { items.Add(new Item(item)); } } } } void droppedItemHandler(GameObject droppedItemObject) { DroppedItem droppedItem = new DroppedItem(droppedItemObject, context.Savegame); if (tribeBase != null) { tribeBase.DroppedItems.Add(droppedItem); } else { droppedItems.Add(droppedItem); } } if (withItems != null && withInventory == null) { foreach (GameObject inventory in gameObject.Components.Values) { if (!inventory.IsInventory()) { continue; } List <ObjectReference> inventoryItems = inventory.GetPropertyValue <IArkArray, ArkArrayObjectReference>("InventoryItems"); foreach (ObjectReference itemReference in inventoryItems ?? Enumerable.Empty <ObjectReference>()) { itemHandler(itemReference); } List <ObjectReference> equippedItems = inventory.GetPropertyValue <IArkArray, ArkArrayObjectReference>("EquippedItems"); foreach (ObjectReference itemReference in equippedItems ?? Enumerable.Empty <ObjectReference>()) { itemHandler(itemReference); } } } ObjectReference myItem = gameObject.GetPropertyValue <ObjectReference>("MyItem"); if (myItem != null) { if (withItems != null && withInventory == null) { itemHandler(myItem); } else if (withInventory != null) { droppedItemHandler(gameObject); } } } void writeStructures(IEnumerable <GameObject> structList) { if (withStructures == null) { return; } generator.WriteArrayFieldStart("structures"); if (structuresLong) { foreach (GameObject structureObject in structList) { Structure structure = new Structure(structureObject, context.Savegame); generator.WriteStartObject(); structure.writeAllProperties(generator, context, writeAllFields); if (withInventory != null) { structure.writeInventory(generator, context, writeAllFields, !inventoryLong); } generator.WriteEndObject(); } } else { Dictionary <ArkName, long> structMap = structList.GroupBy(o => o.ClassName).ToDictionary(objects => objects.Key, objects => objects.LongCount()); foreach (KeyValuePair <ArkName, long> entry in structMap.OrderByDescending(pair => pair.Value)) { generator.WriteStartObject(); string name = entry.Key.ToString(); if (ArkDataManager.HasStructure(name)) { name = ArkDataManager.GetStructure(name).Name; } generator.WriteField("name", name); generator.WriteField("count", entry.Value); generator.WriteEndObject(); } } generator.WriteEndArray(); } void writeCreatures(List <GameObject> creaList) { if (tamed == null) { return; } generator.WriteArrayFieldStart("tamed"); if (tamedLong) { foreach (GameObject creatureObject in creaList) { Creature creature = new Creature(creatureObject, context.Savegame); generator.WriteStartObject(); creature.writeAllProperties(generator, context, writeAllFields); if (withInventory != null) { creature.writeInventory(generator, context, writeAllFields, !inventoryLong); } generator.WriteEndObject(); } } else { Dictionary <ArkName, long> creaMap = creaList.GroupBy(o => o.ClassName).ToDictionary(objects => objects.Key, objects => objects.LongCount()); foreach (KeyValuePair <ArkName, long> entry in creaMap.OrderByDescending(pair => pair.Value)) { generator.WriteStartObject(); string name = entry.Key.ToString(); if (ArkDataManager.HasCreature(name)) { name = ArkDataManager.GetCreature(name).Name; } generator.WriteField("name", name); generator.WriteField("count", entry.Value); generator.WriteEndObject(); } } generator.WriteEndArray(); } void writeDroppedItems(List <DroppedItem> droppedList) { if (withInventory == null) { return; } generator.WriteArrayFieldStart("droppedItems"); foreach (DroppedItem droppedItem in droppedList) { generator.WriteStartObject(); droppedItem.writeAllProperties(generator, context, writeAllFields); droppedItem.writeInventory(generator, context, writeAllFields, !inventoryLong); generator.WriteEndObject(); } generator.WriteEndArray(); } if (withBases && bases != null) { generator.WriteArrayFieldStart("bases"); foreach (TribeBase tribeBase in bases) { generator.WriteStartObject(); generator.WriteField("name", tribeBase.Name); generator.WriteField("x", tribeBase.X); generator.WriteField("y", tribeBase.Y); generator.WriteField("z", tribeBase.Z); generator.WriteField("lat", context.MapData.CalculateLat(tribeBase.Y)); generator.WriteField("lon", context.MapData.CalculateLon(tribeBase.X)); generator.WriteField("radius", tribeBase.Size); writeCreatures(tribeBase.Creatures); writeStructures(tribeBase.Structures); writeDroppedItems(tribeBase.DroppedItems); if (itemsLong) { generator.WritePropertyName("items"); Inventory.writeInventoryLong(generator, context, tribeBase.Items, writeAllFields); generator.WritePropertyName("blueprints"); Inventory.writeInventoryLong(generator, context, tribeBase.Blueprints, writeAllFields); } else { generator.WritePropertyName("items"); Inventory.writeInventorySummary(generator, tribeBase.Items); generator.WritePropertyName("blueprints"); Inventory.writeInventorySummary(generator, tribeBase.Blueprints); } generator.WriteEndObject(); } generator.WriteStartObject(); } writeCreatures(creatures); writeStructures(structures); writeDroppedItems(droppedItems); if (itemsLong) { generator.WritePropertyName("items"); Inventory.writeInventoryLong(generator, context, items, writeAllFields); generator.WritePropertyName("blueprints"); Inventory.writeInventoryLong(generator, context, blueprints, writeAllFields); } else { generator.WritePropertyName("items"); Inventory.writeInventorySummary(generator, items); generator.WritePropertyName("blueprints"); Inventory.writeInventorySummary(generator, blueprints); } if (withBases && bases != null) { generator.WriteEndObject(); generator.WriteEndArray(); } } foreach (string path in Directory.EnumerateFiles(saveDir).Where(path => tribePattern.IsMatch(path))) { Action task = () => { try { Tribe tribe = new Tribe(path, ReadingOptions.Create()); string tribeFileName = tribe.tribeId + ".json"; string tribePath = Path.Combine(outputDirectory, tribeFileName); CommonFunctions.WriteJson(tribePath, (generator, writingOptions) => { generator.WriteStartObject(); tribe.writeAllProperties(generator, context, writeAllFields); mapWriter(generator, tribe.tribeId); generator.WriteEndObject(); }, writingOptions); } catch (Exception ex) { Console.Error.WriteLine("Found potentially corrupt ArkTribe: " + path); if (GlobalOptions.Verbose) { Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(ex.StackTrace); } } }; if (tasks != null) { tasks.Add(task); } else { task(); } } if (tasks != null) { Parallel.ForEach(tasks, task => task()); } if (tribeless) { string tribePath = Path.Combine(outputDirectory, "tribeless.json"); CommonFunctions.WriteJson(tribePath, (generator, writingOptions) => { generator.WriteStartObject(); mapWriter(generator, -1); generator.WriteEndObject(); }, writingOptions); } if (nonPlayers) { string tribePath = Path.Combine(outputDirectory, "non-players.json"); CommonFunctions.WriteJson(tribePath, (generator, writingOptions) => { generator.WriteStartObject(); mapWriter(generator, 0); generator.WriteEndObject(); }, writingOptions); } stopwatch.Stop("Loading tribes and writing info"); stopwatch.Print(); }
public void LoadSavegame(string path) { Savegame = new ArkSavegame().ReadBinary <ArkSavegame>(path, ReadingOptions.Create() // Skip things like NPCZoneVolume and non-instanced objects .WithObjectFilter(obj => !obj.FromDataFile && (obj.Names.Count > 1 || obj.Names[0].Instance > 0)) .WithBuildComponentTree(true)); MapData = LatLonCalculator.ForSave(Savegame); if (Savegame.HibernationEntries.Any()) { List <GameObject> combinedObjects = new List <GameObject>(Savegame.Objects); foreach (HibernationEntry entry in Savegame.HibernationEntries) { ObjectCollector collector = new ObjectCollector(entry, 1); combinedObjects.AddRange(collector.Remap(combinedObjects.Count)); } ObjectContainer = new GameObjectContainer(combinedObjects); } else { ObjectContainer = Savegame; } foreach (GameObject gameObject in ObjectContainer) { if (gameObject.FromDataFile || (gameObject.Names.Count == 1 && gameObject.Names[0].Instance == 0)) { // Skip things like NPCZoneVolume and non-instanced objects } else if (gameObject.IsInventory()) { InventoryMap[gameObject.Id] = new Inventory(gameObject); } else { if (!nameObjectMap.ContainsKey(gameObject.Names[0])) { nameObjectMap[gameObject.Names[0]] = gameObject.Id; if (gameObject.IsItem) { ItemMap[gameObject.Id] = new Item(gameObject); } else if (gameObject.IsCreature()) { CreatureMap[gameObject.Id] = new Creature(gameObject, Savegame); } else if (gameObject.Location != null && !gameObject.IsPlayer() && !gameObject.IsDroppedItem() && !gameObject.IsWeapon()) { // Skip players, weapons and items on the ground // is (probably) a structure StructureMap[gameObject.Id] = new Structure(gameObject, Savegame); } else if (gameObject.IsDroppedItem()) { // dropped Item DroppedItemMap[gameObject.Id] = new DroppedItem(gameObject, Savegame); } } } } }