Skip to content

Commit

Permalink
Add TRR secret support (LostArtefacts#681)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahm86 authored May 21, 2024
1 parent 790e3a6 commit fb263cc
Show file tree
Hide file tree
Showing 32 changed files with 1,835 additions and 799 deletions.
Binary file modified Deps/TRGE.Coord.dll
Binary file not shown.
Binary file modified Deps/TRGE.Core.dll
Binary file not shown.
67 changes: 67 additions & 0 deletions TRDataControl/Data/Remastered/BaseTRRDataCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using TRLevelControl;
using TRLevelControl.Model;

namespace TRDataControl;

public abstract class BaseTRRDataCache<TKey, TAlias>
where TKey : Enum
where TAlias : Enum
{
private const string _pdpExt = ".PDP";

private readonly Dictionary<TKey, TRModel> _pdpCache = new();

public string PDPFolder { get; set; }

public void SetData(TRDictionary<TKey, TRModel> pdpData, Dictionary<TKey, TAlias> mapData, TKey sourceType, TKey destinationType = default)
{
if (EqualityComparer<TKey>.Default.Equals(destinationType, default))
{
destinationType = sourceType;
}

SetPDPData(pdpData, sourceType, destinationType);
SetMapData(mapData, sourceType, destinationType);
}

public void SetPDPData(TRDictionary<TKey, TRModel> pdpData, TKey sourceType, TKey destinationType)
{
TKey translatedKey = TranslateKey(sourceType);
if (!_pdpCache.ContainsKey(sourceType))
{
string sourceLevel = GetSourceLevel(sourceType)
?? throw new KeyNotFoundException($"Source PDP file for {sourceType} is undefined");

TRPDPControlBase<TKey> control = GetPDPControl();
TRDictionary<TKey, TRModel> models = control.Read(Path.Combine(PDPFolder, Path.GetFileNameWithoutExtension(sourceLevel) + _pdpExt));
if (models.ContainsKey(translatedKey))
{
_pdpCache[sourceType] = models[translatedKey];
}
else
{
throw new KeyNotFoundException($"Could not load cached PDP data for {sourceType}");
}
}

translatedKey = TranslateKey(destinationType);
pdpData[translatedKey] = _pdpCache[sourceType];
}

public void SetMapData(Dictionary<TKey, TAlias> mapData, TKey sourceType, TKey destinationType)
{
TAlias alias = GetAlias(sourceType);
if (EqualityComparer<TAlias>.Default.Equals(alias, default))
{
return;
}

TKey translatedKey = TranslateKey(destinationType);
mapData[translatedKey] = alias;
}

protected abstract TRPDPControlBase<TKey> GetPDPControl();
public abstract string GetSourceLevel(TKey key);
public abstract TKey TranslateKey(TKey key);
public abstract TAlias GetAlias(TKey key);
}
49 changes: 49 additions & 0 deletions TRDataControl/Data/Remastered/TR1RDataCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using TRLevelControl;
using TRLevelControl.Helpers;
using TRLevelControl.Model;

namespace TRDataControl;

public class TR1RDataCache : BaseTRRDataCache<TR1Type, TR1RAlias>
{
private TR1PDPControl _control;
private TR1DataProvider _dataProvider;

protected override TRPDPControlBase<TR1Type> GetPDPControl()
=> _control ??= new();

public override TR1Type TranslateKey(TR1Type key)
=> TR1TypeUtilities.TranslateSourceType(key);

public override string GetSourceLevel(TR1Type key)
{
_dataProvider ??= new();
TR1Type translatedType = _dataProvider.TranslateAlias(key);
return _sourceLevels.ContainsKey(translatedType) ? _sourceLevels[translatedType] : null;
}

public override TR1RAlias GetAlias(TR1Type key)
{
_dataProvider ??= new();
TR1Type translatedType = _dataProvider.TranslateAlias(key);
return _mapAliases.ContainsKey(translatedType) ? _mapAliases[translatedType] : default;
}

private static readonly Dictionary<TR1Type, string> _sourceLevels = new()
{
[TR1Type.SecretAnkh_M_H] = TR1LevelNames.OBELISK,
[TR1Type.SecretGoldBar_M_H] = TR1LevelNames.MIDAS,
[TR1Type.SecretGoldIdol_M_H] = TR1LevelNames.VILCABAMBA,
[TR1Type.SecretLeadBar_M_H] = TR1LevelNames.MIDAS,
[TR1Type.SecretScion_M_H] = TR1LevelNames.QUALOPEC,
};

private static readonly Dictionary<TR1Type, TR1RAlias> _mapAliases = new()
{
[TR1Type.SecretAnkh_M_H] = TR1RAlias.PUZZLE_OPTION4_8A_8B,
[TR1Type.SecretGoldBar_M_H] = TR1RAlias.PUZZLE_OPTION1_6,
[TR1Type.SecretGoldIdol_M_H] = TR1RAlias.PUZZLE_OPTION1_2,
[TR1Type.SecretLeadBar_M_H] = TR1RAlias.LEADBAR_OPTION,
[TR1Type.SecretScion_M_H] = TR1RAlias.SCION_OPTION,
};
}
70 changes: 70 additions & 0 deletions TRDataControl/Data/Remastered/TR3RDataCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using TRLevelControl;
using TRLevelControl.Helpers;
using TRLevelControl.Model;

namespace TRDataControl;

public class TR3RDataCache : BaseTRRDataCache<TR3Type, TR3RAlias>
{
private TR3PDPControl _control;
private TR3DataProvider _dataProvider;

protected override TRPDPControlBase<TR3Type> GetPDPControl()
=> _control ??= new();

public override TR3Type TranslateKey(TR3Type key)
{
return key switch
{
TR3Type.Quest1_P or TR3Type.Quest2_P => TR3Type.Puzzle1_P,
TR3Type.Quest1_M_H or TR3Type.Quest2_M_H => TR3Type.Puzzle1_M_H,
_ => key,
};
}

public override string GetSourceLevel(TR3Type key)
{
_dataProvider ??= new();
TR3Type translatedType = _dataProvider.TranslateAlias(key);
return _sourceLevels.ContainsKey(translatedType) ? _sourceLevels[translatedType] : null;
}

public override TR3RAlias GetAlias(TR3Type key)
{
_dataProvider ??= new();
TR3Type translatedType = _dataProvider.TranslateAlias(key);
return _mapAliases.ContainsKey(translatedType) ? _mapAliases[translatedType] : default;
}

private static readonly Dictionary<TR3Type, string> _sourceLevels = new()
{
[TR3Type.Infada_P] = TR3LevelNames.CAVES,
[TR3Type.Infada_M_H] = TR3LevelNames.CAVES,
[TR3Type.OraDagger_P] = TR3LevelNames.PUNA,
[TR3Type.OraDagger_M_H] = TR3LevelNames.PUNA,
[TR3Type.EyeOfIsis_P] = TR3LevelNames.CITY,
[TR3Type.EyeOfIsis_M_H] = TR3LevelNames.CITY,
[TR3Type.Element115_P] = TR3LevelNames.AREA51,
[TR3Type.Element115_M_H] = TR3LevelNames.AREA51,
[TR3Type.Quest1_P] = TR3LevelNames.COASTAL,
[TR3Type.Quest1_M_H] = TR3LevelNames.COASTAL,
[TR3Type.Quest2_P] = TR3LevelNames.MADHOUSE,
[TR3Type.Quest2_M_H] = TR3LevelNames.MADHOUSE,
};

private static readonly Dictionary<TR3Type, TR3RAlias> _mapAliases = new()
{
[TR3Type.Infada_P] = TR3RAlias.ICON_PICKUP1_ITEM,
[TR3Type.Infada_M_H] = TR3RAlias.ICON_PICKUP1_OPTION,
[TR3Type.OraDagger_P] = TR3RAlias.ICON_PICKUP4_ITEM,
[TR3Type.OraDagger_M_H] = TR3RAlias.ICON_PICKUP4_OPTION,
[TR3Type.EyeOfIsis_P] = TR3RAlias.ICON_PICKUP3_ITEM,
[TR3Type.EyeOfIsis_M_H] = TR3RAlias.ICON_PICKUP3_OPTION,
[TR3Type.Element115_P] = TR3RAlias.ICON_PICKUP2_ITEM,
[TR3Type.Element115_M_H] = TR3RAlias.ICON_PICKUP2_OPTION,
[TR3Type.Quest1_P] = TR3RAlias.PUZZLE_ITEM1_SHORE,
[TR3Type.Quest1_M_H] = TR3RAlias.PUZZLE_OPTION1_SHORE,
[TR3Type.Quest2_P] = TR3RAlias.PUZZLE_ITEM1_HAND,
[TR3Type.Quest2_M_H] = TR3RAlias.PUZZLE_OPTION1_HAND,
};
}
12 changes: 12 additions & 0 deletions TRLevelControl/Helpers/TR1TypeUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,18 @@ public static Dictionary<TR1Type, TR1Type> GetSecretModels()
};
}

