public IExtraData ReadJson(GameObject o, JToken node) { int structMapCount = ((JArray)node).Count; List <Dictionary <string, StructPropertyList> > structMapList = new List <Dictionary <string, StructPropertyList> >(structMapCount); foreach (JToken structMapJson in node) { Dictionary <string, StructPropertyList> structMap = new Dictionary <string, StructPropertyList>(); foreach (KeyValuePair <string, JToken> pair in (JObject)structMapJson) { string key = pair.Key == ExtraDataFoliage.NullPlaceholder ? null : pair.Key; structMap[key] = new StructPropertyList((JArray)pair.Value); } structMapList.Add(structMap); } ExtraDataFoliage extraDataFoliage = new ExtraDataFoliage { StructMapList = structMapList }; return(extraDataFoliage); }
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 IExtraData Read(GameObject obj, ArkArchive archive, long length) { var shouldBeZero = archive.GetInt(); if (shouldBeZero != 0) { _logger.Warn($"Expected int after properties to be 0 but found {shouldBeZero} at {archive.Position - 4:X}"); } var structMapCount = archive.GetInt(); IList <IDictionary <string, StructPropertyList> > structMapList = new List <IDictionary <string, StructPropertyList> >(structMapCount); try { for (int structMapIndex = 0; structMapIndex < structMapCount; structMapIndex++) { var structCount = archive.GetInt(); IDictionary <string, StructPropertyList> structMap = new Dictionary <string, StructPropertyList>(); for (int structIndex = 0; structIndex < structCount; structIndex++) { var structName = archive.GetString(); StructPropertyList properties = new StructPropertyList(archive, null); var shouldBeZero2 = archive.GetInt(); if (shouldBeZero2 != 0) { _logger.Warn($"Expected int after properties to be 0 but found {shouldBeZero2} at {archive.Position - 4:X}"); } structMap[structName] = properties; } structMapList.Add(structMap); } } catch (UnreadablePropertyException) { // Just stop reading and attach collected structs } ExtraDataFoliage extraDataFoliage = new ExtraDataFoliage(); extraDataFoliage.StructMapList = structMapList; return(extraDataFoliage); }
public IExtraData ReadBinary(GameObject gameObject, ArkArchive archive, int length) { int shouldBeZero = archive.ReadInt(); if (shouldBeZero != 0) { throw new UnexpectedDataException($"Expected int after properties to be 0 but found {shouldBeZero} at {(archive.Position - 4):X4}"); } int structMapCount = archive.ReadInt(); List <Dictionary <string, StructPropertyList> > structMapList = new List <Dictionary <string, StructPropertyList> >(structMapCount); try { for (int structMapIndex = 0; structMapIndex < structMapCount; structMapIndex++) { int structCount = archive.ReadInt(); Dictionary <string, StructPropertyList> structMap = new Dictionary <string, StructPropertyList>(); for (int structIndex = 0; structIndex < structCount; structIndex++) { string structName = archive.ReadString(); StructPropertyList properties = new StructPropertyList(archive); int shouldBeZero2 = archive.ReadInt(); if (shouldBeZero2 != 0) { throw new UnexpectedDataException($"Expected int after properties to be 0 but found {shouldBeZero2} at {(archive.Position - 4):X4}"); } structMap[structName] = properties; } structMapList.Add(structMap); } } catch (UnreadablePropertyException upe) { throw new UnexpectedDataException(upe); } ExtraDataFoliage extraDataFoliage = new ExtraDataFoliage { StructMapList = structMapList }; return(extraDataFoliage); }
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; } } } } }
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); } }
public Player(string path, IDataContext context, ReadingOptions ro) { ArkProfile profile = new ArkProfile().ReadBinary <ArkProfile>(path, ro); savedPlayerDataVersion = profile.GetPropertyValue <int>("SavedPlayerDataVersion"); StructPropertyList myData = profile.GetPropertyValue <IStruct, StructPropertyList>("MyData"); playerDataId = myData.GetPropertyValue <long>("PlayerDataID"); uniqueId = myData.GetPropertyValue <IStruct, StructUniqueNetIdRepl>("UniqueID"); savedNetworkAddress = myData.GetPropertyValue <string>("SavedNetworkAddress"); playerName = myData.GetPropertyValue <string>("PlayerName"); tribeId = myData.GetPropertyValue <int>("TribeID"); playerDataVersion = myData.GetPropertyValue <int>("PlayerDataVersion"); spawnDayNumber = myData.GetPropertyValue <int>("SpawnDayNumber"); spawnDayTime = myData.GetPropertyValue <float>("SpawnDayTime"); IPropertyContainer characterConfig = myData.GetPropertyValue <IStruct, IPropertyContainer>("MyPlayerCharacterConfig"); // Character data isFemale = characterConfig.GetPropertyValue <bool>("bIsFemale"); bodyColors = Enumerable.Range(0, PlayerBodyColorRegions.Instance.Count).Select(i => characterConfig.GetPropertyValue <IStruct, StructLinearColor>("BodyColors", i)).ToArray(); //for (int i = 0; i < PlayerBodyColorRegions.Instance.Count; i++) { // bodyColors[i] = characterConfig.getPropertyValue<IStruct, StructLinearColor>("BodyColors", i); //} overrideHeadHairColor = characterConfig.GetPropertyValue <IStruct, StructLinearColor>("OverrideHeadHairColor"); overrideFacialHairColor = characterConfig.GetPropertyValue <IStruct, StructLinearColor>("OverrideFacialHairColor"); facialHairIndex = characterConfig.GetPropertyValue <ArkByteValue>("FacialHairIndex")?.ByteValue ?? 0; headHairIndex = characterConfig.GetPropertyValue <ArkByteValue>("HeadHairIndex")?.ByteValue ?? 0; playerCharacterName = characterConfig.GetPropertyValue <string>("PlayerCharacterName", defaultValue: string.Empty); rawBoneModifiers = Enumerable.Range(0, PlayerBoneModifierNames.Instance.Count).Select(i => characterConfig.GetPropertyValue <float>("RawBoneModifiers", i)).ToArray(); //for (int i = 0; i < PlayerBoneModifierNames.Instance.Count; i++) { // rawBoneModifiers[i] = characterConfig.findPropertyValue<float>("RawBoneModifiers", i); //} IPropertyContainer characterStats = myData.GetPropertyValue <IStruct, IPropertyContainer>("MyPersistentCharacterStats"); characterLevel = characterStats.GetPropertyValue <short>("CharacterStatusComponent_ExtraCharacterLevel") + 1; experiencePoints = characterStats.GetPropertyValue <float>("CharacterStatusComponent_ExperiencePoints"); totalEngramPoints = characterStats.GetPropertyValue <int>("PlayerState_TotalEngramPoints"); List <ObjectReference> learnedEngrams = characterStats.GetPropertyValue <IArkArray, ArkArrayObjectReference>("PlayerState_EngramBlueprints"); if (learnedEngrams != null) { foreach (ObjectReference reference in learnedEngrams) { engramBlueprints.Add(reference.ObjectString.ToString()); } } numberOfLevelUpPointsApplied = Enumerable.Range(0, AttributeNames.Instance.Count) .Select(i => characterStats.GetPropertyValue <ArkByteValue>("CharacterStatusComponent_NumberOfLevelUpPointsApplied", i)?.ByteValue ?? 0) .ToArray(); //for (int i = 0; i < AttributeNames.Instance.Count; i++) { // numberOfLevelUpPointsApplied[i] = characterStats.findPropertyValue<ArkByteValue>("CharacterStatusComponent_NumberOfLevelUpPointsApplied", i) // ?.ByteValue ?? 0; //} percentageOfHeadHairGrowth = characterStats.GetPropertyValue <float>("PercentageOfHeadHairGrowth"); percentageOfFacialHairGrowth = characterStats.GetPropertyValue <float>("PercentageOfFacialHairGrowth"); if (context.ObjectContainer == null) { return; } GameObject player = null; foreach (GameObject gameObject in context.ObjectContainer) { long?linkedPlayerDataId = gameObject.GetPropertyValue <long?>("LinkedPlayerDataID"); if (linkedPlayerDataId == null || linkedPlayerDataId != playerDataId) { continue; } player = gameObject; break; } if (player == null) { return; } GameObject playerCharacterStatus = null; foreach (GameObject gameObject in context.ObjectContainer) { if (gameObject.Names.Count != 2 || gameObject.Names[0].ToString() != "PlayerCharacterStatus" || gameObject.Names[1] != player.Names[0]) { continue; } playerCharacterStatus = gameObject; break; } inventory = player.GetPropertyValue <ObjectReference, GameObject>("MyInventoryComponent", map: reference => context.ObjectContainer[reference]); location = player.Location; if (playerCharacterStatus == null) { return; } lastHypothermalCharacterInsulationValue = playerCharacterStatus.GetPropertyValue <float>("LastHypothermalCharacterInsulationValue"); lastHyperthermalCharacterInsulationValue = playerCharacterStatus.GetPropertyValue <float>("LastHyperthermalCharacterInsulationValue"); for (int index = 0; index < AttributeNames.Instance.Count; index++) { currentStatusValues[index] = playerCharacterStatus.GetPropertyValue <float>("CurrentStatusValues", index); } }
public GameObject toGameObject(ICollection <GameObject> existingObjects, int ownerInventory) { GameObject gameObject = new GameObject(); gameObject.ClassName = className; if (!canEquip) { gameObject.Properties.Add(new PropertyBool("bAllowEquppingItem", canEquip)); } if (!canSlot) { gameObject.Properties.Add(new PropertyBool("bCanSlot", canSlot)); } if (isEngram) { gameObject.Properties.Add(new PropertyBool("bIsEngram", isEngram)); } if (isBlueprint) { gameObject.Properties.Add(new PropertyBool("bIsBlueprint", isBlueprint)); } if (!canRemove) { gameObject.Properties.Add(new PropertyBool("bAllowRemovalFromInventory", canRemove)); } if (isHidden) { gameObject.Properties.Add(new PropertyBool("bHideFromInventoryDisplay", isHidden)); } if (quantity != 1) { gameObject.Properties.Add(new PropertyInt("ItemQuantity", quantity)); } if (!string.IsNullOrEmpty(customName)) { gameObject.Properties.Add(new PropertyString("CustomItemName", customName)); } if (!string.IsNullOrEmpty(customDescription)) { gameObject.Properties.Add(new PropertyString("CustomItemDescription", customDescription)); } if (durability > 0) { gameObject.Properties.Add(new PropertyFloat("SavedDurability", durability)); } if (quality > 0) { gameObject.Properties.Add(new PropertyByte("ItemQualityIndex", quality)); } if (nextSpoilingTime > 0) { gameObject.Properties.Add(new PropertyDouble("NextSpoilingTime", nextSpoilingTime)); } if (lastSpoilingTime > 0) { gameObject.Properties.Add(new PropertyDouble("LastSpoilingTime", lastSpoilingTime)); } for (int i = 0; i < itemStatValues.Length; i++) { if (itemStatValues[i] != 0) { gameObject.Properties.Add(new PropertyUInt16("ItemStatValues", i, itemStatValues[i])); } } if (crafterCharacterName != null && !string.IsNullOrEmpty(crafterCharacterName)) { gameObject.Properties.Add(new PropertyString("CrafterCharacterName", crafterCharacterName)); } if (crafterTribeName != null && !string.IsNullOrEmpty(crafterTribeName)) { gameObject.Properties.Add(new PropertyString("CrafterTribeName", crafterTribeName)); } if (craftedSkillBonus != 0.0f) { gameObject.Properties.Add(new PropertyFloat("CraftedSkillBonus", craftedSkillBonus)); } HashSet <long> itemIDs = new HashSet <long>(); // Stored as StructPropertyList with 2 UInt32 HashSet <ArkName> names = new HashSet <ArkName>(); foreach (GameObject existingObject in existingObjects) { existingObject.Names.ForEach(name => names.Add(name)); IPropertyContainer itemID = existingObject.GetPropertyValue <IPropertyContainer>("ItemId"); if (itemID != null) { int?itemID1 = itemID.GetPropertyValue <int?>("ItemID1"); int?itemID2 = itemID.GetPropertyValue <int?>("ItemID2"); if (itemID1 != null && itemID2 != null) { long id = (long)itemID1.Value << 32 | (itemID2.Value & 0xFFFFFFFFL); itemIDs.Add(id); continue; } } } Random random = new Random(); Func <ArkName, ArkName> findFreeName = name => { for (int i = 1; i < int.MaxValue; i++) { ArkName tempName = ArkName.From(name.Name, i); if (!names.Contains(tempName)) { return(tempName); } } throw new Exception("This is insane."); }; long randomId = random.NextLong(); while (itemIDs.Contains(randomId)) { randomId = random.NextLong(); } StructPropertyList structProperty = new StructPropertyList(); structProperty.Properties.Add(new PropertyUInt32("ItemID1", (int)(randomId >> 32))); structProperty.Properties.Add(new PropertyUInt32("ItemID2", (int)randomId)); gameObject.Properties.Add(new PropertyStruct("ItemId", structProperty, ArkName.From("ItemNetID"))); gameObject.Names.Clear(); gameObject.Names.Add(findFreeName(className)); gameObject.IsItem = true; ObjectReference ownerInventoryReference = new ObjectReference(); ownerInventoryReference.Length = 8; ownerInventoryReference.ObjectId = ownerInventory; ownerInventoryReference.ObjectType = ObjectReference.TypeId; gameObject.Properties.Add(new PropertyObject("OwnerInventory", ownerInventoryReference)); gameObject.ExtraData = new ExtraDataZero(); return(gameObject); }
public StructPropertyList toClusterData() { if (blueprintGeneratedClass == "BlueprintGeneratedClass ") { Console.Error.WriteLine("Item " + className + " is missing blueprintGeneratedClass."); return(null); } StructPropertyList result = new StructPropertyList(); StructPropertyList arkTributeItem = new StructPropertyList(); result.Properties.Add(new PropertyStruct("ArkTributeItem", arkTributeItem, ArkName.From("ItemNetInfo"))); ObjectReference itemArchetype = new ObjectReference(); itemArchetype.ObjectType = ObjectReference.TypePath; itemArchetype.ObjectString = ArkName.From(blueprintGeneratedClass); arkTributeItem.Properties.Add(new PropertyObject("ItemArchetype", itemArchetype)); Random random = new Random(); long randomId = random.NextLong(); StructPropertyList structProperty = new StructPropertyList(); structProperty.Properties.Add(new PropertyUInt32("ItemID1", (int)(randomId >> 32))); structProperty.Properties.Add(new PropertyUInt32("ItemID2", (int)randomId)); arkTributeItem.Properties.Add(new PropertyStruct("ItemId", structProperty, ArkName.From("ItemNetID"))); arkTributeItem.Properties.Add(new PropertyBool("bIsBlueprint", isBlueprint)); arkTributeItem.Properties.Add(new PropertyBool("bIsEngram", isEngram)); arkTributeItem.Properties.Add(new PropertyBool("bIsCustomRecipe", false)); arkTributeItem.Properties.Add(new PropertyBool("bIsFoodRecipe", false)); arkTributeItem.Properties.Add(new PropertyBool("bIsRepairing", false)); arkTributeItem.Properties.Add(new PropertyBool("bAllowRemovalFromInventory", canRemove)); arkTributeItem.Properties.Add(new PropertyBool("bAllowRemovalFromSteamInventory", canRemoveFromCluster)); arkTributeItem.Properties.Add(new PropertyBool("bHideFromInventoryDisplay", isHidden)); arkTributeItem.Properties.Add(new PropertyBool("bFromSteamInventory", false)); arkTributeItem.Properties.Add(new PropertyBool("bIsFromAllClustersInventory", false)); arkTributeItem.Properties.Add(new PropertyBool("bIsEquipped", false)); arkTributeItem.Properties.Add(new PropertyBool("bIsSlot", canSlot)); arkTributeItem.Properties.Add(new PropertyUInt32("ExpirationTimeUTC", 0)); arkTributeItem.Properties.Add(new PropertyUInt32("ItemQuantity", quantity - 1)); arkTributeItem.Properties.Add(new PropertyFloat("ItemDurability", durability)); arkTributeItem.Properties.Add(new PropertyFloat("ItemRating", rating)); arkTributeItem.Properties.Add(new PropertyByte("ItemQualityIndex", quality)); for (int i = 0; i < itemStatValues.Length; i++) { arkTributeItem.Properties.Add(new PropertyUInt16("ItemStatValues", i, itemStatValues[i])); } for (int i = 0; i < itemColors.Length; i++) { arkTributeItem.Properties.Add(new PropertyInt16("ItemColorID", i, itemColors[i])); } ObjectReference itemCustomClass = new ObjectReference(); itemCustomClass.Length = 8; itemCustomClass.ObjectId = -1; itemCustomClass.ObjectType = ObjectReference.TypeId; arkTributeItem.Properties.Add(new PropertyObject("ItemCustomClass", itemCustomClass)); ObjectReference itemSkinTemplate = new ObjectReference(); itemSkinTemplate.Length = 8; itemSkinTemplate.ObjectId = -1; itemSkinTemplate.ObjectType = ObjectReference.TypeId; arkTributeItem.Properties.Add(new PropertyObject("ItemSkinTemplate", itemSkinTemplate)); arkTributeItem.Properties.Add(new PropertyFloat("CraftingSkill", 0.0f)); arkTributeItem.Properties.Add(new PropertyString("CustomItemName", customName)); arkTributeItem.Properties.Add(new PropertyString("CustomItemDescription", customDescription)); // TODO: add other values arkTributeItem.Properties.Add(new PropertyDouble("NextSpoilingTime", nextSpoilingTime)); arkTributeItem.Properties.Add(new PropertyDouble("LastSpoilingTime", lastSpoilingTime)); ObjectReference lastOwnerPlayer = new ObjectReference(); lastOwnerPlayer.Length = 4; lastOwnerPlayer.ObjectId = -1; lastOwnerPlayer.ObjectType = ObjectReference.TypeId; arkTributeItem.Properties.Add(new PropertyObject("LastOwnerPlayer", lastOwnerPlayer)); arkTributeItem.Properties.Add(new PropertyDouble("LastAutoDurabilityDecreaseTime", 0.0)); arkTributeItem.Properties.Add(new PropertyStruct("OriginalItemDropLocation", new StructVector(), ArkName.From("Vector"))); for (int i = 0; i < preSkinItemColors.Length; i++) { arkTributeItem.Properties.Add(new PropertyInt16("PreSkinItemColorID", i, preSkinItemColors[i])); } for (int i = 0; i < eggLevelups.Length; i++) { arkTributeItem.Properties.Add(new PropertyByte("EggNumberOfLevelUpPointsApplied", i, eggLevelups[i])); } arkTributeItem.Properties.Add(new PropertyFloat("EggTamedIneffectivenessModifier", 0.0f)); for (int i = 0; i < eggColors.Length; i++) { arkTributeItem.Properties.Add(new PropertyByte("EggColorSetIndices", i, eggColors[i])); } arkTributeItem.Properties.Add(new PropertyString("CrafterCharacterName", crafterCharacterName)); arkTributeItem.Properties.Add(new PropertyString("CrafterTribeName", crafterTribeName)); arkTributeItem.Properties.Add(new PropertyFloat("CraftedSkillBonus", craftedSkillBonus)); arkTributeItem.Properties.Add(new PropertyByte("ItemVersion", (byte)0)); arkTributeItem.Properties.Add(new PropertyInt("CustomItemID", 0)); arkTributeItem.Properties.Add(new PropertyArray("SteamUserItemID", new ArkArrayUInt64())); arkTributeItem.Properties.Add(new PropertyBool("bIsInitialItem", false)); arkTributeItem.Properties.Add(new PropertyDouble("ClusterSpoilingTimeUTC", DateTimeOffset.UtcNow.ToUnixTimeSeconds())); result.Properties.Add(new PropertyFloat("Version", 2.0f)); result.Properties.Add(new PropertyInt("UploadTime", (int)DateTimeOffset.UtcNow.AddSeconds(uploadOffset).ToUnixTimeSeconds())); return(result); }