Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct set analysis tech entry behavior breaking change #504

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Reimplement lost functionality removed by my failure to properly revi…
…ew ALL aspects of the ScannerGadget PR.

Fix: Corrected removals timing
Doc: Added more notes to describe the why things are where they are.
Doc: Added notes on methods that modify instead of replace even if the name is horrible and makes you think they should replace.
  • Loading branch information
MrPurple6411 committed Nov 20, 2023
commit 7015c1820deaba0d0e41a3b85c81bd4961203014
53 changes: 43 additions & 10 deletions Nautilus/Handlers/KnownTechHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ private static void Reinitialize()
public static void UnlockOnStart(TechType techType)
{
KnownTechPatcher.UnlockedAtStart.Add(techType);

bool removed = false;
var removalList = new List<string>();
KnownTechPatcher.DefaultRemovalTechs.ForEach((x) =>
{
if (x.Value.Remove(techType))
{
removed = true;
InternalLogger.Debug($"Removed {techType.AsString()} from {x.Key}'s DefaultRemovalTechs");
if (x.Value.Count > 0 )
{
removalList.Add(x.Key);
}
}
});

foreach (string key in removalList)
KnownTechPatcher.DefaultRemovalTechs.Remove(key);

if (removed)
InternalLogger.Debug($"Set {techType.AsString()} to Unlock On Start ");
Reinitialize();
}

