public static int foodAmountNeeded(int speciesI, int level, double tamingSpeedMultiplier, string food, bool nonViolent = false) { if (speciesI >= 0 && speciesI < Values.V.species.Count) { TamingData taming = Values.V.species[speciesI].taming; double affinityNeeded = taming.affinityNeeded0 + taming.affinityIncreasePL * level; bool specialFood = taming.specialFoodValues != null && taming.specialFoodValues.ContainsKey(food); if (specialFood || Values.V.foodData.ContainsKey(food)) { double foodAffinity; foodAffinity = specialFood ? taming.specialFoodValues[food].affinity : Values.V.foodData[food].affinity; if (nonViolent) { foodAffinity *= taming.wakeAffinityMult; } foodAffinity *= tamingSpeedMultiplier * 2; // *2 in accordance with the permament 2x taming-bonus that was introduced in the game on 2016-12-12 if (foodAffinity > 0) { // amount of food needed for the affinity return((int)Math.Ceiling(affinityNeeded / (foodAffinity * (specialFood ? taming.specialFoodValues[food].quantity : 1)))); } } } return(0); }
private void comboBoxSpecies_SelectedIndexChanged(object sender, EventArgs e) { int sI = comboBoxSpecies.SelectedIndex; if (sI >= 0 && Values.V.species[sI].taming != null) { TamingData td = Values.V.species[sI].taming; this.SuspendLayout(); foreach (TamingFoodControl f in foodControls) { Controls.Remove(f); } foodControls.Clear(); TamingFoodControl tf; int i = 0; foreach (string f in td.eats) { tf = new TamingFoodControl(f); if (f == "Kibble") { tf.foodNameDisplay = "Kibble (" + td.favoriteKibble + " Egg)"; } if (td.specialFoodValues != null && td.specialFoodValues.ContainsKey(f) && td.specialFoodValues[f].quantity > 1) { tf.foodNameDisplay = td.specialFoodValues[f].quantity.ToString() + "× " + tf.foodNameDisplay; } tf.Location = new Point(20, 80 + 45 * i); tf.valueChanged += new TamingFoodControl.ValueChangedEventHandler(updateTamingData); tf.Clicked += new TamingFoodControl.ClickedEventHandler(onlyOneFood); foodControls.Add(tf); Controls.Add(tf); i++; } this.ResumeLayout(); if (foodControls.Count > 0) { foodControls[0].amount = Taming.foodAmountNeeded(sI, (int)nudLevel.Value, foodControls[0].foodName, td.nonViolent); } } }
public static int foodAmountNeeded(int speciesI, int level, string food, bool nonViolent = false) { if (speciesI >= 0 && speciesI < Values.V.species.Count) { TamingData taming = Values.V.species[speciesI].taming; double affinityNeeded = taming.affinityNeeded0 + taming.affinityIncreasePL * level; bool specialFood = (taming.specialFoodValues != null && taming.specialFoodValues.ContainsKey(food)); if (specialFood || Values.V.foodData.ContainsKey(food)) { double foodAffinity = 0; if (specialFood) { foodAffinity = taming.specialFoodValues[food].affinity; } else { foodAffinity = Values.V.foodData[food].affinity; } if (nonViolent) { foodAffinity *= taming.wakeAffinityMult; } foodAffinity *= Values.V.tamingSpeedMultiplier; if (foodAffinity > 0) { // amount of food needed for the affinity return((int)Math.Ceiling(affinityNeeded / foodAffinity)); } } } return(0); }
public void setSpeciesIndex(int speciesIndex) { if (speciesIndex >= 0 && Values.V.species[speciesIndex].taming != null && this.speciesIndex != speciesIndex) { this.SuspendLayout(); this.speciesIndex = speciesIndex; // bone damage adjusters Dictionary <double, string> boneDamageAdjusters = new Dictionary <double, string>(); boneDamageAdjustersImmobilization = Taming.boneDamageAdjustersImmobilization(speciesIndex, out boneDamageAdjusters); int ib = 0; foreach (KeyValuePair <double, string> bd in boneDamageAdjusters) { ib++; if (ib >= rbBoneDamageAdjusters.Count) { RadioButton rbBD = new RadioButton(); gbWeaponDamage.Controls.Add(rbBD); rbBD.Location = new Point(6, 173 + 19 * ib); rbBD.AutoSize = false; rbBD.Size = new Size(194, 17); rbBoneDamageAdjusters.Add(rbBD); rbBoneDamageAdjusterValues.Add(1); rbBD.CheckedChanged += new System.EventHandler(this.rbBoneDamage_CheckedChanged); } rbBoneDamageAdjusterValues[ib] = bd.Key; rbBoneDamageAdjusters[ib].Text = bd.Value + " (" + bd.Key.ToString() + "×)"; rbBoneDamageAdjusters[ib].Visible = true; } for (int j = ib + 1; j < rbBoneDamageAdjusters.Count; j++) { rbBoneDamageAdjusters[j].Visible = false; } rbBoneDamageAdjusters[0].Checked = true; // bone damage adjusters adjusted updateCalculation = false; TamingData td = Values.V.species[speciesIndex].taming; favoriteKibble = td.favoriteKibble; foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * tamingFoodRateMultiplier; TamingFoodControl tf; int i = 0; if (td.eats != null) { for (i = 0; i < td.eats.Count; i++) { string f = td.eats[i]; if (i >= foodControls.Count) { tf = new TamingFoodControl(f); tf.Location = new Point(20, 80 + 45 * i); tf.valueChanged += new TamingFoodControl.ValueChangedEventHandler(updateTamingData); tf.Clicked += new TamingFoodControl.ClickedEventHandler(onlyOneFood); foodControls.Add(tf); Controls.Add(tf); } else { tf = foodControls[i]; tf.FoodName = f; tf.Show(); } if (f == "Kibble") { tf.foodNameDisplay = "Kibble (" + td.favoriteKibble + " Egg)"; } if (td.specialFoodValues != null && td.specialFoodValues.ContainsKey(f) && td.specialFoodValues[f].quantity > 1) { tf.foodNameDisplay = td.specialFoodValues[f].quantity.ToString() + "× " + tf.foodNameDisplay; } } } for (int fci = foodControls.Count - 1; fci >= i; fci--) { foodControls[fci].Hide(); } if (i > 0) { foodControls[0].amount = Taming.foodAmountNeeded(speciesIndex, (int)nudLevel.Value, tamingSpeedMultiplier, foodControls[0].FoodName, td.nonViolent); } updateCalculation = true; updateFirstFeedingWaiting(); updateTamingData(); ResumeLayout(); } }
public void SetSpecies(Species species, bool forceRefresh = false) { if (species == null || (selectedSpecies == species && !forceRefresh)) { return; } selectedSpecies = species; if (species.taming == null) { NoTamingData(); return; } SuspendLayout(); string speciesName = species.name; linkLabelWikiPage.Text = "Wiki: " + speciesName; linkLabelWikiPage.Tag = speciesName; // bone damage adjusters boneDamageAdjustersImmobilization = Taming.BoneDamageAdjustersImmobilization(selectedSpecies, out Dictionary <string, double> boneDamageAdjusters); int ib = 0; foreach (KeyValuePair <string, double> bd in boneDamageAdjusters) { ib++; if (ib >= rbBoneDamageAdjusters.Count) { RadioButton rbBD = new RadioButton(); flcBodyDamageMultipliers.Controls.Add(rbBD); flcBodyDamageMultipliers.SetFlowBreak(rbBD, true); rbBD.AutoSize = true; rbBoneDamageAdjusters.Add(rbBD); rbBoneDamageAdjusterValues.Add(1); rbBD.CheckedChanged += rbBoneDamage_CheckedChanged; } rbBoneDamageAdjusterValues[ib] = bd.Value; rbBoneDamageAdjusters[ib].Text = $"{Loc.S(bd.Key)} (× {bd.Value})"; rbBoneDamageAdjusters[ib].Visible = true; } for (int j = ib + 1; j < rbBoneDamageAdjusters.Count; j++) { rbBoneDamageAdjusters[j].Visible = false; } rbBoneDamageAdjusters[0].Checked = true; // bone damage adjusters adjusted updateCalculation = false; TamingData td = species.taming; kibbleRecipe = string.Empty; // list all recipes of kibbles that give a reasonable affinity (assuming that is larger or equal than 100) foreach (var k in Kibbles.K.kibble) { var kibbleName = $"{k.Key} Kibble"; if (((td.specialFoodValues != null && td.specialFoodValues.TryGetValue(kibbleName, out var kFood)) || Values.V.defaultFoodData.TryGetValue(kibbleName, out kFood)) && kFood.affinity >= 100) { kibbleRecipe += $"\n\n{k.Key} Kibble:{k.Value.RecipeAsText()}"; } } foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * tamingFoodRateMultiplier; int i = 0; if (td.eats != null) { for (i = 0; i < td.eats.Length; i++) { string f = td.eats[i]; TamingFoodControl tf; // if Augmented are not wanted, and food control already exist, update it and hide it. if (!checkBoxAugmented.Checked && f.Contains("Augmented")) { if (i < foodControls.Count) { tf = foodControls[i]; tf.FoodName = f; tf.Hide(); } continue; } if (i >= foodControls.Count) { tf = new TamingFoodControl(f); tf.valueChanged += UpdateTamingData; tf.Clicked += OnlyOneFood; foodControls.Add(tf); flpTamingFood.Controls.Add(tf); } else { tf = foodControls[i]; tf.FoodName = f; tf.Show(); } // special cases where a creature eats multiple food items of one kind at once if (td.specialFoodValues != null && td.specialFoodValues.ContainsKey(f) && td.specialFoodValues[f].quantity > 1) { tf.foodNameDisplay = td.specialFoodValues[f].quantity + "× " + tf.foodNameDisplay; } } } for (int fci = foodControls.Count - 1; fci >= i; fci--) { foodControls[fci].Hide(); } if (i > 0) { foodControls[0].amount = Taming.FoodAmountNeeded(species, (int)nudLevel.Value, tamingSpeedMultiplier, foodControls[0].FoodName, td.nonViolent); } updateCalculation = true; UpdateFirstFeedingWaiting(); UpdateTamingData(); ResumeLayout(); }
public void SetSpecies(Species species) { if (species == null || selectedSpecies == species) { return; } selectedSpecies = species; if (species.taming == null) { NoTamingData(); return; } SuspendLayout(); string speciesName = species.name; linkLabelWikiPage.Text = "Wiki: " + speciesName; linkLabelWikiPage.Tag = speciesName; // bone damage adjusters boneDamageAdjustersImmobilization = Taming.boneDamageAdjustersImmobilization(selectedSpecies, out Dictionary <string, double> boneDamageAdjusters); int ib = 0; foreach (KeyValuePair <string, double> bd in boneDamageAdjusters) { ib++; if (ib >= rbBoneDamageAdjusters.Count) { RadioButton rbBD = new RadioButton(); gbWeaponDamage.Controls.Add(rbBD); rbBD.Location = new Point(6, 199 + 19 * ib); rbBD.AutoSize = false; rbBD.Size = new Size(194, 17); rbBoneDamageAdjusters.Add(rbBD); rbBoneDamageAdjusterValues.Add(1); rbBD.CheckedChanged += rbBoneDamage_CheckedChanged; } rbBoneDamageAdjusterValues[ib] = bd.Value; rbBoneDamageAdjusters[ib].Text = $"{Loc.s(bd.Key)} (× {bd.Value})"; rbBoneDamageAdjusters[ib].Visible = true; } for (int j = ib + 1; j < rbBoneDamageAdjusters.Count; j++) { rbBoneDamageAdjusters[j].Visible = false; } rbBoneDamageAdjusters[0].Checked = true; // bone damage adjusters adjusted updateCalculation = false; TamingData td = species.taming; kibbleRecipe = ""; // TODO replace with new kibble recipes //if (td.favoriteKibble != null && Kibbles.K.kibble.ContainsKey(td.favoriteKibble)) //{ // kibbleRecipe = "\n\nKibble:" + Kibbles.K.kibble[td.favoriteKibble].RecipeAsText(); //} foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * tamingFoodRateMultiplier; int i = 0; if (td.eats != null) { for (i = 0; i < td.eats.Count; i++) { string f = td.eats[i]; TamingFoodControl tf; if (i >= foodControls.Count) { tf = new TamingFoodControl(f); tf.valueChanged += UpdateTamingData; tf.Clicked += OnlyOneFood; foodControls.Add(tf); flpTamingFood.Controls.Add(tf); } else { tf = foodControls[i]; tf.FoodName = f; tf.Show(); } if (f == "Kibble") { tf.foodNameDisplay = $"Kibble ({td.favoriteKibble} {Loc.s("Egg")})"; } if (td.specialFoodValues != null && td.specialFoodValues.ContainsKey(f) && td.specialFoodValues[f].quantity > 1) { tf.foodNameDisplay = td.specialFoodValues[f].quantity + "× " + tf.foodNameDisplay; } } } for (int fci = foodControls.Count - 1; fci >= i; fci--) { foodControls[fci].Hide(); } if (i > 0) { foodControls[0].amount = Taming.foodAmountNeeded(species, (int)nudLevel.Value, tamingSpeedMultiplier, foodControls[0].FoodName, td.nonViolent); } updateCalculation = true; UpdateFirstFeedingWaiting(); UpdateTamingData(); ResumeLayout(); }
public void setSpeciesIndex(int speciesIndex) { if (speciesIndex >= 0 && Values.V.species[speciesIndex].taming != null) { this.speciesIndex = speciesIndex; boneDamageAdjusters = Taming.boneDamageAdjustersImmobilisation(speciesIndex); updateCalculation = false; this.SuspendLayout(); TamingData td = Values.V.species[speciesIndex].taming; foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * Values.V.tamingFoodRateMultiplier; TamingFoodControl tf; int i = 0; if (td.eats != null) { for (i = 0; i < td.eats.Count; i++) { string f = td.eats[i]; if (i >= foodControls.Count) { tf = new TamingFoodControl(f); tf.Location = new Point(20, 80 + 45 * i); tf.valueChanged += new TamingFoodControl.ValueChangedEventHandler(updateTamingData); tf.Clicked += new TamingFoodControl.ClickedEventHandler(onlyOneFood); foodControls.Add(tf); Controls.Add(tf); } else { tf = foodControls[i]; tf.FoodName = f; tf.Show(); } if (f == "Kibble") { tf.foodNameDisplay = "Kibble (" + td.favoriteKibble + " Egg)"; } if (td.specialFoodValues != null && td.specialFoodValues.ContainsKey(f) && td.specialFoodValues[f].quantity > 1) { tf.foodNameDisplay = td.specialFoodValues[f].quantity.ToString() + "× " + tf.foodNameDisplay; } } } for (int fci = foodControls.Count - 1; fci >= i; fci--) { foodControls[fci].Hide(); } if (i > 0) { foodControls[0].amount = Taming.foodAmountNeeded(speciesIndex, (int)nudLevel.Value, evolutionEvent, foodControls[0].FoodName, td.nonViolent); } updateCalculation = true; updateFirstFeedingWaiting(); updateTamingData(); ResumeLayout(); } }
public static void tamingTimes(int speciesI, int level, double tamingSpeedMultiplier, double tamingFoodRateMultiplier, List <string> usedFood, List <int> foodAmount, out List <int> foodAmountUsed, out TimeSpan duration, out int neededNarcoberries, out int neededNarcotics, out int neededBioToxines, out double te, out double hunger, out int bonusLevel, out bool enoughFood) { double affinityNeeded = 0, totalTorpor = 0, torporDeplPS = 0, foodAffinity, foodValue, torporNeeded = 0; string food; int seconds = 0, totalSeconds = 0, foodPiecesNeeded; bonusLevel = 0; te = 1; duration = TimeSpan.Zero; neededNarcoberries = 0; neededNarcotics = 0; neededBioToxines = 0; hunger = 0; enoughFood = false; foodAmountUsed = new List <int>(); foreach (int i in foodAmount) { foodAmountUsed.Add(0); } if (speciesI >= 0 && speciesI < Values.V.species.Count) { te = 100; TamingData taming = Values.V.species[speciesI].taming; // test if(creature is tamend non-violently, then use wakeTame multiplicators bool nonViolent = false; if (taming.nonViolent) { nonViolent = true; } affinityNeeded = taming.affinityNeeded0 + taming.affinityIncreasePL * level; if (!nonViolent) { //total torpor for level totalTorpor = Values.V.species[speciesI].stats[7].BaseValue * (1 + Values.V.species[speciesI].stats[7].IncPerWildLevel * (level - 1)); // torpor depletion per second for level torporDeplPS = torporDepletionPS(taming.torporDepletionPS0, level); } // how much food / resources of the different kinds that this creature eats is needed for (int f = 0; f < usedFood.Count; f++) { if (foodAmount[f] > 0) { food = usedFood[f]; bool specialFood = (taming.specialFoodValues != null && taming.specialFoodValues.ContainsKey(food)); if (specialFood || Values.V.foodData.ContainsKey(food)) { foodAffinity = 0; foodValue = 0; // check if (creature handles this food in a special way (e.g. scorpions not liking raw meat as much) if (specialFood) { foodAffinity = taming.specialFoodValues[food].affinity; foodValue = taming.specialFoodValues[food].foodValue; } else { foodAffinity = Values.V.foodData[food].affinity; foodValue = Values.V.foodData[food].foodValue; } foodAffinity *= specialFood ? taming.specialFoodValues[food].quantity : 1; if (nonViolent) { // consider wake taming multiplicators (non - violent taming) foodAffinity *= taming.wakeAffinityMult; foodValue = foodValue * taming.wakeFoodDeplMult; } foodAffinity *= tamingSpeedMultiplier * 2; // *2 in accordance with the permament 2x taming-bonus that was introduced in the game on 2016-12-12 if (foodAffinity > 0 && foodValue > 0) { // amount of food needed for the left affinity. foodPiecesNeeded = (int)Math.Ceiling(affinityNeeded / foodAffinity); if (foodPiecesNeeded > foodAmount[f]) { foodPiecesNeeded = foodAmount[f]; } foodAmountUsed[f] = foodPiecesNeeded; // time to eat needed food seconds = (int)Math.Ceiling(foodPiecesNeeded * foodValue / (taming.foodConsumptionBase * taming.foodConsumptionMult * tamingFoodRateMultiplier)); affinityNeeded -= foodPiecesNeeded * foodAffinity; if (te > 0) { double factor = taming.tamingIneffectiveness / (100 * foodAffinity); for (int i = 0; i < foodPiecesNeeded; i++) { te -= Math.Pow(te, 2) * factor; } } if (!nonViolent) { //extra needed torpor to eat needed food torporNeeded += (torporDeplPS * seconds); } totalSeconds += seconds; } if (affinityNeeded <= 0) { break; } } } } torporNeeded -= totalTorpor; if (torporNeeded < 0) { torporNeeded = 0; } // amount of Narcoberries(give 7.5 torpor each over 3s) neededNarcoberries = (int)Math.Ceiling(torporNeeded / (7.5 + 3 * torporDeplPS)); // amount of Narcotics(give 40 each over 8s) neededNarcotics = (int)Math.Ceiling(torporNeeded / (40 + 8 * torporDeplPS)); // amount of BioToxines (give 80 each over 16s) neededBioToxines = (int)Math.Ceiling(torporNeeded / (80 + 16 * torporDeplPS)); enoughFood = affinityNeeded <= 0; // needed Time to eat duration = new TimeSpan(0, 0, totalSeconds); if (te < 0) { te = 0; } te *= .01; bonusLevel = (int)Math.Floor(level * te / 2); for (int i = 0; i < usedFood.Count; i++) { if (taming.specialFoodValues != null && taming.specialFoodValues.ContainsKey(usedFood[i])) { hunger += foodAmountUsed[i] * taming.specialFoodValues[usedFood[i]].foodValue; } else if (Values.V.foodData.ContainsKey(usedFood[i])) { hunger += foodAmountUsed[i] * Values.V.foodData[usedFood[i]].foodValue; } } } }
public void setSpeciesIndex(int speciesIndex) { if (speciesIndex >= 0 && Values.V.species[speciesIndex].taming != null && this.speciesIndex != speciesIndex) { SuspendLayout(); this.speciesIndex = speciesIndex; // bone damage adjusters boneDamageAdjustersImmobilization = Taming.boneDamageAdjustersImmobilization(speciesIndex, out Dictionary <double, string> boneDamageAdjusters); int ib = 0; foreach (KeyValuePair <double, string> bd in boneDamageAdjusters) { ib++; if (ib >= rbBoneDamageAdjusters.Count) { RadioButton rbBD = new RadioButton(); gbWeaponDamage.Controls.Add(rbBD); rbBD.Location = new Point(6, 199 + 19 * ib); rbBD.AutoSize = false; rbBD.Size = new Size(194, 17); rbBoneDamageAdjusters.Add(rbBD); rbBoneDamageAdjusterValues.Add(1); rbBD.CheckedChanged += rbBoneDamage_CheckedChanged; } rbBoneDamageAdjusterValues[ib] = bd.Key; rbBoneDamageAdjusters[ib].Text = $"{Loc.s(bd.Value)} ({bd.Key}×)"; rbBoneDamageAdjusters[ib].Visible = true; } for (int j = ib + 1; j < rbBoneDamageAdjusters.Count; j++) { rbBoneDamageAdjusters[j].Visible = false; } rbBoneDamageAdjusters[0].Checked = true; // bone damage adjusters adjusted updateCalculation = false; TamingData td = Values.V.species[speciesIndex].taming; kibbleRecipe = ""; if (td.favoriteKibble != null && Kibbles.K.kibble.ContainsKey(td.favoriteKibble)) { kibbleRecipe = "\n\nKibble:" + Kibbles.K.kibble[td.favoriteKibble].RecipeAsText(); } foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * tamingFoodRateMultiplier; int i = 0; if (td.eats != null) { for (i = 0; i < td.eats.Count; i++) { string f = td.eats[i]; TamingFoodControl tf; if (i >= foodControls.Count) { tf = new TamingFoodControl(f); tf.valueChanged += updateTamingData; tf.Clicked += onlyOneFood; foodControls.Add(tf); flpTamingFood.Controls.Add(tf); } else { tf = foodControls[i]; tf.FoodName = f; tf.Show(); } if (f == "Kibble") { tf.foodNameDisplay = $"Kibble ({td.favoriteKibble} {Loc.s("Egg")})"; } if (td.specialFoodValues != null && td.specialFoodValues.ContainsKey(f) && td.specialFoodValues[f].quantity > 1) { tf.foodNameDisplay = td.specialFoodValues[f].quantity + "× " + tf.foodNameDisplay; } } } for (int fci = foodControls.Count - 1; fci >= i; fci--) { foodControls[fci].Hide(); } if (i > 0) { foodControls[0].amount = Taming.foodAmountNeeded(speciesIndex, (int)nudLevel.Value, tamingSpeedMultiplier, foodControls[0].FoodName, td.nonViolent); } updateCalculation = true; updateFirstFeedingWaiting(); updateTamingData(); ResumeLayout(); } }
public static void tamingTimes(int speciesI, int level, double tamingSpeedMultiplier, double tamingFoodRateMultiplier, List <string> usedFood, List <int> foodAmount, out List <int> foodAmountUsed, out TimeSpan duration, out int neededNarcoberries, out int neededNarcotics, out int neededBioToxines, out double te, out double hunger, out int bonusLevel, out bool enoughFood) { double totalTorpor = 0, torporDeplPS = 0, torporNeeded = 0; int totalSeconds = 0; bonusLevel = 0; te = 1; duration = TimeSpan.Zero; neededNarcoberries = 0; neededNarcotics = 0; neededBioToxines = 0; hunger = 0; enoughFood = false; foodAmountUsed = new List <int>(); foreach (int i in foodAmount) { foodAmountUsed.Add(0); } if (speciesI >= 0 && speciesI < Values.V.species.Count) { TamingData taming = Values.V.species[speciesI].taming; // test if creature is tamend non-violently, then use wakeTame multiplicators bool nonViolent = taming.nonViolent; double affinityNeeded = taming.affinityNeeded0 + taming.affinityIncreasePL * level; if (!nonViolent) { //total torpor for level totalTorpor = Values.V.species[speciesI].stats[7].BaseValue * (1 + Values.V.species[speciesI].stats[7].IncPerWildLevel * (level - 1)); // torpor depletion per second for level torporDeplPS = torporDepletionPS(taming.torporDepletionPS0, level); } double foodByAffinity = 0; // needed for the effectiveness calculation // how much food / resources of the different kinds that this creature eats is needed for (int f = 0; f < usedFood.Count; f++) { if (foodAmount[f] > 0) { string food = usedFood[f]; bool specialFood = taming.specialFoodValues != null && taming.specialFoodValues.ContainsKey(food); if (specialFood || Values.V.foodData.ContainsKey(food)) { double foodAffinity; double foodValue; // check if (creature handles this food in a special way (e.g. scorpions not liking raw meat as much) if (specialFood) { foodAffinity = taming.specialFoodValues[food].affinity; foodValue = taming.specialFoodValues[food].foodValue; } else { foodAffinity = Values.V.foodData[food].affinity; foodValue = Values.V.foodData[food].foodValue; } foodAffinity *= specialFood ? taming.specialFoodValues[food].quantity : 1; if (nonViolent) { // consider wake taming multiplicators (non - violent taming) foodAffinity *= taming.wakeAffinityMult; foodValue = foodValue * taming.wakeFoodDeplMult; } foodAffinity *= tamingSpeedMultiplier * 2; // *2 in accordance with the permament 2x taming-bonus that was introduced in the game on 2016-12-12 if (foodAffinity > 0 && foodValue > 0) { // amount of food needed for the left affinity. int foodPiecesNeeded = (int)Math.Ceiling(affinityNeeded / foodAffinity); if (foodPiecesNeeded > foodAmount[f]) { foodPiecesNeeded = foodAmount[f]; } foodAmountUsed[f] = foodPiecesNeeded; // time to eat needed food // mantis eats every 3 minutes, regardless of level int seconds = 0; if (Values.V.species[speciesI].name == "Mantis") { seconds = foodPiecesNeeded * 180; } else { seconds = (int)Math.Ceiling(foodPiecesNeeded * foodValue / (taming.foodConsumptionBase * taming.foodConsumptionMult * tamingFoodRateMultiplier)); } affinityNeeded -= foodPiecesNeeded * foodAffinity; // new approach with 1/(1 + IM*IA*N/AO + ID*D) from https://forums.unrealengine.com/development-discussion/modding/ark-survival-evolved/56959-tutorial-dinosaur-taming-parameters?85457-Tutorial-Dinosaur-Taming-Parameters= foodByAffinity += foodPiecesNeeded / foodAffinity; if (!nonViolent) { //extra needed torpor to eat needed food torporNeeded += torporDeplPS * seconds; } totalSeconds += seconds; } if (affinityNeeded <= 0) { break; } } } } // add tamingIneffectivenessMultiplier? Needs settings? te = 1 / (1 + taming.tamingIneffectiveness * foodByAffinity); // ignores damage, which has no input torporNeeded -= totalTorpor; if (torporNeeded < 0) { torporNeeded = 0; } // amount of Narcoberries(give 7.5 torpor each over 3s) neededNarcoberries = (int)Math.Ceiling(torporNeeded / (7.5 + 3 * torporDeplPS)); // amount of Narcotics(give 40 each over 8s) neededNarcotics = (int)Math.Ceiling(torporNeeded / (40 + 8 * torporDeplPS)); // amount of BioToxines (give 80 each over 16s) neededBioToxines = (int)Math.Ceiling(torporNeeded / (80 + 16 * torporDeplPS)); enoughFood = affinityNeeded <= 0; // needed Time to eat duration = new TimeSpan(0, 0, totalSeconds); if (te < 0) // TODO correct? <0 possible? { te = 0; } bonusLevel = (int)Math.Floor(level * te / 2); for (int i = 0; i < usedFood.Count; i++) { if (taming.specialFoodValues != null && taming.specialFoodValues.ContainsKey(usedFood[i])) { hunger += foodAmountUsed[i] * taming.specialFoodValues[usedFood[i]].foodValue; } else if (Values.V.foodData.ContainsKey(usedFood[i])) { hunger += foodAmountUsed[i] * Values.V.foodData[usedFood[i]].foodValue; } } } }
public void SetSpecies(Species species, bool forceRefresh = false) { if (species == null || (_selectedSpecies == species && !forceRefresh)) { return; } _selectedSpecies = species; if (species.taming == null) { NoTamingData(); return; } this.SuspendDrawing(); SuspendLayout(); string speciesName = species.name; linkLabelWikiPage.Text = "Wiki: " + speciesName; linkLabelWikiPage.Tag = speciesName; _tt.SetToolTip(linkLabelWikiPage, ArkWiki.WikiUrl(speciesName)); // bone damage adjusters _boneDamageAdjustersImmobilization = Taming.BoneDamageAdjustersImmobilization(_selectedSpecies, out Dictionary <string, double> boneDamageAdjusters); int ib = 0; foreach (KeyValuePair <string, double> bd in boneDamageAdjusters) { ib++; if (ib >= _rbBoneDamageAdjusters.Count) { RadioButton rbBD = new RadioButton(); flcBodyDamageMultipliers.Controls.Add(rbBD); flcBodyDamageMultipliers.SetFlowBreak(rbBD, true); rbBD.AutoSize = true; _rbBoneDamageAdjusters.Add(rbBD); _rbBoneDamageAdjusterValues.Add(1); rbBD.CheckedChanged += rbBoneDamage_CheckedChanged; } _rbBoneDamageAdjusterValues[ib] = bd.Value; _rbBoneDamageAdjusters[ib].Text = $"{Loc.S(bd.Key)} (× {bd.Value})"; _rbBoneDamageAdjusters[ib].Visible = true; } for (int j = ib + 1; j < _rbBoneDamageAdjusters.Count; j++) { _rbBoneDamageAdjusters[j].Visible = false; } _rbBoneDamageAdjusters[0].Checked = true; // bone damage adjusters adjusted _updateCalculation = false; TamingData td = species.taming; _kibbleRecipe = string.Empty; // list all recipes of kibbles that give a reasonable affinity (assuming that is larger or equal than 100) foreach (var k in Kibbles.K.kibble) { var kibbleName = $"{k.Key} Kibble"; var kibbleFood = Values.V.GetTamingFood(species, kibbleName); if (kibbleFood != null && kibbleFood.affinity >= 100) { _kibbleRecipe += $"\n\n{k.Key} Kibble:{k.Value.RecipeAsText()}"; } } _foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * _tamingFoodRateMultiplier; SetTamingFoodControls(species); _updateCalculation = true; UpdateFirstFeedingWaiting(); UpdateTamingData(); if (Properties.Settings.Default.TamingFoodOrderByTime) { SetOrderOfTamingFood(true, true); } ResumeLayout(); this.ResumeDrawing(); }
public static void tamingTimes(int speciesI, int level, List <string> usedFood, List <int> foodAmount, out List <int> foodAmountUsed, out TimeSpan duration, out int neededNarcoberries, out int neededNarcotics, out int neededBioToxines, out double te, out bool enoughFood) { double affinityNeeded = 0, totalTorpor = 0, torporDeplPS = 0, foodAffinity, foodValue, torporNeeded = 0; string food; int seconds = 0, totalSeconds = 0, foodPiecesNeeded; te = 1; duration = new TimeSpan(0); neededNarcoberries = 0; neededNarcotics = 0; neededBioToxines = 0; enoughFood = false; foodAmountUsed = new List <int>(); foreach (int i in foodAmount) { foodAmountUsed.Add(0); } if (speciesI >= 0 && speciesI < Values.V.species.Count) { te = 100; TamingData taming = Values.V.species[speciesI].taming; // test if(creature is tamend non-violently, then use wakeTame multiplicators bool nonViolent = false; if (taming.nonViolent) { nonViolent = true; } affinityNeeded = taming.affinityNeeded0 + taming.affinityIncreasePL * level; if (!nonViolent) { //total torpor for level totalTorpor = Values.V.species[speciesI].stats[7].BaseValue * (1 + Values.V.species[speciesI].stats[7].IncPerWildLevel * (level - 1)); // torpor depletion per second for level // here the linear approach of 0.01819 * baseTorporDepletion / level is used. Data shows, it's actual an exponential increase torporDeplPS = taming.torporDepletionPS0 * (1 + 0.01819 * level); } // how much food / resources of the different kinds that this creature eats is needed for (int f = 0; f < usedFood.Count; f++) { if (foodAmount[f] > 0) { food = usedFood[f]; bool specialFood = (taming.specialFoodValues != null && taming.specialFoodValues.ContainsKey(food)); if (specialFood || Values.V.foodData.ContainsKey(food)) { foodAffinity = 0; foodValue = 0; // check if (creature handles this food in a special way (e.g. scorpions not liking raw meat as much) if (specialFood) { foodAffinity = taming.specialFoodValues[food].affinity; foodValue = taming.specialFoodValues[food].foodValue; } else { foodAffinity = Values.V.foodData[food].affinity; foodValue = Values.V.foodData[food].foodValue; } if (nonViolent) { // consider wake taming multiplicators (non - violent taming) foodAffinity *= taming.wakeAffinityMult; foodValue = foodValue * taming.wakeFoodDeplMult; } foodAffinity *= Values.V.tamingSpeedMultiplier * 2; // *2 in accordance with the permament 2x taming-bonus that was introduced in the game on 1016-12-12 if (foodAffinity > 0 && foodValue > 0) { // amount of food needed for the left affinity. foodPiecesNeeded = (int)Math.Ceiling(affinityNeeded / foodAffinity); if (foodPiecesNeeded > foodAmount[f]) { foodPiecesNeeded = foodAmount[f]; } foodAmountUsed[f] = foodPiecesNeeded; // time to eat needed food seconds = (int)Math.Ceiling(foodPiecesNeeded * foodValue / (taming.foodConsumptionBase * taming.foodConsumptionMult * Values.V.tamingFoodRateMultiplier)); affinityNeeded -= foodPiecesNeeded * foodAffinity; if (te > 0) { double factor = taming.tamingIneffectiveness / (100 * foodAffinity); for (int i = 0; i < foodPiecesNeeded; i++) { te -= Math.Pow(te, 2) * factor; } } if (!nonViolent) { //extra needed torpor to eat needed food torporNeeded += (torporDeplPS * seconds); } totalSeconds += seconds; } if (affinityNeeded <= 0) { break; } } } } torporNeeded -= totalTorpor; if (torporNeeded < 0) { torporNeeded = 0; } // amount of Narcoberries(give 7.5 torpor each over 3s) neededNarcoberries = (int)Math.Ceiling(torporNeeded / (7.5 + 3 * torporDeplPS)); // amount of Narcotics(give 40 each over 5s) neededNarcotics = (int)Math.Ceiling(torporNeeded / (40 + 5 * torporDeplPS)); // amount of BioToxines (give 80 each over 16s) neededBioToxines = (int)Math.Ceiling(torporNeeded / (80 + 16 * torporDeplPS)); enoughFood = affinityNeeded <= 0; // needed Time to eat duration = new TimeSpan(0, 0, totalSeconds); if (te < 0) { te = 0; } te *= .01; if (!nonViolent) { // print needed tranq arrows needed to ko creature. // Bow - arrow causes 20 dmg, tranqMultiplier are 2 + 2.5 = 4.5 ==> 90 Torpor / arrow. // crossbow 35 dmg * 4.5 ==> 157.5 torpor // slingshot: 14 dmg, stone - tranq - mult: 1.75 ==> 24.5 torpor // wooden club: 10 torpor // longneck dart: 26 * 8.5 = 221 // string info = "Wooden Club Hits × " + Math.Ceiling(totalTorpor / 10) + "; Slingshot Hits ×" + Math.Ceiling(totalTorpor / 24.5) + "; Tranquilizer Arrows with a Bow × " + Math.Ceiling(totalTorpor / 90) + "; Tranquilizer Arrows with a Crossbow × " + Math.Ceiling(totalTorpor / 157.5) + "; Tranquilizer Dart Shots × " + Math.Ceiling(totalTorpor / 221); // print torpor depletion per s // string info = "Torpor-depletion: " + Math.Round(torporDeplPS, 2) + " / s; Time until all torpor is depleted: " + (totalTorpor / torporDeplPS) + " s, That is approx.one Narcoberry every " + (Math.Floor(75 / torporDeplPS) / 10 + 3) + " s or one Narcotic every " + (Math.Floor(400 / torporDeplPS) / 10 + 5) + " s"; } } }