public static Faction SpawnNewFactionIntoWorld(CustomFactionDef newFaction) { if (Find.FactionManager.AllFactionsListForReading.Any(x => x.def == newFaction)) { Log.Error($"Attempted to spawn existing faction, {newFaction.defName}, into the world."); return(null); } Faction faction = FactionGenerator.NewGeneratedFaction(newFaction); faction.GenerateNewLeader(); if (faction.leader != null) { Log.Message($"{faction.Name} {faction.def.leaderTitle}, {faction.leader.Name} now exists."); } else { Log.Message($"{faction.Name} {faction.def.leaderTitle} failed to generate."); } Find.FactionManager.Add(faction); return(faction); }
public Dialog_WithRepresentative(Pawn representative, CustomFactionDef factionDef) : base(factionDef.representativeMessage) { this.text = factionDef.representativeMessage + "\n\n" + "SCP_DialogNote".Translate(); this.buttonAText = "Ignore".Translate(); this.buttonAAction = () => factionDef.AcceptWorker.PostIgnore(representative); this.buttonBText = "Yes".Translate(); this.buttonBAction = (() => { if (factionDef.AcceptWorker.CanAccept(representative)) { factionDef.AcceptWorker.PostAccept(representative); var factionsTracker = Find.World.GetComponent <WorldComponent_FactionsTracker>(); var faction = representative.Faction; if (factionsTracker.activeRepresentatives.Contains(representative)) { factionsTracker.activeRepresentatives.Clear(); factionsTracker.activeRepresentatives = new List <Pawn>(); factionsTracker.joinedFactionDef = (CustomFactionDef)representative.Faction.def; } NotifyAllRepresentativesToLeave(); } }); this.buttonCText = "No".Translate(); this.buttonCAction = (() => { factionDef.AcceptWorker.PostDecline(representative); var factionsTracker = Find.World.GetComponent <WorldComponent_FactionsTracker>(); if (factionsTracker.activeRepresentatives.Contains(representative)) { factionsTracker.activeRepresentatives.Remove(representative); } NotifyAllRepresentativesToLeave(); }); this.title = "SCP_Proposal".Translate(factionDef.LabelCap); this.acceptAction = (() => { factionDef.AcceptWorker.PostAccept(representative); var factionsTracker = Find.World.GetComponent <WorldComponent_FactionsTracker>(); if (factionsTracker.activeRepresentatives.Contains(representative)) { factionsTracker.activeRepresentatives.Remove(representative); } NotifyAllRepresentativesToLeave(); }); this.cancelAction = () => factionDef.AcceptWorker.PostIgnore(representative); if (buttonAText.NullOrEmpty()) { this.buttonAText = "OK".Translate(); } forcePause = true; absorbInputAroundWindow = true; //creationRealTime = RealTime.LastRealTime; onlyOneOfTypeAllowed = false; bool flag = buttonAAction == null && buttonBAction == null && buttonCAction == null; forceCatchAcceptAndCancelEventEvenIfUnfocused = (acceptAction != null || cancelAction != null || flag); closeOnAccept = flag; closeOnCancel = flag; }
public static void IntroduceFaction(CustomFactionDef newFaction) { Faction faction = SpawnNewFactionIntoWorld(newFaction); if (faction == null) { return; } SpawnNewFactionBasesIntoWorld(faction, 3); //Prevents errors where pawns will refuse to walk around and throw errors. // This is primarily due to the game not being designed for // dynamic faction introduction. foreach (Map m in Find.Maps) { m.pawnDestinationReservationManager.RegisterFaction(faction); } var map = Find.AnyPlayerHomeMap; IntVec3 result; if (!RCellFinder.TryFindRandomPawnEntryCell(out result, map, CellFinder.EdgeRoadChance_Hostile)) { Log.Error($"Failed to find spawning point along map edge for {faction.Name}"); } PawnGenerationRequest request = new PawnGenerationRequest(newFaction.representativeKind, faction, PawnGenerationContext.NonPlayer, -1, forceGenerateNewPawn: true, newborn: false, allowDead: false, allowDowned: false, canGeneratePawnRelations: true); Pawn pawn = null; try { pawn = PawnGenerator.GeneratePawn(request); } catch { Log.Error($"Failed to generate a representative pawn for {faction.Name}"); } pawn.relations.everSeenByPlayer = true; PawnComponentsUtility.AddComponentsForSpawn(pawn); GenSpawn.Spawn(pawn, result, map); IntVec3 chillSpot; RCellFinder.TryFindRandomSpotJustOutsideColony(pawn, out chillSpot); LordJob_VisitColonyUntilConditionSatisfied lordJob = new LordJob_VisitColonyUntilConditionSatisfied(faction, chillSpot); LordMaker.MakeNewLord(faction, lordJob, map, new List <Pawn>() { pawn }); var ft = Find.World.GetComponent <WorldComponent_FactionsTracker>(); if (ft.joinedFactionDef == null) { ft.activeRepresentatives.Add(pawn); } else { Messages.Message("SCP_AlreadyJoined".Translate(pawn.Faction.def.label), pawn, MessageTypeDefOf.RejectInput); } Find.LetterStack.ReceiveLetter( "SCP_FactionArrival".Translate(), "SCP_FactionArrivalDesc".Translate(newFaction.LabelCap), LetterDefOf.NeutralEvent, pawn); }
public override void WorldComponentTick() { if (Find.TickManager.TicksGame < 500) { base.WorldComponentTick(); return; } if (!firstSCPSpawned && Find.TickManager.TicksGame > ticksUntilSCPArrival) { firstSCPSpawned = true; SCPUtility.SpawnFirstSCPGroup(Find.AnyPlayerHomeMap); factionsLeftToSpawn = new List <CustomFactionDef>(DefDatabase <CustomFactionDef> .AllDefsListForReading); ticksUntilNextReveal = Find.TickManager.TicksGame + GetNextRevealInterval; } if (factionsLeftToSpawn?.Count > 0 && firstSCPSpawned && Find.TickManager.TicksGame > ticksUntilNextReveal) { ticksUntilNextReveal = Find.TickManager.TicksGame + GetNextRevealInterval; CustomFactionDef toBeRevealed = factionsLeftToSpawn.Pop(); if (factionsLeftToSpawn?.Count == 0) { factionsSpawned = true; ticksUntilHostilities = Find.TickManager.TicksGame + GetTimeUntilHostilities; } FactionUtility.IntroduceFaction(toBeRevealed); } if (Find.TickManager.TicksGame > ticksUntilHostilities) { if (joinedFactionDef == null) { ticksUntilHostilities = Find.TickManager.TicksGame + GenDate.TicksPerDay; } else { ticksUntilHostilities = int.MaxValue; var facDefs = new List <CustomFactionDef>(DefDatabase <CustomFactionDef> .AllDefsListForReading); var facs = new List <Faction>(Find.FactionManager.AllFactions .Where(f => f.def is CustomFactionDef sDef && facDefs.Contains(sDef))); var s = new StringBuilder(); if (facs == null || facs?.Count() == 0) { Log.Error("SCP :: Failed to find SCP-related factions for declaring hostilities."); return; } var hostileFacs = facs.Where(x => x.def is CustomFactionDef sDef && sDef.hostileByDefault && sDef != joinedFactionDef); if (hostileFacs != null && hostileFacs?.Count() > 0) { foreach (var hFac in hostileFacs) { hFac.TrySetNotAlly(Faction.OfPlayer, true); hFac.TrySetRelationKind(Faction.OfPlayer, FactionRelationKind.Hostile); s.AppendLine("SCP_Hostilities".Translate(hFac.Name, Faction.OfPlayer.Name)); } } foreach (var f in facs) { var fDef = f.def as CustomFactionDef; foreach (var hostileFactionName in fDef.hostileToFactions) { var hostileFaction = facs.First(ff => ff.def.defName == hostileFactionName); if (hostileFaction == f) { continue; } f.TrySetNotAlly(hostileFaction, true); f.TrySetRelationKind(hostileFaction, FactionRelationKind.Hostile); s.AppendLine("SCP_Hostilities".Translate(f.Name, hostileFaction.Name)); } } var joinedFaction = facs.First(ff => ff.def == joinedFactionDef); joinedFaction.TrySetNotHostileTo(Faction.OfPlayer); Faction.OfPlayer.TryAffectGoodwillWith(joinedFaction, 100, false); joinedFaction.TryAffectGoodwillWith(Faction.OfPlayer, 100, false); s.AppendLine(); s.AppendLine("SCP_Alliances".Translate(joinedFaction.Name, Faction.OfPlayer.HasName ? Faction.OfPlayer.Name : "Player".Translate())); Find.LetterStack.ReceiveLetter("SCP_HostilitiesDeclared".Translate(), "SCP_HostilitiesDeclaredDesc".Translate(s.ToString()), LetterDefOf.ThreatBig); } } base.WorldComponentTick(); }