Skip to content

Commit

Permalink
Fixed scenario part spawning caused by mismatched part indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
edbmods committed Aug 14, 2021
1 parent 7747e9c commit 4a0399d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 24 deletions.
54 changes: 35 additions & 19 deletions Source/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,17 @@ public void PrepareGame() {
// vanilla versions of those parts that can safely be saved without forcing a dependency on
// the mod. The GenStep_RemovePrepareCarefullyScenario class is responsible for switching out
// the actual scenario with the vanilla-friendly version at the end of the map generation process.
Scenario actualScenario = UtilityCopy.CopyExposable(Find.Scenario);
Scenario vanillaFriendlyScenario = UtilityCopy.CopyExposable(Find.Scenario);
Scenario originalScenario = Find.Scenario;
Scenario actualScenario = UtilityCopy.CopyExposable(originalScenario);
Scenario vanillaFriendlyScenario = UtilityCopy.CopyExposable(originalScenario);
Current.Game.Scenario = actualScenario;
PrepareCarefully.OriginalScenario = vanillaFriendlyScenario;

// Remove equipment scenario parts.
ReplaceScenarioParts(actualScenario, vanillaFriendlyScenario);
ReplaceScenarioParts(originalScenario, actualScenario, vanillaFriendlyScenario);

//Logger.Debug(actualScenario.GetFullInformationText());
//Logger.Debug(vanillaFriendlyScenario.GetFullInformationText());
}

protected void PrepareColonists() {
Expand Down Expand Up @@ -268,35 +272,47 @@ protected void MakePawnIntoFactionLeader(CustomPawn pawn) {
pawn.Faction.Faction.leader = pawn.Pawn;
}

protected void ReplaceScenarioParts(Scenario actualScenario, Scenario vanillaFriendlyScenario) {
// The three arguments are:
// - originalScenario: the original, unmodified scenario
// - actualScenario: this is the scenario that will be used to spawn into the map. It contains Prepare Carefully-specific scenario part that should not be saved into a save file.
// - vanillaFriendlyScenario: this is the scenario that will be saved into the game save. It will be a copy of actualScenario, but with all of the Prepare Carefully-specific
// parts replaced by vanilla parts.
protected void ReplaceScenarioParts(Scenario originalScenario, Scenario actualScenario, Scenario vanillaFriendlyScenario) {

// Create lists to hold the new scenario parts.
List<ScenPart> actualScenarioParts = new List<ScenPart>();
List<ScenPart> vanillaFriendlyScenarioParts = new List<ScenPart>();

// Get the list of parts from the original scenario. The actual scenario and the vanilla-friendly
// scenario will both be copies of the original scenario and equivalent at this point, so we only
// need to look at the parts in one of them.
// Get the list of parts from the original scenario. We do this using reflection because the "AllParts" property
// will include an extra "player faction" part that we don't want.
FieldInfo partsField = typeof(Scenario).GetField("parts", BindingFlags.NonPublic | BindingFlags.Instance);
List<ScenPart> originalParts = (List<ScenPart>)partsField.GetValue(actualScenario);

// Replace the pawn count in the configure pawns scenario part to reflect the number of
// pawns that were selected in Prepare Carefully.
foreach (var part in originalParts) {
if (!(part is ScenPart_ConfigPage_ConfigureStartingPawns configurePawnPart)) {
continue;
}
configurePawnPart.pawnCount = Find.GameInitData.startingPawnCount;
}
List<ScenPart> originalParts = (List<ScenPart>)partsField.GetValue(originalScenario);

// Fill in each part list with only the scenario parts that we're not going to replace.
// Fill in the part lists with the scenario parts that we're not going to replace. We won't need to modify any of these.
int index = -1;
foreach (var part in originalParts) {
index++;
if (!PrepareCarefully.Instance.ReplacedScenarioPartIndices.Contains(index)) {
bool partReplaced = PrepareCarefully.Instance.ReplacedScenarioParts.Contains(part);
if (!partReplaced) {
actualScenarioParts.Add(part);
vanillaFriendlyScenarioParts.Add(part);
}
//Logger.Debug(String.Format("[{0}] Replaced? {1}: {2} {3}", index, partReplaced, part.Label, String.Join(", ", part.GetSummaryListEntries("PlayerStartsWith"))));
}

// Replace the pawn count in the configure pawns scenario parts to reflect the number of
// pawns that were selected in Prepare Carefully.
foreach (var part in actualScenarioParts) {
if (!(part is ScenPart_ConfigPage_ConfigureStartingPawns configurePawnPart)) {
continue;
}
configurePawnPart.pawnCount = Find.GameInitData.startingPawnCount;
}
foreach (var part in vanillaFriendlyScenarioParts) {
if (!(part is ScenPart_ConfigPage_ConfigureStartingPawns configurePawnPart)) {
continue;
}
configurePawnPart.pawnCount = Find.GameInitData.startingPawnCount;
}

// Sort the equipment from highest count to lowest so that gear is less likely to get blocked
Expand Down
16 changes: 11 additions & 5 deletions Source/PrepareCarefully.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,11 @@ protected EquipmentRecord AddNonStandardScenarioEquipmentEntry(EquipmentKey key)
}

// Use this set to keep track of which scenario parts we're replacing with our custom ones
public HashSet<int> ReplacedScenarioPartIndices = new HashSet<int>();
public HashSet<ScenPart> ReplacedScenarioParts = new HashSet<ScenPart>();

protected void InitializeDefaultEquipment() {
int index = -1;
ReplacedScenarioPartIndices.Clear();
ReplacedScenarioParts.Clear();

// Go through all of the scenario steps that scatter resources near the player starting location and add
// them to the resource/equipment list.
Expand All @@ -222,7 +222,7 @@ record = AddNonStandardScenarioEquipmentEntry(key);
}
if (record != null) {
AddEquipment(record, count);
ReplacedScenarioPartIndices.Add(index);
ReplacedScenarioParts.Add(part);
}
}

Expand All @@ -245,7 +245,7 @@ record = AddNonStandardScenarioEquipmentEntry(key);
}
if (entry != null) {
AddEquipment(entry, count);
ReplacedScenarioPartIndices.Add(index);
ReplacedScenarioParts.Add(part);
}
else {
Logger.Warning(String.Format("Couldn't initialize all scenario equipment. Didn't find an equipment entry for {0} ({1})",
Expand Down Expand Up @@ -276,14 +276,20 @@ record = AddNonStandardScenarioEquipmentEntry(key);
}
if (entry != null) {
AddEquipment(entry);
ReplacedScenarioPartIndices.Add(index);
ReplacedScenarioParts.Add(part);
}
else {
Logger.Warning("Failed to add the expected scenario animal to list of selected equipment");
}
}
}
}

//index = 0;
//foreach (ScenPart part in Verse.Find.Scenario.AllParts) {
// Logger.Debug(String.Format("[{0}] Replaced? {1}: {2} {3}", index, ReplacedScenarioParts.Contains(part), part.Label, String.Join(", ", part.GetSummaryListEntries("PlayerStartsWith"))));
// index++;
//}
}

private static PawnKindDef RandomPet(ScenPart_StartingAnimal startingAnimal) {
Expand Down

0 comments on commit 4a0399d

Please sign in to comment.