Skip to content

Commit

Permalink
Add secret rando support
Browse files Browse the repository at this point in the history
Reward rooms created and reward items earmarked.
Locations marked for each TRUB level.
Added a method of pinpointing entity indices from environment mods, which we use to adjust some secrets after they have been placed.
  • Loading branch information
lahm86 committed Dec 1, 2023
1 parent 390bef4 commit eb7cafe
Show file tree
Hide file tree
Showing 15 changed files with 2,704 additions and 5 deletions.
115 changes: 115 additions & 0 deletions TREnvironmentEditor/Helpers/EMEntityFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using TRFDControl;
using TRFDControl.Utilities;
using TRLevelControl.Helpers;
using TRLevelControl.Model;

namespace TREnvironmentEditor.Helpers;

public class EMEntityFinder
{
public EMLocation Location { get; set; }
public EMEntityType Type { get; set; }
public List<short> Types { get; set; }

public int GetEntity(TR1Level level)
{
FDControl floorData = new();
floorData.ParseFromLevel(level);

EMLevelData data = EMLevelData.GetData(level);

List<TR1Type> types = new();
if (Type == EMEntityType.Item)
{
types.AddRange(TR1TypeUtilities.GetStandardPickupTypes());
}
else if (Type == EMEntityType.KeyItem)
{
types.AddRange(TR1TypeUtilities.GetKeyItemTypes());
}
if (Types != null)
{
types.AddRange(Types.Select(t => (TR1Type)t));
}

return GetEntity(level.Entities, types, data,
l => FDUtilities.GetRoomSector(l.X, l.Y, l.Z, l.Room, level, floorData));
}

public int GetEntity(TR2Level level)
{
FDControl floorData = new();
floorData.ParseFromLevel(level);

EMLevelData data = EMLevelData.GetData(level);

List<TR2Type> types = new();
if (Type == EMEntityType.Item)
{
types.AddRange(TR2TypeUtilities.GetStandardPickupTypes());
}
else if (Type == EMEntityType.KeyItem)
{
types.AddRange(TR2TypeUtilities.GetKeyItemTypes());
}
if (Types != null)
{
types.AddRange(Types.Select(t => (TR2Type)t));
}

return GetEntity(level.Entities, types, data,
l => FDUtilities.GetRoomSector(l.X, l.Y, l.Z, l.Room, level, floorData));
}

public int GetEntity(TR3Level level)
{
FDControl floorData = new();
floorData.ParseFromLevel(level);

EMLevelData data = EMLevelData.GetData(level);

List<TR3Type> types = new();
if (Type == EMEntityType.Item)
{
types.AddRange(TR3TypeUtilities.GetStandardPickupTypes());
}
else if (Type == EMEntityType.KeyItem)
{
types.AddRange(TR3TypeUtilities.GetKeyItemTypes());
}
if (Types != null)
{
types.AddRange(Types.Select(t => (TR3Type)t));
}

return GetEntity(level.Entities, types, data,
l => FDUtilities.GetRoomSector(l.X, l.Y, l.Z, l.Room, level, floorData));
}

public int GetEntity<E, T>(List<E> entities, List<T> types, EMLevelData data, Func<EMLocation, TRRoomSector> sectorFunc)
where E : TREntity<T>
where T : Enum
{
EMLocation location = new()
{
X = Location.X,
Y = Location.Y,
Z = Location.Z,
Room = data.ConvertRoom(Location.Room)
};

TRRoomSector sector = sectorFunc(location);
for (int i = 0; i < entities.Count; i++)
{
E entity = entities[i];
if (types.Contains(entity.TypeID)
&& entity.Room == location.Room
&& sectorFunc(new() { X = entity.X, Y = entity.Y, Z = entity.Z, Room = entity.Room }) == sector)
{
return i;
}
}

return -1;
}
}
8 changes: 8 additions & 0 deletions TREnvironmentEditor/Helpers/EMEntityType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace TREnvironmentEditor.Helpers;

public enum EMEntityType
{
Any,
Item,
KeyItem,
}
1 change: 1 addition & 0 deletions TREnvironmentEditor/Model/EMType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public enum EMType
RemoveTriggerAction = 71,
RemoveEntityTriggers = 72,
MergeTriggers = 73,
ResetPickupTrigger = 74,

