static IEnumerator <Def> RollInfusion(ChanceDef chanceDef, Thing thing, QualityCategory q, bool skipThingFilter) { IEnumerable <Def> available = DefDatabase <Def> .AllDefs; bool squash = false; if (chanceDef.allowTags != null) { available = available.Where(i => chanceDef.allowTags.Intersect(i.tags).Any()); squash = true; } if (!skipThingFilter) { available = available.Where(i => i.filter?.Allows(thing) ?? true); squash = true; } if (squash) { available = available.ToList(); } while (true) { var tier = RollTier(q); // select Infused Defs List <Def> selected; do { selected = available.Where(i => i.tier == tier).ToList(); #if DEBUG if (selected.Count == 0) { Log.Message($" > No available infusions in {tier} tier for {thing.def.label}"); } #endif tier--; } while (selected.Count == 0 && tier >= 0); if (selected.Count == 0) { #if DEBUG Log.Warning($" > No available infusions for {thing.def.label}"); #endif yield break; } yield return(selected.RandomElementByWeight(i => i.weight)); } }
static IEnumerator <float> RollChance(ChanceDef chanceDef, Thing thing, QualityCategory q) { foreach (var slotChance in chanceDef.slots) { float chance = chanceDef.Chance(q) * slotChance; bool roll = Rand.Chance(chance); #if DEBUG Log.Message($" > Rolled {roll} with {chance}"); #endif if (roll) { yield return(chance); } else { break; } } if (thing.def.apparel != null && chanceDef.slotBonusPerParts > 0) { int bonus = thing.def.apparel.bodyPartGroups.Count % chanceDef.slotBonusPerParts; float firstSlotChance = chanceDef.slots.FirstOrFallback(1f); #if DEBUG Log.Message($" + Bonus {bonus}"); #endif for (int i = 1; i <= bonus; i++) { float chance = chanceDef.Chance(q) * firstSlotChance * 0.8f / i; if (Rand.Chance(chance)) { yield return(chance); } else { break; } } } }