Skip to content

Commit

Permalink
LostArtefacts#245 TR3 Start Positions
Browse files Browse the repository at this point in the history
Start positions for TR3 implemented. This differs slightly from TR2 as we move any triggers that are below Lara to her new position. Some levels only have a handful of locations because of the trigger types nearby. This also updates the EM move trigger function with some defences such as checking the base and target sectors aren't the same.
  • Loading branch information
lahm86 committed Dec 12, 2021
1 parent c981cdf commit 0db038f
Show file tree
Hide file tree
Showing 5 changed files with 1,297 additions and 19 deletions.
27 changes: 15 additions & 12 deletions TREnvironmentEditor/Model/Types/Triggers/EMMoveTriggerFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,26 @@ public override void ApplyToLevel(TR3Level level)

private bool MoveTriggers(TRRoomSector baseSector, TRRoomSector newSector, FDControl control)
{
if (baseSector.FDIndex != 0)
if (baseSector != newSector && baseSector.FDIndex != 0)
{
if (newSector.FDIndex == 0)
List<FDEntry> triggers = control.Entries[baseSector.FDIndex].FindAll(e => e is FDTriggerEntry);
if (triggers.Count > 0)
{
control.CreateFloorData(newSector);
}
if (newSector.FDIndex == 0)
{
control.CreateFloorData(newSector);
}

List<FDEntry> triggers = control.Entries[baseSector.FDIndex].FindAll(e => e is FDTriggerEntry);
control.Entries[newSector.FDIndex].AddRange(triggers);
control.Entries[newSector.FDIndex].AddRange(triggers);

control.Entries[baseSector.FDIndex].RemoveAll(e => triggers.Contains(e));
if (control.Entries[baseSector.FDIndex].Count == 0)
{
control.RemoveFloorData(baseSector);
}
control.Entries[baseSector.FDIndex].RemoveAll(e => triggers.Contains(e));
if (control.Entries[baseSector.FDIndex].Count == 0)
{
control.RemoveFloorData(baseSector);
}

return true;
return true;
}
}

return false;
Expand Down
20 changes: 19 additions & 1 deletion TRRandomizerCore/Editors/TR3RandoEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ protected override int GetSaveTarget(int numLevels)
target += numLevels * 3;
}

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

// Environment randomizer always runs
target += numLevels;

Expand Down Expand Up @@ -193,6 +198,19 @@ protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMoni
}.Randomize(Settings.EnemySeed);
}

if (!monitor.IsCancelled && Settings.RandomizeStartPosition)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing start positions");
new TR3StartPositionRandomizer
{
ScriptEditor = tr23ScriptEditor,
Levels = levels,
BasePath = wipDirectory,
SaveMonitor = monitor,
Settings = Settings
}.Randomize(Settings.StartPositionSeed);
}

if (!monitor.IsCancelled)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, /*Settings.RandomizeEnvironment ? "Randomizing environment" : */"Applying default environment packs");
Expand Down Expand Up @@ -276,7 +294,7 @@ protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMoni
TextureMonitor = textureMonitor
}.Randomize(Settings.TextureSeed);
}
else if (Settings.RandomizeNightMode)
else if (Settings.RandomizeNightMode && !Settings.RandomizeVfx)
{
monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing night mode textures");
new TR3TextureRandomizer
Expand Down
114 changes: 109 additions & 5 deletions TRRandomizerCore/Randomizers/TR3/TR3StartPositionRandomizer.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,120 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TREnvironmentEditor.Helpers;
using TREnvironmentEditor.Model.Types;
using TRGE.Core;
using TRLevelReader.Model;
using TRLevelReader.Model.Enums;
using TRRandomizerCore.Helpers;
using TRRandomizerCore.Levels;

namespace TRRandomizerCore.Randomizers
{
public class TR3StartPositionRandomizer : BaseTR3Randomizer
{
private static readonly short _rotation = -8192;
private Dictionary<string, List<Location>> _startLocations;

public override void Randomize(int seed)
{
throw new NotImplementedException();
_generator = new Random(seed);
_startLocations = JsonConvert.DeserializeObject<Dictionary<string, List<Location>>>(ReadResource(@"TR3\Locations\start_positions.json"));

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

RandomizeStartPosition(_levelInstance);

SaveLevelInstance();

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

private void RandomizeStartPosition(TR3CombinedLevel level)
{
List<TR2Entity> entities = level.Data.Entities.ToList();
TR2Entity lara = entities.Find(e => e.TypeID == (short)TR3Entities.Lara);

// If we haven't defined anything for a level, Lara will just be rotated. This is most likely where there are
// triggers just after Lara's starting spot, so we just skip them here.
if (!Settings.RotateStartPositionOnly && _startLocations.ContainsKey(level.Name))
{
List<Location> locations = _startLocations[level.Name];
if (Settings.DevelopmentMode)
{
foreach (Location loc in locations)
{
entities.Add(new TR2Entity
{
TypeID = (short)TR3Entities.Lara,
X = loc.X,
Y = loc.Y,
Z = loc.Z,
Room = (short)loc.Room,
Angle = lara.Angle,
Intensity1 = -1,
Intensity2 = -1,
Flags = 0
});
}
}
else
{
Location location;
do
{
location = locations[_generator.Next(0, locations.Count)];
}
while (!location.Validated);

// If there are any triggers below Lara, move them
new EMMoveTriggerFunction
{
BaseLocation = new EMLocation
{
X = lara.X,
Y = lara.Y,
Z = lara.Z,
Room = lara.Room
},
NewLocation = new EMLocation
{
X = location.X,
Y = location.Y,
Z = location.Z,
Room = (short)location.Room
}
}.ApplyToLevel(level.Data);

lara.X = location.X;
lara.Y = location.Y;
lara.Z = location.Z;
lara.Room = (short)location.Room;
lara.Angle = (short)(_generator.Next(0, 8) * _rotation);
}
}
else
{
short currentAngle = lara.Angle;
do
{
lara.Angle = (short)(_generator.Next(0, 8) * _rotation);
}
while (lara.Angle == currentAngle);
}

if (Settings.DevelopmentMode)
{
level.Data.Entities = entities.ToArray();
level.Data.NumEntities = (uint)entities.Count;
}
}
}
}
}
Loading

0 comments on commit 0db038f

Please sign in to comment.