private static Thing CreateRandomItem(Pawn visitor, ThingDef thingDef) { ThingDef stuff = GenStuff.RandomStuffFor(thingDef); var item = ThingMaker.MakeThing(thingDef, stuff); item.stackCount = 1; CompQuality compQuality = item.TryGetComp <CompQuality>(); if (compQuality != null) { compQuality.SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); } if (item.def.Minifiable) { item = item.MakeMinified(); } if (item.def.useHitPoints) { // Make sure health is at least 60%. Otherwise too expensive items can become gifts. const float minHealthPct = 0.6f; var healthRange = visitor.kindDef.gearHealthRange; healthRange.min = minHealthPct; healthRange.max = Mathf.Max(minHealthPct, healthRange.max); var healthPct = healthRange.RandomInRange; if (healthPct < 1) { int num = Mathf.RoundToInt(healthPct * item.MaxHitPoints); num = Mathf.Max(1, num); item.HitPoints = num; } } return(item); }
/// <summary> /// Change quality carried by traders depending on Faction/Goodwill/Wealth. /// </summary> /// <returns>QualityCategory depending on wealth or goodwill. Fallsback to vanilla when fails.</returns> private static QualityCategory FactionAndGoodWillDependantQuality(Faction faction, Map map, TraderKindDef trader) { if ((trader.orbital || trader.defName.Contains(value: "_Base")) && map != null) { if (Rand.Value < 0.25f) { return(QualityCategory.Normal); } float num = Rand.Gaussian(centerX: WealthQualityDeterminationCurve.Evaluate(x: map.wealthWatcher.WealthTotal), widthFactor: WealthQualitySpreadDeterminationCurve.Evaluate(x: map.wealthWatcher.WealthTotal)); num = Mathf.Clamp(value: num, min: 0f, max: QualityUtility.AllQualityCategories.Count - 0.5f); return((QualityCategory)num); } if (map != null && faction != null) { float qualityIncreaseFromTimesTradedWithFaction = Mathf.Clamp01(value: (float)map.GetComponent <MapComponent_GoodWillTrader>().TimesTraded[key: faction] / 100); float qualityIncreaseFactorFromPlayerGoodWill = Mathf.Clamp01(value: (float)faction.GoodwillWith(other: Faction.OfPlayer) / 100); if (Rand.Value < 0.25f) { return(QualityCategory.Normal); } float num = Rand.Gaussian(centerX: 2.5f + qualityIncreaseFactorFromPlayerGoodWill, widthFactor: 0.84f + qualityIncreaseFromTimesTradedWithFaction); num = Mathf.Clamp(value: num, min: 0f, max: QualityUtility.AllQualityCategories.Count - 0.5f); return((QualityCategory)num); } return(QualityUtility.GenerateQualityTraderItem()); }
public static List <Thing> GenerateWeaponsCacheReward(int gunCount) { List <Thing> returnList = new List <Thing>(); IEnumerable <ThingDef> weaponList = (from x in ThingSetMakerUtility.allGeneratableItems where x.weaponTags != null && (x.weaponTags.Contains("SpacerGun") || x.weaponTags.Contains("SniperRifle") || x.weaponTags.Contains("GunHeavy") || x.weaponTags.Contains("IndustrialGunAdvanced")) select x); for (int i = 0; i < gunCount; i++) { ThingDef thingDef; weaponList.TryRandomElement(out thingDef); if (thingDef == null) { Log.Error("Could not resolve thingdef to spawn weapons"); continue; } Thing weapon = ThingMaker.MakeThing(thingDef); CompQuality compQuality = weapon.TryGetComp <CompQuality>(); if (compQuality != null) { compQuality.SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); } returnList.Add(weapon); } return(returnList); }
private Thing TryAddQualityToThing(Thing thing) { if (thing.TryGetQuality(out QualityCategory qualityCategory)) { thing.TryGetComp <CompQuality>().SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); } return(thing); }
public static List <Thing> GenerateApperalReward(int apperalCount) { List <Thing> returnList = new List <Thing>(); IEnumerable <ThingDef> apperalList = (from x in DefDatabase <ThingDef> .AllDefs where x.IsApparel == true && x.apparel.tags != null && (x.apparel.tags.Contains("SpacerMilitary") || x.apparel.tags.Contains("IndustrialAdvanced") || x.apparel.tags.Contains("BeltDefense") || x.apparel.tags.Contains("BeltDefensePop")) select x); for (int i = 0; i < apperalCount; i++) { ThingDef thingDef; ThingDef stuffDef = null; if (apperalList == null) { Log.Error("Potential apperal list count is 0"); break; } apperalList.TryRandomElement(out thingDef); if (thingDef == null) { Log.Error("Could not resolve thingdef to spawn apperal"); continue; } if (thingDef.MadeFromStuff) { if (!(from x in GenStuff.AllowedStuffsFor(thingDef, TechLevel.Undefined) where !PawnWeaponGenerator.IsDerpWeapon(thingDef, x) select x).TryRandomElementByWeight((ThingDef x) => x.stuffProps.commonality, out stuffDef)) { stuffDef = GenStuff.RandomStuffByCommonalityFor(thingDef, TechLevel.Undefined); } } Thing apperal = ThingMaker.MakeThing(thingDef, stuffDef); CompQuality compQuality = apperal.TryGetComp <CompQuality>(); if (compQuality != null) { compQuality.SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); } returnList.Add(apperal); } return(returnList); }
public static Thing CreateRandomItem(Pawn visitor, ThingDef thingDef) { ThingDef stuff = GenStuff.RandomStuffFor(thingDef); var item = ThingMaker.MakeThing(thingDef, stuff); item.stackCount = 1; CompQuality compQuality = item.TryGetComp <CompQuality>(); compQuality?.SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); if (item.def.Minifiable) { item = item.MakeMinified(); if (item.GetInnerIfMinified() == null) { Log.ErrorOnce($"Hospitality: Tried to create minified {item.def.defName}, but InnerThing ended up being null. It is from {item.def.modContentPack.Name}.", 42896749 + item.def.debugRandomId); item.Destroy(); return(null); } } if (item.def.useHitPoints) { // Make sure health is at least 60%. Otherwise too expensive items can become gifts. const float minHealthPct = 0.6f; var healthRange = visitor.kindDef.gearHealthRange; healthRange.min = minHealthPct; healthRange.max = Mathf.Max(minHealthPct, healthRange.max); var healthPct = healthRange.RandomInRange; if (healthPct < 1) { int num = Mathf.RoundToInt(healthPct * item.MaxHitPoints); num = Mathf.Max(1, num); item.HitPoints = num; } } return(item); }
public static void setItemQualityRandom(Thing thing) { QualityCategory qual = QualityUtility.GenerateQualityTraderItem(); thing.TryGetComp <CompQuality>().SetQuality(qual, ArtGenerationContext.Outsider); }
private Toil Collect() { return(new Toil() { initAction = delegate { // Increment the record for how many cells this pawn has mined since this counts as mining // TODO: B19 - change to quarry m3 pawn.records.Increment(RecordDefOf.CellsMined); // Start with None to act as a fallback. Rubble will be returned with this parameter ResourceRequest req = ResourceRequest.None; // Use the mineModeToggle to determine the request req = (ResourceRequest)(((int)Quarry.mineModeToggle) + 1); MoteType mote = MoteType.None; int stackCount = 1; // Get the resource from the quarry ThingDef def = Quarry.GiveResources(req, out mote, out bool singleSpawn, out bool eventTriggered); // If something went wrong, bail out if (def == null || def.thingClass == null) { Log.Warning("Quarry:: Tried to quarry mineable ore, but the ore given was null."); mote = MoteType.None; singleSpawn = true; // This shouldn't happen at all, but if it does let's add a little reward instead of just giving rubble def = ThingDefOf.ChunkSlagSteel; } Thing haulableResult = ThingMaker.MakeThing(def); if (!singleSpawn && def != ThingDefOf.ComponentIndustrial) { int sub = (int)(def.BaseMarketValue / 2f); sub = Mathf.Clamp(sub, 0, 10); stackCount += Mathf.Min(Rand.RangeInclusive(15 - sub, 40 - (sub * 2)), def.stackLimit - 1); } if (def == ThingDefOf.ComponentIndustrial) { stackCount += Random.Range(0, 1); } haulableResult.stackCount = stackCount; if (stackCount >= 30) { mote = MoteType.LargeVein; } bool usesQuality = false; // Adjust quality for items that use it if (haulableResult.TryGetComp <CompQuality>() != null) { usesQuality = true; haulableResult.TryGetComp <CompQuality>().SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); } // Adjust hitpoints, this was just mined from under the ground after all if (def.useHitPoints && !def.thingCategories.Contains(QuarryDefOf.StoneChunks) && def != ThingDefOf.ComponentIndustrial) { float minHpThresh = 0.25f; if (usesQuality) { minHpThresh = Mathf.Clamp((float)haulableResult.TryGetComp <CompQuality>().Quality / 10f, 0.1f, 0.7f); } int hp = Mathf.RoundToInt(Rand.Range(minHpThresh, 1f) * haulableResult.MaxHitPoints); hp = Mathf.Max(1, hp); haulableResult.HitPoints = hp; } // Place the resource near the pawn GenPlace.TryPlaceThing(haulableResult, pawn.Position, Map, ThingPlaceMode.Near); // If the resource had a mote, throw it if (mote == MoteType.LargeVein) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_LargeVein, Color.green, 3f); } else if (mote == MoteType.Failure) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_MiningFailed, Color.red, 3f); } // If the sinkhole event was triggered, damage the pawn and end this job // Even if the sinkhole doesn't incapacitate the pawn, they will probably want to seek medical attention if (eventTriggered) { NamedArgument pawnName = new NamedArgument(0, pawn.NameShortColored); Messages.Message("QRY_MessageSinkhole".Translate(pawnName), pawn, MessageTypeDefOf.NegativeEvent); DamageInfo dInfo = new DamageInfo(DamageDefOf.Crush, 9, category: DamageInfo.SourceCategory.Collapse); dInfo.SetBodyRegion(BodyPartHeight.Bottom, BodyPartDepth.Inside); pawn.TakeDamage(dInfo); EndJobWith(JobCondition.Succeeded); } else { // Prevent the colonists from trying to haul rubble, which just makes them visit the platform if (def == ThingDefOf.Filth_RubbleRock) { EndJobWith(JobCondition.Succeeded); } else { // If this is a chunk or slag, mark it as haulable if allowed to if (def.designateHaulable && Quarry.autoHaul) { Map.designationManager.AddDesignation(new Designation(haulableResult, DesignationDefOf.Haul)); } // Try to find a suitable storage spot for the resource, removing it from the quarry // If there are no platforms with free space, or if the resource is a chunk, try to haul it to a storage area if (Quarry.autoHaul) { if (!def.thingCategories.Contains(QuarryDefOf.StoneChunks) && Quarry.HasConnectedPlatform && Quarry.TryFindBestPlatformCell(haulableResult, pawn, Map, pawn.Faction, out IntVec3 c)) { job.SetTarget(TargetIndex.B, haulableResult); job.count = haulableResult.stackCount; job.SetTarget(TargetIndex.C, c); } else { StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(haulableResult); Job result; if (!StoreUtility.TryFindBestBetterStorageFor(haulableResult, pawn, Map, currentPriority, pawn.Faction, out c, out IHaulDestination haulDestination, true)) { JobFailReason.Is("NoEmptyPlaceLower".Translate(), null); } else if (haulDestination is ISlotGroupParent) { result = HaulAIUtility.HaulToCellStorageJob(pawn, haulableResult, c, false); } else { job.SetTarget(TargetIndex.B, haulableResult); job.count = haulableResult.stackCount; job.SetTarget(TargetIndex.C, c); } } }
public static void TrySetQuality(this Thing thing, QualityCategory?quality) { var comp = thing.TryGetComp <CompQuality>(); comp?.SetQuality(quality ?? QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); }
public static IEnumerable <Thing> GenerateWanderingCaravanInventory(float?fixedCaravanValue = null) { if (fixedCaravanValue < 1f) { Log.Error("Tried to generate a wandering caravan inventory with a fixed caravan value smaller than 1"); yield break; } if (fixedCaravanValue == null) { float randValue = Rand.Value; float caravanValue = 50f; ModifyValueBasedOnChance(ref caravanValue, randValue, 0.75f, 50f); // 100 ModifyValueBasedOnChance(ref caravanValue, randValue, 0.5f, 50f); // 150 ModifyValueBasedOnChance(ref caravanValue, randValue, 0.4f, 50f); // 200 ModifyValueBasedOnChance(ref caravanValue, randValue, 0.25f, 25f); // 225 ModifyValueBasedOnChance(ref caravanValue, randValue, 0.1f, 25f); // 250 ModifyValueBasedOnChance(ref caravanValue, randValue, 0.05f, 25f); // 275 ModifyValueBasedOnChance(ref caravanValue, randValue, 0.075f, 25f); // 300 ModifyValueBasedOnChance(ref caravanValue, randValue, 0.025f, 25f); // 325 caravanValue += caravanValue * Rand.Range(-0.2f, 0.2f); fixedCaravanValue = caravanValue; } ThingSetMakerParams thingSetMakerParams = default(ThingSetMakerParams); thingSetMakerParams.traderDef = DefDatabase <TraderKindDef> .AllDefs.Where(trader => !trader.orbital).RandomElementByWeight(trader => trader.commonality); List <Thing> traderInventory = ThingSetMakerDefOf.TraderStock.root.Generate(thingSetMakerParams); traderInventory.RemoveAll(t => t is Pawn || t.MarketValue < 1 || t is MinifiedThing || ((CompProperties_Rottable)t.TryGetComp <CompRottable>()?.props)?.daysToRotStart < 25); List <Thing> inventory = new List <Thing>(); while (inventory.CollectionMarketValue() < fixedCaravanValue && traderInventory.Count > 0) { Thing selectedItem = traderInventory.RandomElementByWeight(thing => Math223.Inverse(thing.MarketValue)); if (inventory.Select(item => item.def).Contains(selectedItem.def)) { ++inventory.First(item => item.def == selectedItem.def).stackCount; } else { inventory.Add(ThingMaker.MakeThing(selectedItem.def, selectedItem.Stuff)); } if (--selectedItem.stackCount == 0) { traderInventory.Remove(selectedItem); } } foreach (Thing item in inventory) { CompRottable compRottable = item.TryGetComp <CompRottable>(); if (compRottable != null) { compRottable.RotProgress = ((CompProperties_Rottable)compRottable.props).TicksToRotStart * Rand.Range(0.5f, 0.9f); } CompQuality compQuality = item.TryGetComp <CompQuality>(); if (compQuality != null) { compQuality.SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider); } yield return(item); } }