Skip to content

Commit

Permalink
Merge pull request #229 from lahm86/master
Browse files Browse the repository at this point in the history
TR3 Preparations
  • Loading branch information
DanzaG authored Nov 8, 2021
2 parents f4c1c3d + 67ee2fa commit c487fe3
Show file tree
Hide file tree
Showing 11 changed files with 464 additions and 10 deletions.
15 changes: 15 additions & 0 deletions TRRandomizerCore/Editors/TR3RandoEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using TRGE.Coord;
using TRGE.Core;
using TRRandomizerCore.Processors;
using TRRandomizerCore.Randomizers;

namespace TRRandomizerCore.Editors
Expand Down Expand Up @@ -30,6 +31,8 @@ protected override int GetSaveTarget(int numLevels)
// randomizers are implemented, just call Settings.GetSaveTarget(numLevels) per TR2.
int target = base.GetSaveTarget(numLevels);

target += numLevels; // sequence-based processing

if (Settings.RandomizeSecrets)
{
// *3 for multithreaded work
Expand Down Expand Up @@ -73,6 +76,18 @@ protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMoni
scriptEditor.SaveScript();
}

if (!monitor.IsCancelled)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Running level sequence checks");
new TR3SequenceProcessor
{
ScriptEditor = tr23ScriptEditor,
Levels = levels,
BasePath = wipDirectory,
SaveMonitor = monitor
}.Run();
}

if (!monitor.IsCancelled && Settings.RandomizeSecrets)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing secrets");
Expand Down
5 changes: 5 additions & 0 deletions TRRandomizerCore/Levels/TR3CombinedLevel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ public class TR3CombinedLevel
/// </summary>
public bool HasExposureMeter => Sequence == 16 || Sequence == 17;

/// <summary>
/// Whether or not this level is in the sequence of original Willard.
/// </summary>
public bool IsWillardSequence => Sequence == 19;

/// <summary>
/// Whether or not the game will account for secrets collected in this level.
/// </summary>
Expand Down
171 changes: 171 additions & 0 deletions TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using TREnvironmentEditor;
using TREnvironmentEditor.Model;
using TRGE.Core;
using TRLevelReader.Helpers;
using TRLevelReader.Model;
using TRLevelReader.Model.Enums;
using TRModelTransporter.Transport;
using TRRandomizerCore.Helpers;
using TRRandomizerCore.Levels;

