MutationSystem style changes (#19954)

This commit is contained in:
TomaszKawalec
2023-09-16 22:25:53 +02:00
committed by GitHub
parent d5aa958421
commit 282db32ad8

View File

@@ -39,41 +39,42 @@ public sealed class MutationSystem : EntitySystem
const int totalbits = 265; const int totalbits = 265;
// Tolerances (55) // Tolerances (55)
MutateFloat(ref seed.NutrientConsumption , 0.05f , 1.2f , 5 , totalbits , severity); MutateFloat(ref seed.NutrientConsumption , 0.05f, 1.2f, 5, totalbits, severity);
MutateFloat(ref seed.WaterConsumption , 3f , 9f , 5 , totalbits , severity); MutateFloat(ref seed.WaterConsumption , 3f , 9f , 5, totalbits, severity);
MutateFloat(ref seed.IdealHeat , 263f , 323f , 5 , totalbits , severity); MutateFloat(ref seed.IdealHeat , 263f , 323f, 5, totalbits, severity);
MutateFloat(ref seed.HeatTolerance , 2f , 25f , 5 , totalbits , severity); MutateFloat(ref seed.HeatTolerance , 2f , 25f , 5, totalbits, severity);
MutateFloat(ref seed.IdealLight , 0f , 14f , 5 , totalbits , severity); MutateFloat(ref seed.IdealLight , 0f , 14f , 5, totalbits, severity);
MutateFloat(ref seed.LightTolerance , 1f , 5f , 5 , totalbits , severity); MutateFloat(ref seed.LightTolerance , 1f , 5f , 5, totalbits, severity);
MutateFloat(ref seed.ToxinsTolerance , 1f , 10f , 5 , totalbits , severity); MutateFloat(ref seed.ToxinsTolerance , 1f , 10f , 5, totalbits, severity);
MutateFloat(ref seed.LowPressureTolerance , 60f , 100f , 5 , totalbits , severity); MutateFloat(ref seed.LowPressureTolerance , 60f , 100f, 5, totalbits, severity);
MutateFloat(ref seed.HighPressureTolerance , 100f , 140f , 5 , totalbits , severity); MutateFloat(ref seed.HighPressureTolerance, 100f , 140f, 5, totalbits, severity);
MutateFloat(ref seed.PestTolerance , 0f , 15f , 5 , totalbits , severity); MutateFloat(ref seed.PestTolerance , 0f , 15f , 5, totalbits, severity);
MutateFloat(ref seed.WeedTolerance , 0f , 15f , 5 , totalbits , severity); MutateFloat(ref seed.WeedTolerance , 0f , 15f , 5, totalbits, severity);
// Stats (30*2 = 60) // Stats (30*2 = 60)
MutateFloat(ref seed.Endurance , 50f , 150f , 5 , totalbits , 2*severity); MutateFloat(ref seed.Endurance , 50f , 150f, 5, totalbits, 2 * severity);
MutateInt(ref seed.Yield , 3 , 10 , 5 , totalbits , 2*severity); MutateInt(ref seed.Yield , 3 , 10 , 5, totalbits, 2 * severity);
MutateFloat(ref seed.Lifespan , 10f , 80f , 5 , totalbits , 2*severity); MutateFloat(ref seed.Lifespan , 10f , 80f , 5, totalbits, 2 * severity);
MutateFloat(ref seed.Maturation , 3f , 8f , 5 , totalbits , 2*severity); MutateFloat(ref seed.Maturation , 3f , 8f , 5, totalbits, 2 * severity);
MutateFloat(ref seed.Production , 1f , 10f , 5 , totalbits , 2*severity); MutateFloat(ref seed.Production , 1f , 10f , 5, totalbits, 2 * severity);
MutateFloat(ref seed.Potency , 30f , 100f , 5 , totalbits , 2*severity); MutateFloat(ref seed.Potency , 30f , 100f, 5, totalbits, 2 * severity);
// Kill the plant (30) // Kill the plant (30)
MutateBool(ref seed.Viable , false , 30 , totalbits , severity); MutateBool(ref seed.Viable , false, 30, totalbits, severity);
// Fun (90) // Fun (90)
MutateBool(ref seed.Seedless , true , 10 , totalbits , severity); MutateBool(ref seed.Seedless , true , 10, totalbits, severity);
MutateBool(ref seed.Slip , true , 10 , totalbits , severity); MutateBool(ref seed.Slip , true , 10, totalbits, severity);
MutateBool(ref seed.Sentient , true , 10 , totalbits , severity); MutateBool(ref seed.Sentient , true , 10, totalbits, severity);
MutateBool(ref seed.Ligneous , true , 10 , totalbits , severity); MutateBool(ref seed.Ligneous , true , 10, totalbits, severity);
MutateBool(ref seed.Bioluminescent , true , 10 , totalbits , severity); MutateBool(ref seed.Bioluminescent, true , 10, totalbits, severity);
// Kudzu disabled until superkudzu bug is fixed // Kudzu disabled until superkudzu bug is fixed
// MutateBool(ref seed.TurnIntoKudzu , true , 5 , totalbits , severity); // MutateBool(ref seed.TurnIntoKudzu , true , 10, totalbits, severity);
MutateBool(ref seed.CanScream , true , 10 , totalbits , severity); MutateBool(ref seed.CanScream , true , 10, totalbits, severity);
seed.BioluminescentColor = RandomColor(seed.BioluminescentColor, 10, totalbits, severity); seed.BioluminescentColor = RandomColor(seed.BioluminescentColor, 10, totalbits, severity);
// ConstantUpgade (10) // ConstantUpgade (10)
MutateHarvestType(ref seed.HarvestRepeat , 10 , totalbits , severity); MutateHarvestType(ref seed.HarvestRepeat, 10, totalbits, severity);
// Gas (5) // Gas (5)
MutateGasses(ref seed.ExudeGasses, 0.01f, 0.5f, 4, totalbits, severity); MutateGasses(ref seed.ExudeGasses, 0.01f, 0.5f, 4, totalbits, severity);
@@ -119,6 +120,7 @@ public sealed class MutationSystem : EntitySystem
CrossBool(ref result.Bioluminescent, a.Bioluminescent); CrossBool(ref result.Bioluminescent, a.Bioluminescent);
// CrossBool(ref result.TurnIntoKudzu, a.TurnIntoKudzu); // CrossBool(ref result.TurnIntoKudzu, a.TurnIntoKudzu);
CrossBool(ref result.CanScream, a.CanScream); CrossBool(ref result.CanScream, a.CanScream);
CrossGasses(ref result.ExudeGasses, a.ExudeGasses); CrossGasses(ref result.ExudeGasses, a.ExudeGasses);
CrossGasses(ref result.ConsumeGasses, a.ConsumeGasses); CrossGasses(ref result.ConsumeGasses, a.ConsumeGasses);
@@ -142,94 +144,93 @@ public sealed class MutationSystem : EntitySystem
// one bit gets flipped. // one bit gets flipped.
private void MutateFloat(ref float val, float min, float max, int bits, int totalbits, float mult) private void MutateFloat(ref float val, float min, float max, int bits, int totalbits, float mult)
{ {
// Probability that a bit flip happens for this value. // Probability that a bit flip happens for this value's representation in thermometer code.
float p = mult*bits/totalbits; float probBitflip = mult * bits / totalbits;
p = Math.Clamp(p, 0, 1); probBitflip = Math.Clamp(probBitflip, 0, 1);
if (!Random(p)) if (!Random(probBitflip))
{
return; return;
}
// Starting number of bits that are high, between 0 and bits. // Starting number of bits that are high, between 0 and bits.
int n = (int)Math.Round((val - min) / (max - min) * bits); // In other words, it's val mapped linearly from range [min, max] to range [0, bits], and then rounded.
// val may be outside the range of min/max due to starting prototype values, so clamp int valInt = (int)MathF.Round((val - min) / (max - min) * bits);
n = Math.Clamp(n, 0, bits); // val may be outside the range of min/max due to starting prototype values, so clamp.
valInt = Math.Clamp(valInt, 0, bits);
// Probability that the bit flip increases n. // Probability that the bit flip increases n.
float p_increase = 1-(float)n/bits; // The higher the current value is, the lower the probability of increasing value is, and the higher the probability of decreasive it it.
int np; // In other words, it tends to go to the middle.
if (Random(p_increase)) float probIncrease = 1 - (float)valInt / bits;
int valIntMutated;
if (Random(probIncrease))
{ {
np = n + 1; valIntMutated = valInt + 1;
} }
else else
{ {
np = n - 1; valIntMutated = valInt - 1;
} }
// Set value based on mutated thermometer code. // Set value based on mutated thermometer code.
float nval = MathF.Min(MathF.Max((float)np/bits * (max - min) + min, min), max); float valMutated = Math.Clamp((float)valIntMutated / bits * (max - min) + min, min, max);
val = nval; val = valMutated;
} }
private void MutateInt(ref int n, int min, int max, int bits, int totalbits, float mult) private void MutateInt(ref int val, int min, int max, int bits, int totalbits, float mult)
{ {
// Probability that a bit flip happens for this value. // Probability that a bit flip happens for this value's representation in thermometer code.
float p = mult*bits/totalbits; float probBitflip = mult * bits / totalbits;
p = Math.Clamp(p, 0, 1); probBitflip = Math.Clamp(probBitflip, 0, 1);
if (!Random(p)) if (!Random(probBitflip))
{
return; return;
}
// Probability that the bit flip increases n. // Probability that the bit flip increases n.
float p_increase = 1-(float)n/bits; // The higher the current value is, the lower the probability of increasing value is, and the higher the probability of decreasive it it.
int np; // In other words, it tends to go to the middle.
if (Random(p_increase)) float probIncrease = 1 - (float)val / bits;
int valMutated;
if (Random(probIncrease))
{ {
np = n + 1; valMutated = val + 1;
} }
else else
{ {
np = n - 1; valMutated = val - 1;
} }
np = Math.Min(Math.Max(np, min), max); valMutated = Math.Clamp(valMutated, min, max);
n = np; val = valMutated;
} }
private void MutateBool(ref bool val, bool polarity, int bits, int totalbits, float mult) private void MutateBool(ref bool val, bool polarity, int bits, int totalbits, float mult)
{ {
// Probability that a bit flip happens for this value. // Probability that a bit flip happens for this value.
float p = mult * bits / totalbits; float probSet = mult * bits / totalbits;
p = Math.Clamp(p, 0, 1); probSet = Math.Clamp(probSet, 0, 1);
if (!Random(p)) if (!Random(probSet))
{
return; return;
}
val = polarity; val = polarity;
} }
private void MutateHarvestType(ref HarvestType val, int bits, int totalbits, float mult) private void MutateHarvestType(ref HarvestType val, int bits, int totalbits, float mult)
{ {
float p = mult * bits/totalbits; float probModify = mult * bits / totalbits;
p = Math.Clamp(p, 0, 1); probModify = Math.Clamp(probModify, 0, 1);
if (!Random(p))
if (!Random(probModify))
return; return;
if (val == HarvestType.NoRepeat) if (val == HarvestType.NoRepeat)
val = HarvestType.Repeat; val = HarvestType.Repeat;
else if (val == HarvestType.Repeat) else if (val == HarvestType.Repeat)
val = HarvestType.SelfHarvest; val = HarvestType.SelfHarvest;
} }
private void MutateGasses(ref Dictionary<Gas, float> gasses, float min, float max, int bits, int totalbits, float mult) private void MutateGasses(ref Dictionary<Gas, float> gasses, float min, float max, int bits, int totalbits, float mult)
{ {
float p = mult * bits / totalbits; float probModify = mult * bits / totalbits;
p = Math.Clamp(p, 0, 1); probModify = Math.Clamp(probModify, 0, 1);
if (!Random(p)) if (!Random(probModify))
return; return;
// Add a random amount of a random gas to this gas dictionary // Add a random amount of a random gas to this gas dictionary
@@ -247,34 +248,31 @@ public sealed class MutationSystem : EntitySystem
private void MutateChemicals(ref Dictionary<string, SeedChemQuantity> chemicals, int max, int bits, int totalbits, float mult) private void MutateChemicals(ref Dictionary<string, SeedChemQuantity> chemicals, int max, int bits, int totalbits, float mult)
{ {
float p = mult * bits / totalbits; float probModify = mult * bits / totalbits;
p = Math.Clamp(p, 0, 1); probModify = Math.Clamp(probModify, 0, 1);
if (!Random(p)) if (!Random(probModify))
return; return;
// Add a random amount of a random chemical to this set of chemicals // Add a random amount of a random chemical to this set of chemicals
ReagentPrototype selected_chemical = _robustRandom.Pick(_allChemicals); ReagentPrototype selectedChemical = _robustRandom.Pick(_allChemicals);
if (selected_chemical != null) if (selectedChemical != null)
{ {
string chemical_id = selected_chemical.ID; string chemicalId = selectedChemical.ID;
int amount = _robustRandom.Next(1, max); int amount = _robustRandom.Next(1, max);
SeedChemQuantity seed_chem_quantity = new SeedChemQuantity(); SeedChemQuantity seedChemQuantity = new SeedChemQuantity();
if (chemicals.ContainsKey(chemical_id)) if (chemicals.ContainsKey(chemicalId))
{ {
seed_chem_quantity.Min = chemicals[chemical_id].Min; seedChemQuantity.Min = chemicals[chemicalId].Min;
seed_chem_quantity.Max = chemicals[chemical_id].Max + amount; seedChemQuantity.Max = chemicals[chemicalId].Max + amount;
int potency = (int) Math.Ceiling(100.0f / (float) seed_chem_quantity.Max);
seed_chem_quantity.PotencyDivisor = potency;
chemicals[chemical_id] = seed_chem_quantity;
} }
else else
{ {
seed_chem_quantity.Min = 1; seedChemQuantity.Min = 1;
seed_chem_quantity.Max = 1 + amount; seedChemQuantity.Max = 1 + amount;
int potency = (int) Math.Ceiling(100.0f / (float) seed_chem_quantity.Max);
seed_chem_quantity.PotencyDivisor = potency;
chemicals.Add(chemical_id, seed_chem_quantity);
} }
int potencyDivisor = (int) Math.Ceiling(100.0f / seedChemQuantity.Max);
seedChemQuantity.PotencyDivisor = potencyDivisor;
chemicals[chemicalId] = seedChemQuantity;
} }
} }
@@ -305,8 +303,8 @@ public sealed class MutationSystem : EntitySystem
private Color RandomColor(Color color, int bits, int totalbits, float mult) private Color RandomColor(Color color, int bits, int totalbits, float mult)
{ {
float p = mult*bits/totalbits; float probModify = mult * bits / totalbits;
if (Random(p)) if (Random(probModify))
{ {
var colors = new List<Color>{ var colors = new List<Color>{
Color.White, Color.White,
@@ -325,33 +323,33 @@ public sealed class MutationSystem : EntitySystem
private void CrossChemicals(ref Dictionary<string, SeedChemQuantity> val, Dictionary<string, SeedChemQuantity> other) private void CrossChemicals(ref Dictionary<string, SeedChemQuantity> val, Dictionary<string, SeedChemQuantity> other)
{ {
// Go through chemicals from the pollen in swab // Go through chemicals from the pollen in swab
foreach (var other_chem in other) foreach (var otherChem in other)
{ {
// if both have same chemical, randomly pick potency ratio from the two. // if both have same chemical, randomly pick potency ratio from the two.
if (val.ContainsKey(other_chem.Key)) if (val.ContainsKey(otherChem.Key))
{ {
val[other_chem.Key] = Random(0.5f) ? other_chem.Value : val[other_chem.Key]; val[otherChem.Key] = Random(0.5f) ? otherChem.Value : val[otherChem.Key];
} }
// if target plant doesn't have this chemical, has 50% chance to add it. // if target plant doesn't have this chemical, has 50% chance to add it.
else else
{ {
if (Random(0.5f)) if (Random(0.5f))
{ {
val.Add(other_chem.Key, other_chem.Value); val.Add(otherChem.Key, otherChem.Value);
} }
} }
} }
// if the target plant has chemical that the pollen in swab does not, 50% chance to remove it. // if the target plant has chemical that the pollen in swab does not, 50% chance to remove it.
foreach (var this_chem in val) foreach (var thisChem in val)
{ {
if (!other.ContainsKey(this_chem.Key)) if (!other.ContainsKey(thisChem.Key))
{ {
if (Random(0.5f)) if (Random(0.5f))
{ {
if (val.Count > 1) if (val.Count > 1)
{ {
val.Remove(this_chem.Key); val.Remove(thisChem.Key);
} }
} }
} }
@@ -361,30 +359,30 @@ public sealed class MutationSystem : EntitySystem
private void CrossGasses(ref Dictionary<Gas, float> val, Dictionary<Gas, float> other) private void CrossGasses(ref Dictionary<Gas, float> val, Dictionary<Gas, float> other)
{ {
// Go through gasses from the pollen in swab // Go through gasses from the pollen in swab
foreach (var other_gas in other) foreach (var otherGas in other)
{ {
// if both have same gas, randomly pick ammount from the two. // if both have same gas, randomly pick ammount from the two.
if (val.ContainsKey(other_gas.Key)) if (val.ContainsKey(otherGas.Key))
{ {
val[other_gas.Key] = Random(0.5f) ? other_gas.Value : val[other_gas.Key]; val[otherGas.Key] = Random(0.5f) ? otherGas.Value : val[otherGas.Key];
} }
// if target plant doesn't have this gas, has 50% chance to add it. // if target plant doesn't have this gas, has 50% chance to add it.
else else
{ {
if (Random(0.5f)) if (Random(0.5f))
{ {
val.Add(other_gas.Key, other_gas.Value); val.Add(otherGas.Key, otherGas.Value);
} }
} }
} }
// if the target plant has gas that the pollen in swab does not, 50% chance to remove it. // if the target plant has gas that the pollen in swab does not, 50% chance to remove it.
foreach (var this_gas in val) foreach (var thisGas in val)
{ {
if (!other.ContainsKey(this_gas.Key)) if (!other.ContainsKey(thisGas.Key))
{ {
if (Random(0.5f)) if (Random(0.5f))
{ {
val.Remove(this_gas.Key); val.Remove(thisGas.Key);
} }
} }
} }