protected void SpawnPawns(IncidentParms parms, List <Pawn> spawned) { var map = (Map)parms.target; var selection = GetPawnsToSpawn(parms).Distinct(); foreach (var pawn in selection) { try { var visitor = SpawnGroupUtility.SpawnVisitor(spawned, pawn, map, parms.spawnCenter); if (visitor.needs?.rest != null) { visitor.needs.rest.CurLevel = Rand.Range(0.1f, 0.7f); } } catch (Exception e) { Log.Error($"Hospitality: Failed to spawn pawn {pawn?.Label}:\n{e}"); if (pawn.Spawned) { pawn.DeSpawn(); pawn.DestroyOrPassToWorld(); } } } }
private bool SpawnGroup(IncidentParms parms, Map map) { var visitors = new List <Pawn>(); try { //Log.Message(string.Format("Spawning visitors from {0}, at {1}.", parms.faction, parms.spawnCenter)); SpawnPawns(parms, visitors); SpawnGroupUtility.CheckVisitorsValid(visitors); if (visitors == null || visitors.Count == 0) { return(false); } var area = visitors.First().GetGuestArea() ?? map.GetMapComponent().defaultAreaRestriction; var spot = GetSpot(map, area, visitors.First()); if (!spot.IsValid) { throw new Exception($"Visitors from {parms.faction.Name} failed to find a valid travel target from {visitors.First()?.Position} to guest area {area?.Label}."); } GiveItems(visitors); var stayDuration = (int)(Rand.Range(1f, 2.4f) * GenDate.TicksPerDay); CreateLord(parms.faction, spot, visitors, map, true, true, stayDuration); } catch (Exception e) { var faction = parms.faction?.Name; var factionType = parms.faction?.def.label; Log.Error($"Hospitality: Something failed when setting up visitors from faction {faction} ({factionType}):\n{e}"); foreach (var visitor in visitors) { if (visitor?.Spawned == true) { visitor.DeSpawn(); visitor.DestroyOrPassToWorld(); } } GenericUtility.PlanNewVisit(map, Rand.Range(1f, 3f), parms.faction); } return(true); // be gone, event }
protected IEnumerable <Pawn> GetPawnsToSpawn(IncidentParms parms) { var totalAmount = GetGroupSize(); int knownPawnAmount = Mathf.RoundToInt(totalAmount * ChanceToKnowEachPawn); var options = SpawnGroupUtility.GetKnownPawns(parms).RandomlyUsingTitleAsChance().InRandomOrder().Take(knownPawnAmount).ToList(); if (options.Count < totalAmount) { try { // Create some new people int missing = totalAmount - options.Count; var newPawns = GenerateNewPawns(parms, missing); options.AddRange(newPawns); } catch (Exception e) { Log.Error($"Failed to create new pawns for faction {parms.faction?.Name}.\n{e}"); } } return(options); }
private static void GiveItems(IEnumerable <Pawn> visitors) { foreach (var visitor in visitors) { PawnInventoryGenerator.GiveRandomFood(visitor); if (Rand.Value < 0.5f) { visitor.TryGiveBackpack(); } float totalValue = 0; // Money //Log.Message("Goodwill: "+visitor.Faction.ColonyGoodwill); var wealthBase = visitor.Faction.PlayerGoodwill; var title = visitor.royalty?.MostSeniorTitle; if (title != null) { wealthBase += title.def.seniority / 2; } var amountS = Mathf.Max(0, Mathf.RoundToInt(Rand.Gaussian(wealthBase, wealthBase) * 2)) + Rand.Range(0, 40); if (amountS >= Rand.Range(10, 25)) { var money = SpawnGroupUtility.CreateRandomItem(visitor, ThingDefOf.Silver); money.stackCount = amountS; var spaceFor = visitor.GetInventorySpaceFor(money); if (spaceFor > 0) { money.stackCount = Mathf.Min(spaceFor, amountS); var success = visitor.inventory.innerContainer.TryAdd(money); if (success) { totalValue += money.MarketValue * money.stackCount; } else if (!money.Destroyed) { money.Destroy(); } } } // Items float maxValue = (wealthBase + 25) * Rand.Range(5, 8); if (maxValue - totalValue <= 100) { maxValue = totalValue + Rand.Range(25, 60); // At least bring some junk } float value = maxValue - totalValue; int curCount = 0; while (value > 100 && curCount < 200) { //Log.Message("Total is now " + totalValue + ", space left is " + space); curCount++; bool apparel = Rand.Value < 0.5f; ThingDef thingDef; do { thingDef = SpawnGroupUtility.GetRandomItem(visitor.Faction.def.techLevel, ref _items); }while (thingDef != null && apparel && thingDef.IsApparel); if (thingDef == null) { break; } //var amount = Mathf.Min(Mathf.RoundToInt(Mathf.Abs(Rand.Gaussian(1, thingDef.stackLimit/2f))), // thingDef.stackLimit); //if (amount <= 0) continue; var item = SpawnGroupUtility.CreateRandomItem(visitor, thingDef); //Log.Message(item.Label + " has this value: " + item.MarketValue); if (item.Destroyed) { continue; } if (item.MarketValue >= value) { item.Destroy(); continue; } if (item.MarketValue < 1) { item.Destroy(); continue; } var uniquesAmount = item.TryGetComp <CompQuality>() != null ? 1 : item.def.stackLimit; var maxItems = Mathf.Min(Mathf.FloorToInt(value / item.MarketValue), item.def.stackLimit, uniquesAmount); var minItems = Mathf.Max(1, Mathf.CeilToInt(Rand.Range(50, 100) / item.MarketValue)); if (maxItems < 1 || minItems > maxItems) { item.Destroy(); continue; } //Log.Message("Can fit " + maxItems+" of "+item.Label); item.stackCount = Rand.RangeInclusive(minItems, maxItems); //Log.Message("Added " + item.stackCount + " with a value of " + (item.MarketValue * item.stackCount)); var spaceFor = visitor.GetInventorySpaceFor(item); if (spaceFor > 0) { item.stackCount = Mathf.Min(spaceFor, item.stackCount); var success = visitor.inventory.innerContainer.TryAdd(item); if (success) { totalValue += item.MarketValue * item.stackCount; } else if (!item.Destroyed) { item.Destroy(); } } value = maxValue - totalValue; } } }