public static TR1Type TranslateSourceType(TR1Type type)
{
return type switch
{
TR1Type.SecretAnkh_M_H => TR1Type.Puzzle4_M_H,
TR1Type.SecretGoldBar_M_H or TR1Type.SecretGoldIdol_M_H => TR1Type.Puzzle1_M_H,
TR1Type.SecretLeadBar_M_H => TR1Type.LeadBar_M_H,
TR1Type.SecretScion_M_H => TR1Type.ScionPiece_M_H,
_ => type,
};
}

public static Dictionary<TR1Type, TR1Type> GetSecretReplacements()
{
// Note Key1 is omitted because of Pierre
Expand Down
2 changes: 2 additions & 0 deletions TRLevelControl/Model/TR1/Enums/TR1RAlias.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public enum TR1RAlias
KEY_OPTION4_4,
LARSON_EGYPT,
LAVA_WEDGE_10B_10C,
LEADBAR_OPTION,
LIGHTNING_EMITTER_10C,
LIGHTNING_EMITTER_4,
MOVABLE_BLOCK_10A,
Expand Down Expand Up @@ -141,6 +142,7 @@ public enum TR1RAlias
ROLLING_BALL_5,
ROLLING_BALL_8A,
SCION_HOLDER,
SCION_OPTION,
SWITCH_TYPE1_10A,
SWITCH_TYPE1_10B_10C,
SWITCH_TYPE1_4_7A_7B,
Expand Down
8 changes: 8 additions & 0 deletions TRLevelControl/Model/TR3/Enums/TR3RAlias.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ public enum TR3RAlias
FIREHEAD_SCOTLAND,
FISH_CUT11,
ICICLES_RAPIDS,
ICON_PICKUP1_ITEM,
ICON_PICKUP2_ITEM,
ICON_PICKUP3_ITEM,
ICON_PICKUP4_ITEM,
ICON_PICKUP1_OPTION,
ICON_PICKUP2_OPTION,
ICON_PICKUP3_OPTION,
ICON_PICKUP4_OPTION,
ICON_PICKUP1_ITEM_HAND,
ICON_PICKUP1_OPTION_HAND,
KEY_HOLE_CRASH,
Expand Down
49 changes: 48 additions & 1 deletion TRRandomizerCore/Editors/TR1RemasteredEditor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using TRGE.Core;
using TRDataControl;
using TRGE.Core;
using TRLevelControl.Model;
using TRRandomizerCore.Helpers;
using TRRandomizerCore.Randomizers;
Expand All @@ -22,6 +23,11 @@ protected override int GetSaveTarget(int numLevels)
{
int target = 0;

if (Settings.RandomizeSecrets)
{
target += numLevels * 3;
}

if (Settings.RandomizeItems)
{
target += numLevels;
Expand All @@ -31,6 +37,11 @@ protected override int GetSaveTarget(int numLevels)
}
}

if (Settings.RandomizeSecretRewardsPhysical)
{
target += numLevels;
}

if (Settings.RandomizeStartPosition)
{
target += numLevels;
Expand Down Expand Up @@ -61,6 +72,11 @@ protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMoni
string backupDirectory = _io.BackupDirectory.FullName;
string wipDirectory = _io.WIPOutputDirectory.FullName;

TR1RDataCache dataCache = new()
{
PDPFolder = backupDirectory,
};

ItemFactory<TR1Entity> itemFactory = new(@"Resources\TR1\Items\repurposable_items.json");
TR1RItemRandomizer itemRandomizer = new()
{
Expand All @@ -83,12 +99,43 @@ protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMoni
Settings = Settings,
};

if (!monitor.IsCancelled && Settings.RandomizeSecrets)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing secrets");
new TR1RSecretRandomizer
{
ScriptEditor = scriptEditor,
Levels = levels,
BasePath = wipDirectory,
BackupPath = backupDirectory,
SaveMonitor = monitor,
Settings = Settings,
ItemFactory = itemFactory,
DataCache = dataCache,
}.Randomize(Settings.SecretSeed);
}

if (!monitor.IsCancelled && Settings.RandomizeItems)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing standard items");
itemRandomizer.Randomize(Settings.ItemSeed);
}

