public static void DoRipStats(PropertyReader reader, ArkDinoEntry entry) { /*entry.baseLevel = ReadStatsArray("MaxStatusValues", reader, entry, DEFAULT_BASE_LEVEL); * entry.increasePerWildLevel = ReadStatsArray("AmountMaxGainedPerLevelUpValue", reader, entry, DEFAULT_INCREASE_PER_WILD_LEVEL); * entry.increasePerTamedLevel = ReadStatsArray("AmountMaxGainedPerLevelUpValueTamed", reader, entry, DEFAULT_INCREASE_PER_TAMED_LEVEL); * entry.additiveTamingBonus = ReadStatsArray("TamingMaxStatAdditions", reader, entry, DEFAULT_TAMING_MAX_STAT_ADDITIONS); * entry.multiplicativeTamingBonus = ReadStatsArray("TamingMaxStatMultipliers", reader, entry, DEFAULT_TAMING_MAX_STAT_MULTIPLY);*/ //Create dicts entry.baseLevel = new Dictionary <DinoStatTypeIndex, float>(); entry.increasePerWildLevel = new Dictionary <DinoStatTypeIndex, float>(); entry.increasePerTamedLevel = new Dictionary <DinoStatTypeIndex, float>(); entry.additiveTamingBonus = new Dictionary <DinoStatTypeIndex, float>(); entry.multiplicativeTamingBonus = new Dictionary <DinoStatTypeIndex, float>(); //Loop through ARK indexes for (int i = 0; i <= 11; i++) { //Convert to our standard stat DinoStatTypeIndex stat = (DinoStatTypeIndex)i; //Calculate multipliers bool can_level = true;// (i == 2) || (reader.GetPropertyByte("CanLevelUpValue", CANLEVELUP_VALUES[i], i) == 1); int add_one = IS_PERCENT_STAT[i]; float zero_mult = can_level ? 1 : 0; float ETHM = reader.GetPropertyFloat("ExtraTamedHealthMultiplier", EXTRA_MULTS_VALUES[i], i); //Add stat data entry.baseLevel.Add(stat, MathF.Round(reader.GetPropertyFloat("MaxStatusValues", BASE_VALUES[i], i) + add_one, ROUND_PERCISION)); entry.increasePerWildLevel.Add(stat, MathF.Round(reader.GetPropertyFloat("AmountMaxGainedPerLevelUpValue", IW_VALUES[i], i) * zero_mult, ROUND_PERCISION)); entry.increasePerTamedLevel.Add(stat, MathF.Round(reader.GetPropertyFloat("AmountMaxGainedPerLevelUpValueTamed", 0, i) * ETHM * zero_mult, ROUND_PERCISION)); entry.additiveTamingBonus.Add(stat, MathF.Round(reader.GetPropertyFloat("TamingMaxStatAdditions", 0, i), ROUND_PERCISION)); entry.multiplicativeTamingBonus.Add(stat, MathF.Round(reader.GetPropertyFloat("TamingMaxStatMultipliers", 0, i), ROUND_PERCISION)); } }
/// <summary> /// Calculates the max stats for a dinosaur. REQUIRES YOU TO RUN ArkSaveEditor.ArkImports.ImportContent() BEFORE THIS! /// </summary> /// <returns></returns> public ArkDinosaurStats GetMaxStats() { ArkDinoEntry d = dino_entry; ArkWorldSettings settings = ArkImports.world_settings; float tamingEffectiveness = 0.5f; float imprintingBonus = 0f; if (d == null) { return(null); } return(new ArkDinosaurStats { health = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.Health, baseLevelupsApplied.health, tamingEffectiveness, tamedLevelupsApplied.health, imprintingBonus, settings, world.configSettings, isTamed), stamina = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.Stamina, baseLevelupsApplied.stamina, tamingEffectiveness, tamedLevelupsApplied.stamina, imprintingBonus, settings, world.configSettings, isTamed), unknown1 = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.Torpidity, baseLevelupsApplied.unknown1, tamingEffectiveness, tamedLevelupsApplied.unknown1, imprintingBonus, settings, world.configSettings, isTamed), oxygen = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.Oxygen, baseLevelupsApplied.oxygen, tamingEffectiveness, tamedLevelupsApplied.oxygen, imprintingBonus, settings, world.configSettings, isTamed), food = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.Food, baseLevelupsApplied.food, tamingEffectiveness, tamedLevelupsApplied.food, imprintingBonus, settings, world.configSettings, isTamed), water = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.Water, baseLevelupsApplied.water, tamingEffectiveness, tamedLevelupsApplied.water, imprintingBonus, settings, world.configSettings, isTamed), inventoryWeight = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.Weight, baseLevelupsApplied.inventoryWeight, tamingEffectiveness, tamedLevelupsApplied.inventoryWeight, imprintingBonus, settings, world.configSettings, isTamed), meleeDamageMult = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.MeleeDamage, baseLevelupsApplied.meleeDamageMult, tamingEffectiveness, tamedLevelupsApplied.meleeDamageMult, imprintingBonus, settings, world.configSettings, isTamed), movementSpeedMult = (float)ArkStatsCalculator.CalculateStat(d, DinoStatTypeIndex.Speed, baseLevelupsApplied.movementSpeedMult, tamingEffectiveness, tamedLevelupsApplied.movementSpeedMult, imprintingBonus, settings, world.configSettings, isTamed), }); }
/* * 0: MaxStatusValues - baseLevel * 1: AmountMaxGainedPerLevelUpValue - increasePerWildLevel * 2: AmountMaxGainedPerLevelUpValueTamed - increasePerTamedLevel * 3: TamingMaxStatAdditions - additiveTamingBonus * 4: TamingMaxStatMultipliers - multiplicativeTamingBonus */ public static ArkBreedingStat Compute(ArkDinoEntry e, DinoStatTypeIndex index, ArkConfigSettings settings) { double[] statMultipliers = new double[] { 1, 1, 1, 1 }; return(new ArkBreedingStat { BaseValue = e.baseLevel[index], AddWhenTamed = (float)e.additiveTamingBonus[index] * (e.additiveTamingBonus[index] > 0 ? (float)statMultipliers[0] : 1), MultAffinity = (float)e.multiplicativeTamingBonus[index] * (e.multiplicativeTamingBonus[index] > 0 ? (float)statMultipliers[1] : 1), IncPerTamedLevel = (float)e.increasePerTamedLevel[index] * (float)statMultipliers[2], IncPerWildLevel = (float)e.increasePerWildLevel[index] * (float)statMultipliers[3], }); }
public static double CalculateStat(ArkDinoEntry dino_entry, DinoStatTypeIndex stat, float levelWild, float tamingEff, float levelDom, float imprintingBonus, ArkWorldSettings world, ArkConfigSettings settings, bool isTamed) { // if stat is generally available but level is set to -1 (== unknown), return -1 (== unknown) if (levelWild < 0 && dino_entry != null && dino_entry.increasePerWildLevel[stat] != 0) { return(-1); } if (dino_entry != null) { Dictionary <DinoStatTypeIndex, ArkBreedingStat> stats = dino_entry.GetBreedingStats(settings); double add = 0, domMult = 1, imprintingM = 1, tamedBaseHP = 1; if (isTamed) { add = stats[stat].AddWhenTamed; double domMultAffinity = stats[stat].MultAffinity; // the multiplicative bonus is only multiplied with the TE if it is positive (i.e. negative boni won't get less bad if the TE is low) if (domMultAffinity >= 0) { domMultAffinity *= tamingEff; } domMult = (tamingEff >= 0 ? (1 + domMultAffinity) : 1) * (1 + levelDom * stats[stat].IncPerTamedLevel); if (imprintingBonus > 0 && stat != DinoStatTypeIndex.Stamina && stat != DinoStatTypeIndex.Oxygen && stat != DinoStatTypeIndex.Temperature && (stat != DinoStatTypeIndex.Speed /*|| species.NoImprintingForSpeed == false*/) && stat != DinoStatTypeIndex.TemperatureFortitude && stat != DinoStatTypeIndex.CraftingSpeed ) { imprintingM = 1 + 0.2 * imprintingBonus * settings.BabyImprintingStatScaleMultiplier; // TODO 0.2 is not always true } if (stat == 0) { tamedBaseHP = (float)dino_entry.statusComponent.tamedBaseHealthMultiplier; } } //double result = Math.Round((species.stats[stat].BaseValue * tamedBaseHP * (1 + species.stats[stat].IncPerWildLevel * levelWild) * imprintingM + add) * domMult, Utils.precision(stat), MidpointRounding.AwayFromZero); // double is too precise and results in wrong values due to rounding. float results in better values, probably ARK uses float as well. // or rounding first to a precision of 7, then use the rounding of the precision //double resultt = Math.Round((species.stats[stat].BaseValue * tamedBaseHP * (1 + species.stats[stat].IncPerWildLevel * levelWild) * imprintingM + add) * domMult, 7); //resultt = Math.Round(resultt, Utils.precision(stat), MidpointRounding.AwayFromZero); // adding an epsilon to handle rounding-errors double result = Math.Round((stats[stat].BaseValue * tamedBaseHP * (1 + stats[stat].IncPerWildLevel * levelWild) * imprintingM + add) * domMult + roundupDelta, precision(stat), MidpointRounding.AwayFromZero); return(result >= 0 ? result : 0); } return(0); }
public static ArkTribeLogDinoTarget TryFindDinoProfile(string name, int level, string classname, int tribeId, List <ArkDinosaur> globalDinos, bool constrictToTribe) { //Find profiles matching this. var profiles = globalDinos.Where(x => x.isTamed == true && x.tamedName == name && x.dino_entry != null && x.dino_entry.screen_name == classname.Trim(' ').Trim('(').Trim(')') && (x.tribeId == tribeId || !constrictToTribe)).ToArray(); //Find dino entries matching this too var dinoEntries = ArkImports.dino_entries.Where(x => x.screen_name == classname.Trim(' ').Trim('(').Trim(')')).ToArray(); ArkDinoEntry dinoEntry = null; if (dinoEntries.Length > 0) { dinoEntry = dinoEntries[0]; } //If results were found, return them if (profiles.Length >= 1) { return(new ArkTribeLogDinoTarget { name = name, level = level, displayClassname = classname, found = true, exact = profiles.Length == 1, profile = profiles[0], isTamed = true, dinoEntry = dinoEntry }); } else { return(new ArkTribeLogDinoTarget { name = name, level = level, displayClassname = classname, found = false, exact = true, profile = null, isTamed = true, dinoEntry = dinoEntry }); } }
public static void ImportDinos(UAssetCacheBlock cache, Dictionary <string, string> map, List <string> readErrors) { //Open PrimalGameData Console.WriteLine("Opening PrimalGameData..."); UAssetFileBlueprint primalGameData = UAssetFileBlueprint.OpenFile(Program.GAME_ROOT_PATH + @"PrimalEarth\CoreBlueprints\PrimalGameData_BP.uasset", false, "PrimalGameData_BP", Program.GAME_ROOT_PATH); PropertyReader primalGameDataReader = new PropertyReader(primalGameData.GetFullProperties(cache)); Console.WriteLine("PrimalGameData opened."); //Now, open all dino entries Console.WriteLine("Opening dino entries..."); Dictionary <string, PropertyReader> dinoEntries = new Dictionary <string, PropertyReader>(); ArrayProperty entriesArray = primalGameDataReader.GetProperty <ArrayProperty>("DinoEntries"); int entriesCount = 0; foreach (var en in entriesArray.props) { //Open UAssetFileBlueprint bp = ((ObjectProperty)en).GetReferencedFileBlueprint(); PropertyReader bpReader = new PropertyReader(bp.GetFullProperties(cache)); string name = bpReader.GetPropertyStringOrName("DinoNameTag"); if (dinoEntries.ContainsKey(name)) { dinoEntries.Remove(name); } dinoEntries.Add(name, bpReader); entriesCount++; } Console.WriteLine($"Finished opening dino entries. Found {entriesCount} entries."); //Now, open binder ClassListBinder binder = ClassListBinder.OpenBinder("classes.json"); //Find base dino ClassListEntry dinoBase = binder.ClassData.SearchForClass("Dino_Character_BP"); if (dinoBase == null) { throw new Exception("Failed to find dino base class."); } //Get children List <ClassListEntry> dinoClasses = dinoBase.GetAllChildren(); Console.WriteLine($"Found {dinoClasses.Count} dino classes to import."); //Loop classes and start reading List <ArkDinoEntry> dinos = new List <ArkDinoEntry>(); foreach (ClassListEntry e in dinoClasses) { try { //Find this dino file in the map if (!map.ContainsKey(e.Name)) { throw new Exception($"Failed to find dino {e.Name} in uasset map."); } string pathname = map[e.Name]; //Now, open the UASSET file UAssetFileBlueprint f = UAssetFileBlueprint.OpenFile(pathname, false, e.Name, Program.GAME_ROOT_PATH); //Create a dino entry ArkDinoEntry entry = ArkDinoEntry.Convert(f, cache, dinoEntries); dinos.Add(entry); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"Failed to import dino {e.Name} with error {ex.Message}!"); readErrors.Add($"Failed to import dino {e.Name} with error {ex.Message}{ex.StackTrace}!"); Console.ForegroundColor = ConsoleColor.White; } } //Now, save Console.WriteLine($"Finished reading {dinos.Count}/{dinoClasses.Count} dinos. Saving now..."); File.WriteAllText(Program.GetOutputDir() + "dinos.json", JsonConvert.SerializeObject(dinos, Formatting.Indented)); Console.WriteLine("Done importing dinos."); }
public ArkDinosaur(ArkWorld world, DotArkGameObject orig) : base(world, orig) { //Grab the data and save it here. //Get the other components of this dinosaur. HighLevelArkGameObjectRef statusComponent = GetGameObjectRef("MyCharacterStatusComponent"); //Check if this dinosaur is tamed. isTamed = CheckIfValueExists("TamedName") && CheckIfValueExists("TribeName") && CheckIfValueExists("TargetingTeam"); //Grab the values that will exist on both tamed and untamed dinosaurs. isFemale = GetBooleanProperty("bIsFemale"); //Convert the colors into a byte array and hex. var colorAttrib = GetPropertiesByName("ColorSetIndices"); //Get all of the color properties from the dinosaur. These are indexes in the color table. colors = new byte[colorAttrib.Length]; //Initialize the array for storing the indexes. These will be saved to the file. colors_hex = new string[colorAttrib.Length]; //Initialize the array for reading nice HTML color values. for (int i = 0; i < colors.Length; i++) //For each color region this dinosaur has. Each "ColorSetIndices" value is a color region. { colors[i] = ((ByteProperty)colorAttrib[i]).byteValue; //Get the index in the color table by getting the byte value out of the property //Validate that the color is in range byte color = colors[i]; if (color <= 0 || color > ArkColorIds.ARK_COLOR_IDS.Length) { colors_hex[i] = "#FFF"; } else { colors_hex[i] = ArkColorIds.ARK_COLOR_IDS[colors[i] - 1]; //Look this up in the color table to get the nice HTML value. } } //Read the dinosaur ID by combining the the bytes of the two UInt32 values. byte[] buf = new byte[8]; BitConverter.GetBytes(GetUInt32Property("DinoID1")).CopyTo(buf, 0); BitConverter.GetBytes(GetUInt32Property("DinoID2")).CopyTo(buf, 4); //Convert this to a ulong dinosaurId = BitConverter.ToUInt64(buf, 0); //Read in levels currentStats = ArkDinosaurStats.ReadStats(statusComponent, "CurrentStatusValues", false); baseLevelupsApplied = ArkDinosaurStats.ReadStats(statusComponent, "NumberOfLevelUpPointsApplied", true); baseLevel = 1; if (statusComponent.CheckIfValueExists("BaseCharacterLevel")) { baseLevel = statusComponent.GetInt32Property("BaseCharacterLevel"); } level = baseLevel; //Now, convert attributes that only exist on tamed dinosaurs. isInTribe = isTamed; if (isTamed) { tamedName = GetStringProperty("TamedName"); tribeId = GetInt32Property("TargetingTeam"); tamerName = GetStringProperty("TribeName"); tamedLevelupsApplied = ArkDinosaurStats.ReadStats(statusComponent, "NumberOfLevelUpPointsAppliedTamed", true); if (statusComponent.CheckIfValueExists("ExtraCharacterLevel")) { level += statusComponent.GetUInt16Property("ExtraCharacterLevel"); } if (statusComponent.HasProperty("ExperiencePoints")) { experience = statusComponent.GetFloatProperty("ExperiencePoints"); } else { experience = 0; } isBaby = GetBooleanProperty("bIsBaby"); if (isBaby) { babyAge = GetFloatProperty("BabyAge"); nextImprintTime = -1; if (HasProperty("BabyNextCuddleTime")) { nextImprintTime = GetDoubleProperty("BabyNextCuddleTime"); } if (statusComponent.HasProperty("DinoImprintingQuality")) { imprintQuality = statusComponent.GetFloatProperty("DinoImprintingQuality"); } else { imprintQuality = 0; } } } //Get the dino entry data dino_entry = ArkImports.GetDinoDataByClassname(classname.classname); isInit = true; }
static Dictionary <DinoStatTypeIndex, float> ReadStatsArray(string name, PropertyReader reader, ArkDinoEntry entry, Dictionary <DinoStatTypeIndex, float> defaults) { return(new Dictionary <DinoStatTypeIndex, float> { { DinoStatTypeIndex.Health, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Health], (int)DinoStatTypeIndex.Health) }, { DinoStatTypeIndex.Stamina, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Stamina], (int)DinoStatTypeIndex.Stamina) }, { DinoStatTypeIndex.Torpidity, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Torpidity], (int)DinoStatTypeIndex.Torpidity) }, { DinoStatTypeIndex.Oxygen, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Oxygen], (int)DinoStatTypeIndex.Oxygen) }, { DinoStatTypeIndex.Food, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Food], (int)DinoStatTypeIndex.Food) }, { DinoStatTypeIndex.Water, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Water], (int)DinoStatTypeIndex.Water) }, { DinoStatTypeIndex.Temperature, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Temperature], (int)DinoStatTypeIndex.Temperature) }, { DinoStatTypeIndex.Weight, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Weight], (int)DinoStatTypeIndex.Weight) }, { DinoStatTypeIndex.MeleeDamage, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.MeleeDamage], (int)DinoStatTypeIndex.MeleeDamage) }, { DinoStatTypeIndex.Speed, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.Speed], (int)DinoStatTypeIndex.Speed) }, { DinoStatTypeIndex.TemperatureFortitude, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.TemperatureFortitude], (int)DinoStatTypeIndex.TemperatureFortitude) }, { DinoStatTypeIndex.CraftingSpeed, reader.GetPropertyFloat(name, defaults[DinoStatTypeIndex.CraftingSpeed], (int)DinoStatTypeIndex.CraftingSpeed) } }); }