Expand All @@ -48,7 +69,7 @@ public static void AddRequirementForUnlock(TechType blueprint, TechType requirem
public static void SetHardLocked(TechType techType)
{
KnownTechPatcher.HardLocked.Add(techType);
KnownTechPatcher.UnlockedAtStart.Remove(techType);
RemoveDefaultUnlock(techType);
Reinitialize();
}

Expand Down Expand Up @@ -140,24 +161,25 @@ internal static void RemoveAnalysisSpecific(TechType targetTechType, List<TechTy
{
foreach (TechType techType in techTypes)
{
if (KnownTechPatcher.AnalysisTech.TryGetValue(techType, out var analysisTech) && analysisTech.unlockTechTypes.Remove(targetTechType))
InternalLogger.Debug($"Removed unlock for {targetTechType.AsString()} from {techType} that was added by another mod.");

if (KnownTechPatcher.RemoveFromSpecificTechs.TryGetValue(techType, out HashSet<TechType> types))
{
if (!types.Contains(targetTechType))
{
types.Add(targetTechType);
}
}
types.Add(targetTechType);
else
{
KnownTechPatcher.RemoveFromSpecificTechs[techType] = new HashSet<TechType>() { targetTechType };
}
}

Reinitialize();
}

internal static void RemoveAnalysisTechEntry(TechType targetTechType)
{
if (KnownTechPatcher.AnalysisTech.Remove(targetTechType))
{
InternalLogger.Debug($"Removed Analysis Tech for {targetTechType.AsString()} that was added by another mod!");
}

foreach (KnownTech.AnalysisTech tech in KnownTechPatcher.AnalysisTech.Values)
{
if (tech.unlockTechTypes.Remove(targetTechType))
Expand Down Expand Up @@ -186,6 +208,7 @@ internal static void RemoveAnalysisTechEntry(TechType targetTechType)
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an existing AnalysisTech entry for a TechType, all the TechTypes in "techTypesToUnlock" will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techTypeToBeAnalysed">This TechType is the criteria for all of the "unlock TechTypes"; when this TechType is unlocked, so are all the ones in that list</param>
/// <param name="techTypesToUnlock">The TechTypes that will be unlocked when "techTypeToSet" is unlocked.</param>
Expand All @@ -198,6 +221,7 @@ public static void SetAnalysisTechEntry(TechType techTypeToBeAnalysed, IEnumerab
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an existing AnalysisTech entry for a TechType, all the TechTypes in "techTypesToUnlock" will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techTypeToBeAnalysed">This TechType is the criteria for all of the "unlock TechTypes"; when this TechType is unlocked, so are all the ones in that list</param>
/// <param name="techTypesToUnlock">The TechTypes that will be unlocked when "techTypeToSet" is unlocked.</param>
Expand All @@ -211,6 +235,7 @@ public static void SetAnalysisTechEntry(TechType techTypeToBeAnalysed, IEnumerab
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an existing AnalysisTech entry for a TechType, all the TechTypes in "techTypesToUnlock" will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techTypeToBeAnalysed">This TechType is the criteria for all of the "unlock TechTypes"; when this TechType is unlocked, so are all the ones in that list</param>
/// <param name="techTypesToUnlock">The TechTypes that will be unlocked when "techTypeToSet" is unlocked.</param>
Expand All @@ -224,6 +249,7 @@ public static void SetAnalysisTechEntry(TechType techTypeToBeAnalysed, IEnumerab
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an exisitng AnalysisTech entry for a TechType, all the TechTypes in "techTypesToUnlock" will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techTypeToBeAnalysed">This TechType is the criteria for all of the "unlock TechTypes"; when this TechType is unlocked, so are all the ones in that list</param>
/// <param name="techTypesToUnlock">The TechTypes that will be unlocked when "techTypeToSet" is unlocked.</param>
Expand All @@ -237,6 +263,7 @@ public static void SetAnalysisTechEntry(TechType techTypeToBeAnalysed, IEnumerab
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an existing AnalysisTech entry for a TechType, all the TechTypes in "techTypesToUnlock" will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techTypeToBeAnalysed">This TechType is the criteria for all of the "unlock TechTypes"; when this TechType is unlocked, so are all the ones in that list</param>
/// <param name="techTypesToUnlock">The TechTypes that will be unlocked when "techTypeToSet" is unlocked.</param>
Expand All @@ -251,6 +278,7 @@ public static void SetAnalysisTechEntry(TechType techTypeToBeAnalysed, IEnumerab
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an existing AnalysisTech entry for a TechType, all the TechTypes in "techTypesToUnlock" will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techTypeToBeAnalysed">This TechType is the criteria for all of the "unlock TechTypes"; when this TechType is unlocked, so are all the ones in that list</param>
/// <param name="techTypesToUnlock">The TechTypes that will be unlocked when "techTypeToSet" is unlocked.</param>
Expand All @@ -265,6 +293,7 @@ public static void SetAnalysisTechEntry(TechType techTypeToBeAnalysed, IEnumerab
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an existing AnalysisTech entry for a TechType, all the TechTypes in "techTypesToUnlock" will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techTypeToBeAnalysed">This TechType is the criteria for all of the "unlock TechTypes"; when this TechType is unlocked, so are all the ones in that list</param>
/// <param name="techTypesToUnlock">The TechTypes that will be unlocked when "techTypeToSet" is unlocked.</param>
Expand All @@ -279,6 +308,7 @@ public static void SetAnalysisTechEntry(TechType techTypeToBeAnalysed, IEnumerab
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an existing AnalysisTech entry for a TechType, all the TechTypes in <see cref="KnownTech.AnalysisTech.unlockTechTypes"/> will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="analysisTech">The analysis tech entry to add.</param>
public static void SetAnalysisTechEntry(KnownTech.AnalysisTech analysisTech)
Expand All @@ -290,6 +320,7 @@ public static void SetAnalysisTechEntry(KnownTech.AnalysisTech analysisTech)
/// Allows you to define which TechTypes are unlocked when a certain TechType is unlocked, i.e., "analysed".
/// If there is already an existing AnalysisTech entry for a TechType, all the TechTypes in "techTypesToUnlock" will be
/// added to the existing AnalysisTech entry unlocks.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techTypeToBeAnalysed">This TechType is the criteria for all of the "unlock TechTypes"; when this TechType is unlocked, so are all the ones in that list</param>
/// <param name="techTypesToUnlock">The TechTypes that will be unlocked when "techTypeToSet" is unlocked.</param>
Expand All @@ -303,7 +334,7 @@ public static void SetAnalysisTechEntry(TechType techTypeToBeAnalysed, IEnumerab

/// <summary>
/// Allows you to set up a custom Compound Unlock requiring multiple techtypes to be unlocked before 1 is.
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAnalysisTechEntryFromSpecific"/> or <see cref="RemoveAllCurrentAnalysisTechEntry"/>
/// ***Note: This will not remove any original unlock and if you need to do so you should use <see cref="RemoveAllCurrentAnalysisTechEntry"/> before calling this method.
/// </summary>
/// <param name="techType"></param>
/// <param name="compoundTechsForUnlock"></param>
Expand Down Expand Up @@ -348,6 +379,8 @@ public static void RemoveDefaultUnlock(TechType techType)
techTypes.Add(techType);

KnownTechPatcher.DefaultRemovalTechs[modName] = techTypes;
if (KnownTechPatcher.UnlockedAtStart.Remove(techType))
InternalLogger.Debug($"Removed Default unlock for {techType} that was added by another mod.");
Reinitialize();
}

Expand Down
89 changes: 53 additions & 36 deletions Nautilus/Patchers/KnownTechPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,46 @@ internal static void Reinitialize()

private static void InitializePrefix(PDAData data)
{
foreach (var unlockedTech in UnlockedAtStart)
// This needs to be done first as this list was supposed to be only for game unlocks.
// Mod unlocks requesting removal are already processed in the KnownTechHandler at the time of the request.
// Mods trying to remove other mods unlocks must make sure to run after the original mod has already added them.
foreach (var removalTech in RemovalTechs)
{
if (!data.defaultTech.Contains(unlockedTech))
if (data.compoundTech.RemoveAll((x)=> x.techType == removalTech) > 0)
InternalLogger.Debug($"RemovalTechs: Removed compoundTech for '{removalTech}'");

if (data.analysisTech.RemoveAll((x) => x.techType == removalTech) > 0)
InternalLogger.Debug($"RemovalTechs: Removed analysisTech for '{removalTech}'");

foreach (var analysisTech in data.analysisTech)
{
data.defaultTech.Add(unlockedTech);
InternalLogger.Debug($"Setting {unlockedTech.AsString()} to be unlocked at start.");
if (analysisTech.unlockTechTypes.Remove(removalTech))
{
InternalLogger.Debug($"RemovalTechs: Removed unlockTechType '{removalTech}' from '{analysisTech.techType}' AnalysisTech.");
}
}
}

// Process removals of specific game unlocks as requested by mods.
// Mod unlocks requesting removal are already processed in the KnownTechHandler at the time of the request.
// Mods trying to remove other mods unlocks must make sure to run after the original mod has already added them.
foreach (var analysisTech in data.analysisTech)
{
if (RemoveFromSpecificTechs.TryGetValue(analysisTech.techType, out var techsToRemove))
{
foreach (var removalTech in techsToRemove)
{
if (analysisTech.unlockTechTypes.Remove(removalTech))
{
InternalLogger.Debug($"RemoveFromSpecificTechs: Removed unlockTechType '{removalTech}' from '{analysisTech.techType}' AnalysisTech.");
}
}
}
}

// remove all default unlocks specified by mods.
// Mod unlocks requesting removal are already processed in the KnownTechHandler at the time of the request.
// Mods trying to remove other mods unlocks must make sure to run after the original mod has already added them.
foreach (var removalTechsByMod in DefaultRemovalTechs)
{
foreach (var removalTech in removalTechsByMod.Value)
Expand All @@ -70,12 +101,27 @@ private static void InitializePrefix(PDAData data)
}
}

// Add all default unlocks set by mods.
foreach (var unlockedTech in UnlockedAtStart)
{
if (!data.defaultTech.Contains(unlockedTech))
{
data.defaultTech.Add(unlockedTech);
InternalLogger.Debug($"Setting {unlockedTech.AsString()} to be unlocked at start.");
}
}

// Add or modify analysisTechs as requested by mods.
foreach (var tech in AnalysisTech.Values)
{
var index = data.analysisTech.FindIndex(analysisTech => analysisTech.techType == tech.techType);
if (index == -1)
{
InternalLogger.Debug($"Adding analysisTech for {tech.techType}");

if (tech.unlockSound == null)
tech.unlockSound = KnownTechHandler.DefaultUnlockData.BlueprintUnlockSound;

data.analysisTech.Add(tech);
}
else
Expand All @@ -91,13 +137,10 @@ private static void InitializePrefix(PDAData data)
existingEntry.storyGoals.AddRange(tech.storyGoals);
#endif
}

if (tech.unlockSound == null)
{
tech.unlockSound = KnownTechHandler.DefaultUnlockData.BlueprintUnlockSound;
}
}

// Set unlocks for already existing analysis techs where a AnalysisTech is not created by the mod.
// tbh I don't know why this was added as we used to just make an analysis tech with the data given by the modder if they did not specify one.
foreach (var blueprintRequirements in BlueprintRequirements)
{
var index = data.analysisTech.FindIndex(tech => tech.techType == blueprintRequirements.Key);
Expand All @@ -111,6 +154,7 @@ private static void InitializePrefix(PDAData data)
data.analysisTech[index].unlockTechTypes.AddRange(blueprintRequirements.Value);
}

// Add or Replace CompoundTechs as requested by mods.
foreach (var tech in CompoundTech.Values)
{
var index = data.compoundTech.FindIndex(compoundTech => compoundTech.techType == tech.techType);
Expand All @@ -125,33 +169,6 @@ private static void InitializePrefix(PDAData data)
data.compoundTech[index] = tech;
}
}

foreach (var analysisTech in data.analysisTech)
{
foreach (var removalTech in RemovalTechs)
{
if (analysisTech.techType == removalTech)
{
continue;
}

if (analysisTech.unlockTechTypes.Remove(removalTech))
{
InternalLogger.Debug($"RemovalTechs: Removed unlockTechType '{removalTech}' from '{analysisTech.techType}' AnalysisTech.");
}
}

if (RemoveFromSpecificTechs.TryGetValue(analysisTech.techType, out var techsToRemove))
{
foreach (var removalTech in techsToRemove)
{
if (analysisTech.unlockTechTypes.Remove(removalTech))
{
InternalLogger.Debug($"RemoveFromSpecificTechs: Removed unlockTechType '{removalTech}' from '{analysisTech.techType}' AnalysisTech.");
}
}
}
}
}

private static void GetAllUnlockablesPostfix(HashSet<TechType> __result)
Expand Down
Loading