if (!monitor.IsCancelled && Settings.RandomizeSecretRewardsPhysical)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing secret rewards");
new TR1RSecretRewardRandomizer
{
ScriptEditor = scriptEditor,
Levels = levels,
BasePath = wipDirectory,
BackupPath = backupDirectory,
SaveMonitor = monitor,
Settings = Settings,
ItemFactory = itemFactory,
}.Randomize(Settings.SecretRewardsPhysicalSeed);
}

if (!monitor.IsCancelled && Settings.RandomizeStartPosition)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing start positions");
Expand Down
20 changes: 20 additions & 0 deletions TRRandomizerCore/Editors/TR2RemasteredEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ protected override int GetSaveTarget(int numLevels)
{
int target = 0;

if (Settings.RandomizeSecrets)
{
target += numLevels;
}

if (Settings.RandomizeItems)
{
target += numLevels;
Expand Down Expand Up @@ -86,6 +91,21 @@ protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMoni
Settings = Settings,
};

if (!monitor.IsCancelled && Settings.RandomizeSecrets)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing secrets");
new TR2RSecretRandomizer
{
ScriptEditor = scriptEditor,
Levels = levels,
BasePath = wipDirectory,
BackupPath = backupDirectory,
SaveMonitor = monitor,
Settings = Settings,
ItemFactory = itemFactory,
}.Randomize(Settings.SecretSeed);
}

if (!monitor.IsCancelled && Settings.RandomizeItems)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing standard items");
Expand Down
Loading

0 comments on commit fb263cc

Please sign in to comment.