// Portal types 81-100
VisibilityPortal = 81,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace TREnvironmentEditor.Model.Types;
public class EMModifyEntityFunction : BaseEMFunction
{
public int EntityIndex { get; set; }
public EMEntityFinder EntityFinder { get; set; }
public bool? Invisible { get; set; }
public bool? ClearBody { get; set; }
public short? Intensity1 { get; set; }
Expand All @@ -15,19 +16,22 @@ public class EMModifyEntityFunction : BaseEMFunction
public override void ApplyToLevel(TR1Level level)
{
EMLevelData data = GetData(level);
ModifyEntity(level.Entities[data.ConvertEntity(EntityIndex)]);
int entityIndex = EntityFinder?.GetEntity(level) ?? EntityIndex;
ModifyEntity(level.Entities[data.ConvertEntity(entityIndex)]);
}

public override void ApplyToLevel(TR2Level level)
{
EMLevelData data = GetData(level);
ModifyEntity(level.Entities[data.ConvertEntity(EntityIndex)]);
int entityIndex = EntityFinder?.GetEntity(level) ?? EntityIndex;
ModifyEntity(level.Entities[data.ConvertEntity(entityIndex)]);
}

public override void ApplyToLevel(TR3Level level)
{
EMLevelData data = GetData(level);
ModifyEntity(level.Entities[data.ConvertEntity(EntityIndex)]);
int entityIndex = EntityFinder?.GetEntity(level) ?? EntityIndex;
ModifyEntity(level.Entities[data.ConvertEntity(entityIndex)]);
}

private void ModifyEntity(TR1Entity entity)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using TREnvironmentEditor.Helpers;
using TRFDControl;
using TRFDControl.FDEntryTypes;
using TRFDControl.Utilities;
using TRLevelControl.Model;

namespace TREnvironmentEditor.Model.Types;

public class EMResetPickupTriggerFunction : BaseEMFunction
{
public List<EMLocation> Locations { get; set; }

public override void ApplyToLevel(TR1Level level)
{
EMLevelData data = GetData(level);

FDControl floorData = new();
floorData.ParseFromLevel(level);

ResetPickupTriggers(floorData, l => FDUtilities.GetRoomSector(l.X, l.Y, l.Z, data.ConvertRoom(l.Room), level, floorData));

floorData.WriteToLevel(level);
}

public override void ApplyToLevel(TR2Level level)
{
EMLevelData data = GetData(level);

FDControl floorData = new();
floorData.ParseFromLevel(level);

ResetPickupTriggers(floorData, l => FDUtilities.GetRoomSector(l.X, l.Y, l.Z, data.ConvertRoom(l.Room), level, floorData));

floorData.WriteToLevel(level);
}

public override void ApplyToLevel(TR3Level level)
{
EMLevelData data = GetData(level);

FDControl floorData = new();
floorData.ParseFromLevel(level);

ResetPickupTriggers(floorData, l => FDUtilities.GetRoomSector(l.X, l.Y, l.Z, data.ConvertRoom(l.Room), level, floorData));

floorData.WriteToLevel(level);
}

private void ResetPickupTriggers(FDControl floorData, Func<EMLocation, TRRoomSector> sectorFunc)
{
foreach (EMLocation location in Locations)
{
TRRoomSector sector = sectorFunc(location);
if (sector.FDIndex == 0)
{
continue;
}

FDEntry entry = floorData.Entries[sector.FDIndex].Find(e => e is FDTriggerEntry);
if (entry is FDTriggerEntry trigger
&& trigger.TrigType == FDTrigType.Pickup
&& trigger.TrigActionList.Count > 1)
{
trigger.TrigActionList.RemoveRange(1, trigger.TrigActionList.Count - 1);
}
}
}
}
1 change: 1 addition & 0 deletions TREnvironmentEditor/Parsing/EMConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ private object ReadEMType(JObject jo)
EMType.RemoveTriggerAction => JsonConvert.DeserializeObject<EMRemoveTriggerActionFunction>(jo.ToString(), this),
EMType.RemoveEntityTriggers => JsonConvert.DeserializeObject<EMRemoveEntityTriggersFunction>(jo.ToString(), this),
EMType.MergeTriggers => JsonConvert.DeserializeObject<EMMergeTriggersFunction>(jo.ToString(), this),
EMType.ResetPickupTrigger => JsonConvert.DeserializeObject<EMResetPickupTriggerFunction>(jo.ToString(), this),

// Portals
EMType.VisibilityPortal => JsonConvert.DeserializeObject<EMVisibilityPortalFunction>(jo.ToString(), this),
Expand Down
10 changes: 9 additions & 1 deletion TRLevelControl/Helpers/TR1TypeUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,14 @@ public static TR1Type GetBestLevelSecretModel(string lvl)
[TR1LevelNames.ATLANTIS]
= TR1Type.SecretGoldIdol_M_H,
[TR1LevelNames.PYRAMID]
= TR1Type.SecretGoldIdol_M_H
= TR1Type.SecretGoldIdol_M_H,
[TR1LevelNames.EGYPT]
= TR1Type.SecretLeadBar_M_H,
[TR1LevelNames.CAT]
= TR1Type.SecretLeadBar_M_H,
[TR1LevelNames.STRONGHOLD]
= TR1Type.SecretGoldBar_M_H,
[TR1LevelNames.HIVE]
= TR1Type.SecretGoldIdol_M_H,
};
}
3 changes: 2 additions & 1 deletion TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,8 @@ private void CreateSecretTrigger(TR1CombinedLevel level, TRSecretPlacement<TR1Ty
existingActions.Add(actionItem);
}
}
else
else if (!Settings.UseRewardRoomCameras
|| (actionItem.TrigAction != FDTrigAction.Camera && actionItem.TrigAction != FDTrigAction.LookAtItem))
{
existingActions.Add(actionItem);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5987,6 +5987,59 @@
}
}
]
},
{
"Condition": {
"Comments": "If a particular secret is present, hide it until the level is flipped.",
"ConditionType": 22,
"Location": {
"X": 73216,
"Y": 4608,
"Z": 69120,
"Room": 38
}
},
"OnTrue": [
{
"EMType": 48,
"EntityFinder": {
"Location": {
"X": 73216,
"Y": 4608,
"Z": 69120,
"Room": 38
},
"Type": 2
},
"Invisible": true
},
{
"EMType": 74,
"Locations": [
{
"X": 73216,
"Y": 4608,
"Z": 69120,
"Room": 38
}
]
},
{
"EMType": 73,
"BaseLocation": {
"X": 72772,
"Y": 4608,
"Z": 68738,
"Room": 38
},
"TargetLocation": {
"X": 73216,
"Y": 3584,
"Z": 61952,
"Room": 5
}
}
]
}
],
"ConditionalOneOf": [],
Expand Down
Loading

0 comments on commit eb7cafe

Please sign in to comment.