public static ArkContainer GetCryopodCreature(this GameObject gameObject) { StructPropertyList customData = gameObject.GetPropertyValue <IArkArray, ArkArrayStruct>("CustomItemDatas").FirstOrDefault() as StructPropertyList; PropertyStruct customDataBytes = customData?.Properties.FirstOrDefault(p => p.NameString == "CustomDataBytes") as PropertyStruct; PropertyArray byteArrays = (customDataBytes?.Value as StructPropertyList)?.Properties.FirstOrDefault(property => property.NameString == "ByteArrays") as PropertyArray; ArkArrayStruct byteArraysValue = byteArrays?.Value as ArkArrayStruct; if (!(((byteArraysValue?[0] as StructPropertyList)?.Properties.FirstOrDefault(p => p.NameString == "Bytes") as PropertyArray)?.Value is ArkArrayUInt8 creatureBytes)) { return(null); } ArkContainer creature = new ArkContainer(creatureBytes); /* * ArkArrayUInt8 saddleBytes = ((byteArraysValue?[1] as StructPropertyList)?.Properties.FirstOrDefault(p => p.NameString == "Bytes") as PropertyArray)?.Value as ArkArrayUInt8; * * using (MemoryStream stream = new MemoryStream(saddleBytes?.ToArray())) { * using (ArkArchive archive = new ArkArchive(stream)) { * int objectCount = archive.ReadInt(); * * //List<GameObject> objects = new List<GameObject>(); * //for (int i = 0; i < objectCount; i++) { * // //objects.Add(new GameObject(archive)); * //} * } * } */ return(creature); }
public void ReadBinary(ArkArchive archive, ReadingOptions options) { readBinaryHeader(archive); if (SaveVersion > 5) { // Name table is located after the objects block, but will be needed to read the objects block readBinaryNameTable(archive); } readBinaryDataFiles(archive, options); readBinaryEmbeddedData(archive, options); readBinaryDataFilesObjectMap(archive, options); readBinaryObjects(archive, options); readBinaryObjectProperties(archive, options); if (SaveVersion > 6) { readBinaryHibernation(archive, options); } // Now parse cryo creature data foreach (GameObject cryo in Objects.Where(x => x.ClassName.ToString().Contains("Cryop")).ToList()) { StructPropertyList customData = cryo.GetPropertyValue <IArkArray, ArkArrayStruct>("CustomItemDatas")?.FirstOrDefault() as StructPropertyList; PropertyStruct customDataBytes = customData?.Properties.FirstOrDefault(p => p.NameString == "CustomDataBytes") as PropertyStruct; PropertyArray byteArrays = (customDataBytes?.Value as StructPropertyList)?.Properties.FirstOrDefault(property => property.NameString == "ByteArrays") as PropertyArray; ArkArrayStruct byteArraysValue = byteArrays?.Value as ArkArrayStruct; ArkArrayUInt8 creatureBytes = ((byteArraysValue?[0] as StructPropertyList)?.Properties.FirstOrDefault(p => p.NameString == "Bytes") as PropertyArray)?.Value as ArkArrayUInt8; if (creatureBytes == null) { continue; } MemoryStream cryoStream = new MemoryStream(creatureBytes.ToArray <byte>()); using (ArkArchive cryoArchive = new ArkArchive(cryoStream)) { cryoArchive.ReadBytes(4); GameObject dino = new GameObject(cryoArchive); GameObject statusObject = new GameObject(cryoArchive); dino.LoadProperties(cryoArchive, new GameObject(), 0); statusObject.LoadProperties(cryoArchive, new GameObject(), 0); dino.IsCryo = true; addObject(dino, true); addObject(statusObject, true); //hack the id's so that the dino points to the appropriate dino status component PropertyObject statusComponentRef = dino.GetTypedProperty <PropertyObject>("MyCharacterStatusComponent"); statusComponentRef.Value.ObjectId = statusObject.Id; } } OldNameList = archive.HasUnknownNames ? archive.NameTable : null; HasUnknownData = archive.HasUnknownData; }
public static ArkTamedCreatureAncestor[] FromPropertyValue(ArkArrayStruct ancestorsArrayStruct) { return(ancestorsArrayStruct?.OfType <StructPropertyList>().Select(x => new ArkTamedCreatureAncestor { FemaleId1 = x.GetPropertyValue <uint>(_femaleDinoID1), FemaleId2 = x.GetPropertyValue <uint>(_femaleDinoID2), FemaleName = x.GetPropertyValue <string>(_femaleName), MaleId1 = x.GetPropertyValue <uint>(_maleDinoID1), MaleId2 = x.GetPropertyValue <uint>(_maleDinoID2), MaleName = x.GetPropertyValue <string>(_maleName) }).ToArray()); }
private Creature ConvertGameObject(GameObject creatureObject, int?levelStep) { if (!Values.V.TryGetSpeciesByClassName(creatureObject.ClassString, out Species species)) { // species is unknown, creature cannot be imported. // use name-field to temporarily save the unknown classString to display in a messagebox return(new Creature { name = creatureObject.ClassString }); } GameObject statusObject = creatureObject.CharacterStatusComponent(); // error while deserializing that creature if (statusObject == null) { return(null); } string imprinterName = creatureObject.GetPropertyValue <string>("ImprinterName"); string owner = string.IsNullOrWhiteSpace(imprinterName) ? creatureObject.GetPropertyValue <string>("TamerString") : imprinterName; int[] wildLevels = Enumerable.Repeat(-1, Values.STATS_COUNT).ToArray(); // -1 is unknown int[] tamedLevels = new int[Values.STATS_COUNT]; for (int i = 0; i < Values.STATS_COUNT; i++) { wildLevels[i] = statusObject.GetPropertyValue <ArkByteValue>("NumberOfLevelUpPointsApplied", i)?.ByteValue ?? 0; } wildLevels[(int)StatNames.Torpidity] = statusObject.GetPropertyValue <int>("BaseCharacterLevel", defaultValue: 1) - 1; // torpor for (int i = 0; i < Values.STATS_COUNT; i++) { tamedLevels[i] = statusObject.GetPropertyValue <ArkByteValue>("NumberOfLevelUpPointsAppliedTamed", i)?.ByteValue ?? 0; } float ti = statusObject.GetPropertyValue <float>("TamedIneffectivenessModifier", defaultValue: float.NaN); double te = 1f / (1 + (!float.IsNaN(ti) ? ti : creatureObject.GetPropertyValue <float>("TameIneffectivenessModifier"))); Creature creature = new Creature(species, creatureObject.GetPropertyValue <string>("TamedName"), owner, creatureObject.GetPropertyValue <string>("TribeName"), creatureObject.IsFemale() ? Sex.Female : Sex.Male, wildLevels, tamedLevels, te, !string.IsNullOrWhiteSpace(creatureObject.GetPropertyValue <string>("ImprinterName")), statusObject.GetPropertyValue <float>("DinoImprintingQuality"), levelStep ) { imprinterName = creatureObject.GetPropertyValue <string>("ImprinterName"), guid = Utils.ConvertArkIdToGuid(creatureObject.GetDinoId()), ArkId = creatureObject.GetDinoId(), ArkIdImported = true, domesticatedAt = DateTime.Now, // TODO: possible to convert ingame-time to realtime? addedToLibrary = DateTime.Now, mutationsMaternal = creatureObject.GetPropertyValue <int>("RandomMutationsFemale"), mutationsPaternal = creatureObject.GetPropertyValue <int>("RandomMutationsMale"), flags = creatureObject.GetPropertyValue <bool>("bNeutered") ? CreatureFlags.Neutered : CreatureFlags.None }; // If it's a baby and still growing, work out growingUntil if (creatureObject.GetPropertyValue <bool>("bIsBaby") || !creatureObject.GetPropertyValue <bool>("bIsBaby") && !string.IsNullOrWhiteSpace(imprinterName)) { double maturationTime = species.breeding?.maturationTimeAdjusted ?? 0; float tamedTime = _gameTime - (float)creatureObject.GetPropertyValue <double>("TamedAtTime"); if (tamedTime < maturationTime - 120) // there seems to be a slight offset of one of these saved values, so don't display a creature as being in cooldown if it is about to leave it in the next 2 minutes { creature.growingUntil = DateTime.Now + TimeSpan.FromSeconds(maturationTime - tamedTime); } } // Ancestor linking is done later after entire collection is formed - here we just set the guids ArkArrayStruct femaleAncestors = creatureObject.GetPropertyValue <IArkArray, ArkArrayStruct>("DinoAncestors"); StructPropertyList femaleAncestor = (StructPropertyList)femaleAncestors?.LastOrDefault(); if (femaleAncestor != null) { creature.motherGuid = Utils.ConvertArkIdToGuid(Utils.ConvertArkIdsToLongArkId( femaleAncestor.GetPropertyValue <int>("FemaleDinoID1"), femaleAncestor.GetPropertyValue <int>("FemaleDinoID2"))); creature.motherName = femaleAncestor.GetPropertyValue <string>("FemaleName"); creature.isBred = true; } ArkArrayStruct maleAncestors = creatureObject.GetPropertyValue <IArkArray, ArkArrayStruct>("DinoAncestorsMale"); StructPropertyList maleAncestor = (StructPropertyList)maleAncestors?.LastOrDefault(); if (maleAncestor != null) { creature.fatherGuid = Utils.ConvertArkIdToGuid(GameObjectExtensions.CreateDinoId( maleAncestor.GetPropertyValue <int>("MaleDinoID1"), maleAncestor.GetPropertyValue <int>("MaleDinoID2"))); creature.fatherName = maleAncestor.GetPropertyValue <string>("MaleName"); creature.isBred = true; } creature.colors = new int[6]; for (int i = 0; i < 6; i++) { creature.colors[i] = creatureObject.GetPropertyValue <ArkByteValue>("ColorSetIndices", i)?.ByteValue ?? 0; } bool isDead = creatureObject.GetPropertyValue <bool>("bIsDead"); if (isDead) { creature.Status = CreatureStatus.Dead; // dead is always dead } if (creatureObject.IsCryo) { creature.Status = CreatureStatus.Cryopod; } creature.RecalculateCreatureValues(levelStep); return(creature); }
public void ReadBinary(ArkArchive archive, ReadingOptions options) { readBinaryHeader(archive); if (SaveVersion > 5) { // Name table is located after the objects block, but will be needed to read the objects block readBinaryNameTable(archive); } readBinaryDataFiles(archive, options); readBinaryEmbeddedData(archive, options); readBinaryDataFilesObjectMap(archive, options); readBinaryObjects(archive, options); readBinaryObjectProperties(archive, options); if (SaveVersion > 6) { readBinaryHibernation(archive, options); } // Parse creatures in cryopods and soultraps (from the mod DinoStorageV2) foreach (var cryo in this.Objects.Where(x => x.ClassString.Contains("Cryop") || x.ClassString.Contains("SoulTrap_")).ToList()) { ArkArrayStruct customItemDatas = cryo.GetPropertyValue <IArkArray, ArkArrayStruct>("CustomItemDatas"); StructPropertyList customDinoData = (StructPropertyList)customItemDatas?.FirstOrDefault(cd => ((StructPropertyList)cd).GetTypedProperty <PropertyName>("CustomDataName").Value.Name == "Dino"); PropertyStruct customDataBytes = customDinoData?.Properties.FirstOrDefault(p => p.NameString == "CustomDataBytes") as PropertyStruct; PropertyArray byteArrays = (customDataBytes?.Value as StructPropertyList)?.Properties.FirstOrDefault(property => property.NameString == "ByteArrays") as PropertyArray; ArkArrayStruct byteArraysValue = byteArrays?.Value as ArkArrayStruct; if (!(byteArraysValue?.Any() ?? false)) { continue; } ArkArrayUInt8 creatureBytes = ((byteArraysValue?[0] as StructPropertyList)?.Properties.FirstOrDefault(p => p.NameString == "Bytes") as PropertyArray)?.Value as ArkArrayUInt8; if (creatureBytes == null) { continue; } var cryoStream = new System.IO.MemoryStream(creatureBytes.ToArray <byte>()); using (ArkArchive cryoArchive = new ArkArchive(cryoStream)) { // number of serialized objects int objCount = cryoArchive.ReadInt(); if (objCount == 0) { continue; } var storedGameObjects = new List <GameObject>(objCount); for (int oi = 0; oi < objCount; oi++) { storedGameObjects.Add(new GameObject(cryoArchive)); } foreach (var ob in storedGameObjects) { ob.LoadProperties(cryoArchive, new GameObject(), 0); } // assume the first object is the creature object string creatureActorId = storedGameObjects[0].Names[0].ToString(); storedGameObjects[0].IsCryo = true; // the tribe name is stored in `TamerString`, non-cryoed creatures have the property `TribeName` for that. if (!storedGameObjects[0].HasAnyProperty("TribeName") && storedGameObjects[0].HasAnyProperty("TamerString")) { storedGameObjects[0].Properties.Add(new PropertyString("TribeName", storedGameObjects[0].GetPropertyValue <string>("TamerString"))); } // add cryopod object as parent to all child objects of the creature object (ActorIDs are not unique across cryopodded and non-cryopodded creatures) // assume that child objects are stored after their parent objects foreach (var ob in storedGameObjects) { int nIndex = ob.Names.FindIndex(n => n.ToString() == creatureActorId); if (nIndex != -1) { ob.Names.Insert(nIndex + 1, cryo.Names[0]); addObject(ob, true); } } // assign the created ID of the dinoStatusComponent to the creature's property. var statusComponentObject = storedGameObjects.FirstOrDefault(ob => ob.ClassString?.StartsWith("DinoCharacterStatusComponent") ?? false); if (statusComponentObject != null) { var statusComponentRef = storedGameObjects[0].GetTypedProperty <PropertyObject>("MyCharacterStatusComponent"); statusComponentRef.Value.ObjectId = statusComponentObject.Id; } } } OldNameList = archive.HasUnknownNames ? archive.NameTable : null; HasUnknownData = archive.HasUnknownData; }
public Tribe(string path, ReadingOptions ro) { ArkTribe tribe = new ArkTribe().ReadBinary <ArkTribe>(path, ro); StructPropertyList tribeData = tribe.GetPropertyValue <IStruct, StructPropertyList>("TribeData"); tribeName = tribeData.GetPropertyValue <string>("TribeName", defaultValue: string.Empty); ownerPlayerDataId = tribeData.GetPropertyValue <int>("OwnerPlayerDataID"); tribeId = tribeData.GetPropertyValue <int>("TribeID"); ArkArrayString membersNames = tribeData.GetPropertyValue <IArkArray, ArkArrayString>("MembersPlayerName"); if (membersNames != null) { membersPlayerName.AddRange(membersNames); foreach (string memberName in membersNames) { membersPlayerName.Add(memberName); } } ArkArrayUInt32 membersData = tribeData.GetPropertyValue <IArkArray, ArkArrayUInt32>("MembersPlayerDataID"); if (membersData != null) { foreach (int memberDataId in membersData) { membersPlayerDataId.Add(memberDataId); } } ArkArrayUInt32 tribeAdminIds = tribeData.GetPropertyValue <IArkArray, ArkArrayUInt32>("TribeAdmins"); if (tribeAdminIds != null) { foreach (int tribeAdmin in tribeAdminIds) { tribeAdmins.Add(tribeAdmin); } } ArkArrayInt8 memberRankGroups = tribeData.GetPropertyValue <IArkArray, ArkArrayInt8>("MembersRankGroups"); if (memberRankGroups != null) { foreach (byte memberRankGroup in memberRankGroups) { membersRankGroups.Add(memberRankGroup); } } setGovernment = tribeData.GetPropertyValue <bool>("SetGovernment"); IPropertyContainer tribeGovernment = tribeData.GetPropertyValue <IStruct, IPropertyContainer>("TribeGovernment"); if (tribeGovernment != null) { tribeGovernPINCode = tribeGovernment.GetPropertyValue <int>("TribeGovern_PINCode"); tribeGovernDinoOwnership = tribeGovernment.GetPropertyValue <int>("TribeGovern_DinoOwnership"); tribeGovernStructureOwnership = tribeGovernment.GetPropertyValue <int>("TribeGovern_StructureOwnership"); tribeGovernDinoTaming = tribeGovernment.GetPropertyValue <int>("TribeGovern_DinoTaming"); tribeGovernDinoUnclaimAdminOnly = tribeGovernment.GetPropertyValue <int>("TribeGovern_DinoUnclaimAdminOnly"); } else { tribeGovernDinoOwnership = 1; tribeGovernStructureOwnership = 1; } ArkArrayString logEntrys = tribeData.GetPropertyValue <IArkArray, ArkArrayString>("TribeLog"); if (logEntrys != null) { foreach (string log in logEntrys) { tribeLog.Add(log); } } logIndex = tribeData.GetPropertyValue <int>("LogIndex"); ArkArrayStruct tribeRankStructs = tribeData.GetPropertyValue <IStruct, ArkArrayStruct>("TribeRankGroups"); if (tribeRankStructs != null) { foreach (IStruct tribeRankStruct in tribeRankStructs) { tribeRankGroups.Add(new TribeRankGroup((IPropertyContainer)tribeRankStruct)); } } }
private void extractBinaryObjectCryopods(ReadingOptions options) { if (!options.CryopodCreatures) { return; } // Parse creatures in cryopods and soultraps (from the mod DinoStorageV2) var cryopods = Objects.Where(x => x.ClassString.Contains("Cryop") || x.ClassString.Contains("SoulTrap_")).ToArray(); foreach (var cryo in cryopods) { ArkArrayStruct customItemDatas = cryo.GetPropertyValue <IArkArray, ArkArrayStruct>("CustomItemDatas"); StructPropertyList customDinoData = (StructPropertyList)customItemDatas?.FirstOrDefault(cd => ((StructPropertyList)cd).GetTypedProperty <PropertyName>("CustomDataName").Value.Name == "Dino"); PropertyStruct customDataBytes = customDinoData?.Properties.FirstOrDefault(p => p.NameString == "CustomDataBytes") as PropertyStruct; PropertyArray byteArrays = (customDataBytes?.Value as StructPropertyList)?.Properties.FirstOrDefault(property => property.NameString == "ByteArrays") as PropertyArray; ArkArrayStruct byteArraysValue = byteArrays?.Value as ArkArrayStruct; if (!(byteArraysValue?.Any() ?? false)) { continue; } ArkArrayUInt8 creatureBytes = ((byteArraysValue[0] as StructPropertyList)?.Properties.FirstOrDefault(p => p.NameString == "Bytes") as PropertyArray)?.Value as ArkArrayUInt8; if (creatureBytes == null) { continue; } var cryoStream = new System.IO.MemoryStream(creatureBytes.ToArray <byte>()); using (ArkArchive cryoArchive = new ArkArchive(cryoStream)) { // number of serialized objects int objCount = cryoArchive.ReadInt(); if (objCount == 0) { continue; } var storedGameObjects = new List <GameObject>(objCount); for (int oi = 0; oi < objCount; oi++) { storedGameObjects.Add(new GameObject(cryoArchive)); } foreach (var ob in storedGameObjects) { ob.LoadProperties(cryoArchive, new GameObject(), 0); } // assume the first object is the creature object string creatureActorId = storedGameObjects[0].Names[0].ToString(); storedGameObjects[0].IsCryo = true; // the tribe name is stored in `TamerString`, non-cryoed creatures have the property `TribeName` for that. if (!storedGameObjects[0].HasAnyProperty("TribeName") && storedGameObjects[0].HasAnyProperty("TamerString")) { storedGameObjects[0].Properties.Add(new PropertyString("TribeName", storedGameObjects[0].GetPropertyValue <string>("TamerString"))); } // add cryopod object as parent to all child objects of the creature object (ActorIDs are not unique across cryopodded and non-cryopodded creatures) // assume that child objects are stored after their parent objects for (int i = 0; i < objCount; i++) { var ob = storedGameObjects[i]; int nIndex = ob.Names.FindIndex(n => n.ToString() == creatureActorId); if (nIndex != -1) { ob.Names.Insert(nIndex + 1, cryo.Names[0]); addObject(ob, false); // processing the names can cause conflicts with reused ids } if (i == 0) { for (int ii = 1; ii < objCount; ii++) { ob.AddComponent(storedGameObjects[ii]); } } else { ob.Parent = storedGameObjects[0]; } } // assign the created ID of the components to the creature's properties AssignComponentId("DinoCharacterStatusComponent", "MyCharacterStatusComponent"); AssignComponentId("DinoTamedInventoryComponent", "MyInventoryComponent"); void AssignComponentId(string classStringStartsWith, string propertyName) { var statusComponentObject = storedGameObjects.FirstOrDefault(ob => ob.ClassString?.StartsWith(classStringStartsWith) ?? false); if (statusComponentObject == null) { return; } var statusComponentRef = storedGameObjects[0].GetTypedProperty <PropertyObject>(propertyName); if (statusComponentRef != null) { statusComponentRef.Value.ObjectId = statusComponentObject.Id; } } } } }
protected override void RunCommand(IEnumerable <string> args) { List <string> argsList = args.ToList(); if (showCommandHelp(argsList)) { return; } string clusterDirectory = argsList[0]; string outputDirectory = argsList[1]; ArkDataManager.LoadData(GlobalOptions.Language); List <Action> tasks = GlobalOptions.Parallel ? new List <Action>() : null; Stopwatch stopwatch = new Stopwatch(GlobalOptions.UseStopWatch); foreach (string path in Directory.EnumerateFiles(clusterDirectory)) { Action task = () => { try { ArkCloudInventory cloudInventory = new ArkCloudInventory().ReadBinary <ArkCloudInventory>(path, ReadingOptions.Create()); CustomDataContext context = new CustomDataContext { ObjectContainer = cloudInventory }; IPropertyContainer arkData = cloudInventory.InventoryData.GetPropertyValue <IPropertyContainer>("MyArkData"); CommonFunctions.WriteJson(Path.Combine(outputDirectory, path + ".json"), (generator, writingOptions) => { generator.WriteStartObject(); ArkArrayStruct tamedDinosData = arkData.GetPropertyValue <ArkArrayStruct>("ArkTamedDinosData"); if (tamedDinosData != null && tamedDinosData.Any()) { generator.WriteArrayFieldStart("creatures"); foreach (IStruct dinoStruct in tamedDinosData) { IPropertyContainer dino = (IPropertyContainer)dinoStruct; ArkContainer container = null; if (cloudInventory.InventoryVersion == 1) { ArkArrayUInt8 byteData = dino.GetPropertyValue <ArkArrayUInt8>("DinoData"); container = new ArkContainer(byteData); } else if (cloudInventory.InventoryVersion == 3) { ArkArrayInt8 byteData = dino.GetPropertyValue <ArkArrayInt8>("DinoData"); container = new ArkContainer(byteData); } ObjectReference dinoClass = dino.GetPropertyValue <ObjectReference>("DinoClass"); // Skip "BlueprintGeneratedClass " = 24 chars string dinoClassName = dinoClass.ObjectString.ToString().Substring(24); generator.WriteStartObject(); generator.WriteField("type", ArkDataManager.HasCreatureByPath(dinoClassName) ? ArkDataManager.GetCreatureByPath(dinoClassName).Name : dinoClassName); // NPE for unknown versions Creature creature = new Creature(container.Objects[0], container); generator.WriteObjectFieldStart("data"); creature.writeAllProperties(generator, context, writeAllFields); generator.WriteEndObject(); generator.WriteEndObject(); } generator.WriteEndArray(); } ArkArrayStruct arkItems = arkData.GetPropertyValue <ArkArrayStruct>("ArkItems"); if (arkItems != null) { List <Item> items = new List <Item>(); foreach (IStruct itemStruct in arkItems) { IPropertyContainer item = (IPropertyContainer)itemStruct; IPropertyContainer netItem = item.GetPropertyValue <IPropertyContainer>("ArkTributeItem"); items.Add(new Item(netItem)); } if (items.Any()) { generator.WritePropertyName("items"); Inventory.writeInventoryLong(generator, context, items, writeAllFields); } } generator.WriteEndObject(); }, writingOptions); } catch (Exception ex) { Console.Error.WriteLine("Found potentially corrupt cluster data: " + 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()); } stopwatch.Stop("Loading cluster data and writing info"); stopwatch.Print(); }
private Creature convertGameObject(GameObject creatureObject, int?levelStep) { GameObject statusObject = creatureObject.CharacterStatusComponent(); string imprinterName = creatureObject.GetPropertyValue <string>("ImprinterName"); string owner = string.IsNullOrWhiteSpace(imprinterName) ? creatureObject.GetPropertyValue <string>("TamerString") : imprinterName; int[] wildLevels = Enumerable.Repeat(-1, statsCount).ToArray(); // -1 is unknown int[] tamedLevels = new int[statsCount]; for (int i = 0; i < statsCount; i++) { wildLevels[i] = statusObject.GetPropertyValue <ArkByteValue>("NumberOfLevelUpPointsApplied", i)?.ByteValue ?? 0; } wildLevels[(int)StatNames.Torpidity] = statusObject.GetPropertyValue <int>("BaseCharacterLevel", defaultValue: 1) - 1; // torpor for (int i = 0; i < statsCount; i++) { tamedLevels[i] = statusObject.GetPropertyValue <ArkByteValue>("NumberOfLevelUpPointsAppliedTamed", i)?.ByteValue ?? 0; } string convertedSpeciesName = convertSpecies(creatureObject.GetNameForCreature(arkData) ?? creatureObject.ClassString); float ti = statusObject.GetPropertyValue <float>("TamedIneffectivenessModifier", defaultValue: float.NaN); double te = 1f / (1 + (!float.IsNaN(ti) ? ti : creatureObject.GetPropertyValue <float>("TameIneffectivenessModifier"))); Creature creature = new Creature(convertedSpeciesName, creatureObject.GetPropertyValue <string>("TamedName"), owner, creatureObject.GetPropertyValue <string>("TribeName"), creatureObject.IsFemale() ? Sex.Female : Sex.Male, wildLevels, tamedLevels, te, !string.IsNullOrWhiteSpace(creatureObject.GetPropertyValue <string>("ImprinterName")), statusObject.GetPropertyValue <float>("DinoImprintingQuality"), levelStep ) { imprinterName = creatureObject.GetPropertyValue <string>("ImprinterName"), guid = Utils.ConvertArkIdToGuid(creatureObject.GetDinoId()), ArkId = creatureObject.GetDinoId(), ArkIdImported = true, domesticatedAt = DateTime.Now, // TODO: possible to convert ingame-time to realtime? addedToLibrary = DateTime.Now, mutationsMaternal = creatureObject.GetPropertyValue <int>("RandomMutationsFemale"), mutationsPaternal = creatureObject.GetPropertyValue <int>("RandomMutationsMale") }; // If it's a baby and still growing, work out growingUntil if (creatureObject.GetPropertyValue <bool>("bIsBaby") || !creatureObject.GetPropertyValue <bool>("bIsBaby") && !string.IsNullOrWhiteSpace(imprinterName)) { int i = Values.V.speciesNames.IndexOf(convertedSpeciesName); double maturationTime = Values.V.species[i].breeding?.maturationTimeAdjusted ?? 0; float tamedTime = gameTime - (float)creatureObject.GetPropertyValue <double>("TamedAtTime"); if (tamedTime < maturationTime) { creature.growingUntil = DateTime.Now + TimeSpan.FromSeconds(maturationTime - tamedTime); } } // Ancestor linking is done later after entire collection is formed - here we just set the guids ArkArrayStruct femaleAncestors = creatureObject.GetPropertyValue <IArkArray, ArkArrayStruct>("DinoAncestors"); StructPropertyList femaleAncestor = (StructPropertyList)femaleAncestors?.LastOrDefault(); if (femaleAncestor != null) { creature.motherGuid = Utils.ConvertArkIdToGuid(GameObjectExtensions.CreateDinoId( femaleAncestor.GetPropertyValue <int>("FemaleDinoID1"), femaleAncestor.GetPropertyValue <int>("FemaleDinoID2"))); creature.motherName = femaleAncestor.GetPropertyValue <string>("FemaleName"); creature.isBred = true; } ArkArrayStruct maleAncestors = creatureObject.GetPropertyValue <IArkArray, ArkArrayStruct>("DinoAncestorsMale"); StructPropertyList maleAncestor = (StructPropertyList)maleAncestors?.LastOrDefault(); if (maleAncestor != null) { creature.fatherGuid = Utils.ConvertArkIdToGuid(GameObjectExtensions.CreateDinoId( maleAncestor.GetPropertyValue <int>("MaleDinoID1"), maleAncestor.GetPropertyValue <int>("MaleDinoID2"))); creature.fatherName = maleAncestor.GetPropertyValue <string>("MaleName"); creature.isBred = true; } creature.colors = new int[6]; for (int i = 0; i < 6; i++) { creature.colors[i] = colorModulo(creatureObject.GetPropertyValue <ArkByteValue>("ColorSetIndices", i)?.ByteValue ?? 0); } bool isDead = creatureObject.GetPropertyValue <bool>("bIsDead"); if (isDead) { creature.status = CreatureStatus.Dead; // dead is always dead } if (!isDead && creature.status == CreatureStatus.Dead) { creature.status = CreatureStatus.Unavailable; // if found alive when marked dead, mark as unavailable } creature.recalculateAncestorGenerations(); creature.recalculateCreatureValues(levelStep); return(creature); }
public Creature(GameObject creature, GameObjectContainer container) { className = creature.ClassName; CreatureData creatureData = ArkDataManager.GetCreature(creature.ClassString); type = creatureData != null ? creatureData.Name : creature.ClassString; location = creature.Location; int dinoID1 = creature.GetPropertyValue <int>("DinoID1"); int dinoID2 = creature.GetPropertyValue <int>("DinoID2"); dinoId = (long)dinoID1 << 32 | (dinoID2 & 0xFFFFFFFFL); targetingTeam = creature.GetPropertyValue <int>("TargetingTeam"); tamed = targetingTeam < 0 || targetingTeam >= 50000; owningPlayerId = creature.GetPropertyValue <int>("OwningPlayerID"); isFemale = creature.IsFemale(); for (int i = 0; i < 6; i++) { colorSetIndices[i] = creature.GetPropertyValue <ArkByteValue>("ColorSetIndices", i)?.ByteValue ?? 0; } tamedAtTime = creature.GetPropertyValue <double>("TamedAtTime"); tribeName = creature.GetPropertyValue <string>("TribeName", defaultValue: string.Empty); tamerstring = creature.GetPropertyValue <string>("Tamerstring", defaultValue: string.Empty); owningPlayerName = creature.GetPropertyValue <string>("OwningPlayerName", defaultValue: string.Empty); tamedName = creature.GetPropertyValue <string>("TamedName", defaultValue: string.Empty); imprinterName = creature.GetPropertyValue <string>("ImprinterName", defaultValue: string.Empty); // Not all ancestors are saved. Only those ancestor information // are available which are displayed ingame in the UI. ArkArrayStruct ancestors = creature.GetPropertyValue <IArkArray, ArkArrayStruct>("DinoAncestors"); if (ancestors != null) { // traverse female ancestor line foreach (IStruct value in ancestors) { StructPropertyList propertyList = (StructPropertyList)value; int fatherID1 = propertyList.GetPropertyValue <int>("MaleDinoID1"); int fatherID2 = propertyList.GetPropertyValue <int>("MaleDinoID2"); int motherID1 = propertyList.GetPropertyValue <int>("FemaleDinoID1"); int motherID2 = propertyList.GetPropertyValue <int>("FemaleDinoID2"); AncestorLineEntry entry = new AncestorLineEntry { MaleName = propertyList.GetPropertyValue <string>("MaleName", defaultValue: string.Empty), MaleId = (long)fatherID1 << 32 | (fatherID2 & 0xFFFFFFFFL), FemaleName = propertyList.GetPropertyValue <string>("FemaleName", defaultValue: string.Empty), FemaleId = (long)motherID1 << 32 | (motherID2 & 0xFFFFFFFFL) }; femaleAncestors.Add(entry); } } ancestors = creature.GetPropertyValue <IArkArray, ArkArrayStruct>("DinoAncestorsMale"); if (ancestors != null) { // traverse male ancestor line foreach (IStruct value in ancestors) { StructPropertyList propertyList = (StructPropertyList)value; int fatherID1 = propertyList.GetPropertyValue <int>("MaleDinoID1"); int fatherID2 = propertyList.GetPropertyValue <int>("MaleDinoID2"); int motherID1 = propertyList.GetPropertyValue <int>("FemaleDinoID1"); int motherID2 = propertyList.GetPropertyValue <int>("FemaleDinoID2"); AncestorLineEntry entry = new AncestorLineEntry { MaleName = propertyList.GetPropertyValue <string>("MaleName", defaultValue: string.Empty), MaleId = (long)fatherID1 << 32 | (fatherID2 & 0xFFFFFFFFL), FemaleName = propertyList.GetPropertyValue <string>("FemaleName", defaultValue: string.Empty), FemaleId = (long)motherID1 << 32 | (motherID2 & 0xFFFFFFFFL) }; maleAncestors.Add(entry); } } wildRandomScale = creature.GetPropertyValue <float>("WildRandomScale", defaultValue: 1F); isWakingTame = creature.GetPropertyValue <bool>("bIsWakingTame"); isSleeping = creature.GetPropertyValue <bool>("bIsSleeping"); requiredTameAffinity = creature.GetPropertyValue <float>("RequiredTameAffinity"); currentTameAffinity = creature.GetPropertyValue <float>("CurrentTameAffinity"); tamedIneffectivenessModifier = creature.GetPropertyValue <float>("TameIneffectivenessModifier"); tamedFollowTarget = creature.GetPropertyValue <ObjectReference>("TamedFollowTarget")?.ObjectId ?? -1; tamingTeamID = creature.GetPropertyValue <int>("TamingTeamID"); tamedOnServerName = creature.GetPropertyValue <string>("TamedOnServerName", defaultValue: string.Empty); uploadedFromServerName = creature.GetPropertyValue <string>("UploadedFromServerName", defaultValue: string.Empty); tamedAggressionLevel = creature.GetPropertyValue <int>("TamedAggressionLevel"); matingProgress = creature.GetPropertyValue <float>("MatingProgress"); lastEnterStasisTime = creature.GetPropertyValue <double>("LastEnterStasisTime"); status = creature.GetPropertyValue <ObjectReference, GameObject>("MyCharacterStatusComponent", map: reference => container[reference]); inventory = creature.GetPropertyValue <ObjectReference, GameObject>("MyInventoryComponent", map: reference => container[reference]); if (status != null && status.ClassString.StartsWith("DinoCharacterStatusComponent_")) { baseCharacterLevel = status.GetPropertyValue <int>("BaseCharacterLevel", defaultValue: 1); for (int index = 0; index < AttributeNames.Instance.Count; index++) { numberOfLevelUpPointsApplied[index] = status.GetPropertyValue <ArkByteValue>("NumberOfLevelUpPointsApplied", index)?.ByteValue ?? 0; } extraCharacterLevel = status.GetPropertyValue <short>("ExtraCharacterLevel"); for (int index = 0; index < AttributeNames.Instance.Count; index++) { numberOfLevelUpPointsAppliedTamed[index] = status.GetPropertyValue <ArkByteValue>("NumberOfLevelUpPointsAppliedTamed", index)?.ByteValue ?? 0; } allowLevelUps = status.GetPropertyValue <bool>("bAllowLevelUps"); experiencePoints = status.GetPropertyValue <float>("ExperiencePoints"); dinoImprintingQuality = status.GetPropertyValue <float>("DinoImprintingQuality"); tamedIneffectivenessModifier = status.GetPropertyValue <float>("TamedIneffectivenessModifier", defaultValue: tamedIneffectivenessModifier); } }