namespace TRRandomizerCore.Processors
{
public class TR3SequenceProcessor : TR3LevelProcessor
{
private static readonly int _entityLimit = 256;

private static readonly Dictionary<TR3Entities, TR3Entities> _artefactAssignment = new Dictionary<TR3Entities, TR3Entities>
{
[TR3Entities.Infada_P] = TR3Entities.Key1_P,
[TR3Entities.OraDagger_P] = TR3Entities.Key2_P,
[TR3Entities.EyeOfIsis_P] = TR3Entities.Key3_P,
[TR3Entities.Element115_P] = TR3Entities.Key4_P,
[TR3Entities.Infada_M_H] = TR3Entities.Key1_M_H,
[TR3Entities.OraDagger_M_H] = TR3Entities.Key2_M_H,
[TR3Entities.EyeOfIsis_M_H] = TR3Entities.Key3_M_H,
[TR3Entities.Element115_M_H] = TR3Entities.Key4_M_H,
};

private Dictionary<string, List<Location>> _upvLocations;

public void Run()
{
_upvLocations = JsonConvert.DeserializeObject<Dictionary<string, List<Location>>>(ReadResource(@"TR3\Locations\upv_locations.json"));

foreach (TR3ScriptedLevel lvl in Levels)
{
LoadLevelInstance(lvl);

AdjustLevel(_levelInstance);

SaveLevelInstance();

if (!TriggerProgress())
{
break;
}
}
}

private void AdjustLevel(TR3CombinedLevel level)
{
if (level.HasExposureMeter)
{
if (!level.Is(TR3LevelNames.ANTARC) && !level.Is(TR3LevelNames.RXTECH))
{
// The UPV keeps Lara warm underwater so make this available for
// those levels that have long underwater sections.
ImportUPV(level);
}
}

if (level.Is(TR3LevelNames.WILLIE))
{
if (!level.IsWillardSequence)
{
// Picking-up the artefacts will end the level for all sequences != 19 so
// re-assign the items as keys, which Cavern doesn't use.
AmendWillardBoss(level);
}
}
else if (level.IsWillardSequence)
{
// Because the stones don't end the level on sequence 19, make any required mods
// to make end level triggers.
AmendBossFight(level);
}
}

private void ImportUPV(TR3CombinedLevel level)
{
if (!_upvLocations.ContainsKey(level.Name) || _upvLocations[level.Name].Count == 0)
{
return;
}

TR3ModelImporter importer = new TR3ModelImporter
{
Level = level.Data,
LevelName = level.Name,
EntitiesToImport = new List<TR3Entities> { TR3Entities.UPV },
DataFolder = GetResourcePath(@"TR3\Models")
};

importer.Import();

List<TR2Entity> entities = level.Data.Entities.ToList();
foreach (Location location in _upvLocations[level.Name])
{
if (entities.Count == _entityLimit)
{
break;
}

entities.Add(new TR2Entity
{
TypeID = (short)TR3Entities.UPV,
Room = (short)location.Room,
X = location.X,
Y = location.Y,
Z = location.Z,
Angle = location.Angle,
Flags = 0,
Intensity1 = -1,
Intensity2 = -1
});
}

level.Data.Entities = entities.ToArray();
level.Data.NumEntities = (uint)entities.Count;
}

private void AmendWillardBoss(TR3CombinedLevel level)
{
List<TR2Entity> entities = level.Data.Entities.ToList();
List<TRModel> models = level.Data.Models.ToList();

// Add new duplicate models for keys, so secret rando doesn't replace the originals.
foreach (TR3Entities artefact in _artefactAssignment.Keys)
{
TR3Entities replacement = _artefactAssignment[artefact];
TRModel artefactModel = models.Find(m => m.ID == (uint)artefact);
models.Add(new TRModel
{
Animation = artefactModel.Animation,
FrameOffset = artefactModel.FrameOffset,
ID = (uint)replacement,
MeshTree = artefactModel.MeshTree,
NumMeshes = artefactModel.NumMeshes,
StartingMesh = artefactModel.StartingMesh
});

entities.FindAll(e => e.TypeID == (short)artefact).ForEach(e => e.TypeID = (short)replacement);
}

// Copy the artefact names into the keys
for (int i = 0; i < 4; i++)
{
level.Script.Keys[i] = ScriptEditor.Script.GameStrings1[80 + i];
}

level.Data.Models = models.ToArray();
level.Data.NumModels = (uint)models.Count;

// Apply any changes needed for the boss fight
AmendBossFight(level);
}

private void AmendBossFight(TR3CombinedLevel level)
{
string mappingPath = @"TR3\BossMapping\" + level.Name + "-BossMapping.json";
if (ResourceExists(mappingPath))
{
EMEditorSet mods = JsonConvert.DeserializeObject<EMEditorSet>(ReadResource(mappingPath), EMEditorMapping.Converter);
mods.ApplyToLevel(level.Data);
}
}
}
}
18 changes: 9 additions & 9 deletions TRRandomizerCore/Resources/TR2/Locations/item_locations.json
Original file line number Diff line number Diff line change
Expand Up @@ -113853,10 +113853,10 @@
"IsItem": true
},
{
"X": 69127,
"Z": 56817,
"X": 64000,
"Z": 55808,
"Y": 0,
"Room": 70,
"Room": 69,
"RequiresGlitch": false,
"Difficulty": 0,
"IsInRoomSpace": false,
Expand All @@ -113873,10 +113873,10 @@
"IsItem": true
},
{
"X": 69102,
"Z": 58886,
"X": 60928,
"Z": 54784,
"Y": 0,
"Room": 70,
"Room": 69,
"RequiresGlitch": false,
"Difficulty": 0,
"IsInRoomSpace": false,
Expand All @@ -113893,10 +113893,10 @@
"IsItem": true
},
{
"X": 69093,
"Z": 60909,
"X": 69120,
"Z": 54784,
"Y": 0,
"Room": 70,
"Room": 69,
"RequiresGlitch": false,
"Difficulty": 0,
"IsInRoomSpace": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[
{
"Comments": "Get rid of the MP trigger under the artefact.",
"EMType": 62,
"Locations": [
{
"X": 44544,
"Y": -7424,
"Z": 35328,
"Room": 18
}
]
},

{
"Comments": "Add a trigger under the artefact so that picking it up will end the level.",
"EMType": 61,
"TriggerEntry": {
"Setup": {
"Value": 4
},
"TrigSetup": {
"Value": 15872
},
"TrigType": 4,
"TrigActionList": [
{
"TrigAction": 0,
"Parameter": 44
},
{
"TrigAction": 7
}
]
},
"Locations": [
{
"X": 44544,
"Y": -7424,
"Z": 35328,
"Room": 18
}
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"Comments": "Convert Willie into a gun enemy.",
"EMType": 45,
"EntityIndex": 22,
"NewEntityType": 40
},

{
"Comments": "Create another couple of enemies.",
"EMType": 45,
"EntityIndex": 16,
"NewEntityType": 40
},

{
"EMType": 45,
"EntityIndex": 18,
"NewEntityType": 40
},

{
"Comments": "Amend the trigger under Lara to activate the new enemies.",
"EMType": 68,
"Location": {
"X": 61952,
"Y": -512,
"Z": 62976,
"Room": 5
},
"ActionItems": [
{
"TrigAction": 0,
"Parameter": 16
},
{
"TrigAction": 0,
"Parameter": 18
}
]
}
]
Loading

0 comments on commit c487fe3

Please sign in to comment.