using RimWorld; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; namespace Verse { public class RecipeDef : Def { public Type workerClass = typeof(RecipeWorker); public Type workerCounterClass = typeof(RecipeWorkerCounter); [MustTranslate] public string jobString = "Doing an unknown recipe."; public WorkTypeDef requiredGiverWorkType; public float workAmount = -1f; public StatDef workSpeedStat; public StatDef efficiencyStat; public StatDef workTableEfficiencyStat; public StatDef workTableSpeedStat; public List ingredients = new List(); public ThingFilter fixedIngredientFilter = new ThingFilter(); public ThingFilter defaultIngredientFilter; public bool allowMixingIngredients; private Type ingredientValueGetterClass = typeof(IngredientValueGetter_Volume); public List forceHiddenSpecialFilters; public bool autoStripCorpses = true; public List products = new List(); public List specialProducts; public bool productHasIngredientStuff; public int targetCountAdjustment = 1; public ThingDef unfinishedThingDef; public List skillRequirements; public SkillDef workSkill; public float workSkillLearnFactor = 1f; public EffecterDef effectWorking; public SoundDef soundWorking; public List recipeUsers; public List appliedOnFixedBodyParts = new List(); public HediffDef addsHediff; public HediffDef removesHediff; public bool hideBodyPartNames; public bool isViolation; [MustTranslate] public string successfullyRemovedHediffMessage; public float surgerySuccessChanceFactor = 1f; public float deathOnFailedSurgeryChance; public bool targetsBodyPart = true; public bool anesthetize = true; public ResearchProjectDef researchPrerequisite; [NoTranslate] public List factionPrerequisiteTags; public ConceptDef conceptLearned; public bool dontShowIfAnyIngredientMissing; [Unsaved] private RecipeWorker workerInt; [Unsaved] private RecipeWorkerCounter workerCounterInt; [Unsaved] private IngredientValueGetter ingredientValueGetterInt; [Unsaved] private List premultipliedSmallIngredients; public RecipeWorker Worker { get { if (this.workerInt == null) { this.workerInt = (RecipeWorker)Activator.CreateInstance(this.workerClass); this.workerInt.recipe = this; } return this.workerInt; } } public RecipeWorkerCounter WorkerCounter { get { if (this.workerCounterInt == null) { this.workerCounterInt = (RecipeWorkerCounter)Activator.CreateInstance(this.workerCounterClass); this.workerCounterInt.recipe = this; } return this.workerCounterInt; } } public IngredientValueGetter IngredientValueGetter { get { if (this.ingredientValueGetterInt == null) { this.ingredientValueGetterInt = (IngredientValueGetter)Activator.CreateInstance(this.ingredientValueGetterClass); } return this.ingredientValueGetterInt; } } public bool AvailableNow { get { if (this.researchPrerequisite != null && !this.researchPrerequisite.IsFinished) { return false; } if (this.factionPrerequisiteTags != null) { if (this.factionPrerequisiteTags.Any((string tag) => Faction.OfPlayer.def.recipePrerequisiteTags == null || !Faction.OfPlayer.def.recipePrerequisiteTags.Contains(tag))) { return false; } } return true; } } public string MinSkillString { get { StringBuilder stringBuilder = new StringBuilder(); bool flag = false; if (this.skillRequirements != null) { for (int i = 0; i < this.skillRequirements.Count; i++) { SkillRequirement skillRequirement = this.skillRequirements[i]; stringBuilder.AppendLine(string.Concat(new object[] { " ", skillRequirement.skill.skillLabel.CapitalizeFirst(), ": ", skillRequirement.minLevel })); flag = true; } } if (!flag) { stringBuilder.AppendLine(" (" + "NoneLower".Translate() + ")"); } return stringBuilder.ToString(); } } public IEnumerable AllRecipeUsers { get { if (this.recipeUsers != null) { for (int i = 0; i < this.recipeUsers.Count; i++) { yield return this.recipeUsers[i]; } } List thingDefs = DefDatabase.AllDefsListForReading; for (int j = 0; j < thingDefs.Count; j++) { if (thingDefs[j].recipes != null && thingDefs[j].recipes.Contains(this)) { yield return thingDefs[j]; } } } } public bool UsesUnfinishedThing { get { return this.unfinishedThingDef != null; } } public bool IsSurgery { get { foreach (ThingDef current in this.AllRecipeUsers) { if (current.category == ThingCategory.Pawn) { return true; } } return false; } } public ThingDef ProducedThingDef { get { if (this.specialProducts != null) { return null; } if (this.products == null || this.products.Count != 1) { return null; } return this.products[0].thingDef; } } public float WorkAmountTotal(ThingDef stuffDef) { if (this.workAmount >= 0f) { return this.workAmount; } return this.products[0].thingDef.GetStatValueAbstract(StatDefOf.WorkToMake, stuffDef); } [DebuggerHidden] public IEnumerable PotentiallyMissingIngredients(Pawn billDoer, Map map) { for (int i = 0; i < this.ingredients.Count; i++) { IngredientCount ing = this.ingredients[i]; bool foundIng = false; List thingList = map.listerThings.ThingsInGroup(ThingRequestGroup.HaulableEver); for (int j = 0; j < thingList.Count; j++) { Thing thing = thingList[j]; if ((billDoer == null || !thing.IsForbidden(billDoer)) && !thing.Position.Fogged(map) && (ing.IsFixedIngredient || this.fixedIngredientFilter.Allows(thing)) && ing.filter.Allows(thing)) { foundIng = true; break; } } if (!foundIng) { if (ing.IsFixedIngredient) { yield return ing.filter.AllowedThingDefs.First(); } else { ThingDef def = (from x in ing.filter.AllowedThingDefs orderby x.BaseMarketValue select x).FirstOrDefault((ThingDef x) => this.$this.fixedIngredientFilter.Allows(x)); if (def != null) { yield return def; } } } } } public bool IsIngredient(ThingDef th) { for (int i = 0; i < this.ingredients.Count; i++) { if (this.ingredients[i].filter.Allows(th) && (this.ingredients[i].IsFixedIngredient || this.fixedIngredientFilter.Allows(th))) { return true; } } return false; } [DebuggerHidden] public override IEnumerable ConfigErrors() { foreach (string e in base.ConfigErrors()) { yield return e; } if (this.workerClass == null) { yield return "workerClass is null."; } } public override void ResolveReferences() { base.ResolveReferences(); if (this.workTableSpeedStat == null) { this.workTableSpeedStat = StatDefOf.WorkTableWorkSpeedFactor; } if (this.workTableEfficiencyStat == null) { this.workTableEfficiencyStat = StatDefOf.WorkTableEfficiencyFactor; } for (int i = 0; i < this.ingredients.Count; i++) { this.ingredients[i].ResolveReferences(); } if (this.fixedIngredientFilter != null) { this.fixedIngredientFilter.ResolveReferences(); } if (this.defaultIngredientFilter == null) { this.defaultIngredientFilter = new ThingFilter(); if (this.fixedIngredientFilter != null) { this.defaultIngredientFilter.CopyAllowancesFrom(this.fixedIngredientFilter); } } this.defaultIngredientFilter.ResolveReferences(); } public bool PawnSatisfiesSkillRequirements(Pawn pawn) { return this.FirstSkillRequirementPawnDoesntSatisfy(pawn) == null; } public SkillRequirement FirstSkillRequirementPawnDoesntSatisfy(Pawn pawn) { if (this.skillRequirements == null) { return null; } for (int i = 0; i < this.skillRequirements.Count; i++) { if (!this.skillRequirements[i].PawnSatisfies(pawn)) { return this.skillRequirements[i]; } } return null; } public List GetPremultipliedSmallIngredients() { if (this.premultipliedSmallIngredients != null) { return this.premultipliedSmallIngredients; } this.premultipliedSmallIngredients = (from td in this.ingredients.SelectMany((IngredientCount ingredient) => ingredient.filter.AllowedThingDefs) where td.smallVolume select td).Distinct().ToList(); bool flag = true; while (flag) { flag = false; for (int i = 0; i < this.ingredients.Count; i++) { bool flag2 = this.ingredients[i].filter.AllowedThingDefs.Any((ThingDef td) => !this.premultipliedSmallIngredients.Contains(td)); if (flag2) { foreach (ThingDef current in this.ingredients[i].filter.AllowedThingDefs) { flag |= this.premultipliedSmallIngredients.Remove(current); } } } } return this.premultipliedSmallIngredients; } [DebuggerHidden] public override IEnumerable SpecialDisplayStats(StatRequest req) { if (this.workSkill != null) { yield return new StatDrawEntry(StatCategoryDefOf.Basics, "Skill".Translate(), this.workSkill.LabelCap, 0, string.Empty); } if (this.ingredients != null && this.ingredients.Count > 0) { yield return new StatDrawEntry(StatCategoryDefOf.Basics, "Ingredients".Translate(), (from ic in this.ingredients select ic.Summary).ToCommaList(true), 0, string.Empty); } if (this.skillRequirements != null && this.skillRequirements.Count > 0) { yield return new StatDrawEntry(StatCategoryDefOf.Basics, "SkillRequirements".Translate(), (from sr in this.skillRequirements select sr.Summary).ToCommaList(true), 0, string.Empty); } if (this.products != null && this.products.Count > 0) { yield return new StatDrawEntry(StatCategoryDefOf.Basics, "Products".Translate(), (from pr in this.products select pr.Summary).ToCommaList(true), 0, string.Empty); } if (this.workSpeedStat != null) { yield return new StatDrawEntry(StatCategoryDefOf.Basics, "WorkSpeedStat".Translate(), this.workSpeedStat.LabelCap, 0, string.Empty); } if (this.efficiencyStat != null) { yield return new StatDrawEntry(StatCategoryDefOf.Basics, "EfficiencyStat".Translate(), this.efficiencyStat.LabelCap, 0, string.Empty); } if (this.IsSurgery) { if (this.surgerySuccessChanceFactor >= 99999f) { yield return new StatDrawEntry(StatCategoryDefOf.Surgery, "SurgerySuccessChanceFactor".Translate(), "100%", 0, string.Empty); } else { yield return new StatDrawEntry(StatCategoryDefOf.Surgery, "SurgerySuccessChanceFactor".Translate(), this.surgerySuccessChanceFactor.ToStringPercent(), 0, string.Empty); } } } } }