Skip to content

Commit

Permalink
Add option to hide dead T-rexes (#709)
Browse files Browse the repository at this point in the history
Resolves #708.
  • Loading branch information
lahm86 authored Jun 19, 2024
1 parent d47b78c commit 1c1658a
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 7 deletions.
3 changes: 3 additions & 0 deletions TRRandomizerCore/Editors/RandomizerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public class RandomizerSettings
public bool ProtectMonks { get; set; }
public bool DocileWillard { get; set; }
public bool RelocateAwkwardEnemies { get; set; }
public bool HideDeadTrexes { get; set; }
public BirdMonsterBehaviour BirdMonsterBehaviour { get; set; }
public bool DefaultChickens => BirdMonsterBehaviour == BirdMonsterBehaviour.Default;
public bool DocileChickens => BirdMonsterBehaviour == BirdMonsterBehaviour.Docile;
Expand Down Expand Up @@ -233,6 +234,7 @@ public void ApplyConfig(Config config)
ProtectMonks = config.GetBool(nameof(ProtectMonks), true);
DocileWillard = config.GetBool(nameof(DocileWillard));
RelocateAwkwardEnemies = config.GetBool(nameof(RelocateAwkwardEnemies), true);
HideDeadTrexes = config.GetBool(nameof(HideDeadTrexes), true);
BirdMonsterBehaviour = (BirdMonsterBehaviour)config.GetEnum(nameof(BirdMonsterBehaviour), typeof(BirdMonsterBehaviour), BirdMonsterBehaviour.Default);
RandoEnemyDifficulty = (RandoDifficulty)config.GetEnum(nameof(RandoEnemyDifficulty), typeof(RandoDifficulty), RandoDifficulty.Default);
DragonSpawnType = (DragonSpawnType)config.GetEnum(nameof(DragonSpawnType), typeof(DragonSpawnType), DragonSpawnType.Default);
Expand Down Expand Up @@ -407,6 +409,7 @@ public void StoreConfig(Config config)
config[nameof(ProtectMonks)] = ProtectMonks;
config[nameof(DocileWillard)] = DocileWillard;
config[nameof(RelocateAwkwardEnemies)] = RelocateAwkwardEnemies;
config[nameof(HideDeadTrexes)] = HideDeadTrexes;
config[nameof(BirdMonsterBehaviour)] = BirdMonsterBehaviour;
config[nameof(RandoEnemyDifficulty)] = RandoEnemyDifficulty;
config[nameof(DragonSpawnType)] = DragonSpawnType;
Expand Down
40 changes: 40 additions & 0 deletions TRRandomizerCore/Randomizers/TR1/Remastered/TR1REnemyRandomizer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using TRDataControl;
using TRGE.Core;
using TRLevelControl;
using TRLevelControl.Helpers;
using TRLevelControl.Model;
using TRRandomizerCore.Helpers;
Expand All @@ -12,6 +13,7 @@ namespace TRRandomizerCore.Randomizers;
public class TR1REnemyRandomizer : BaseTR1RRandomizer
{
private static readonly List<int> _tihocanEndEnemies = new() { 73, 74, 82 };
private const int _trexDeathAnimation = 10;

private TR1EnemyAllocator _allocator;

Expand Down Expand Up @@ -111,7 +113,9 @@ private void RandomizeEnemies(TR1RCombinedLevel level, EnemyRandomizationCollect
private void ApplyPostRandomization(TR1RCombinedLevel level, EnemyRandomizationCollection<TR1Type> enemies)
{
UpdateAtlanteanPDP(level, enemies);
HideTrexDeath(level);
AdjustTihocanEnding(level);
AdjustScionEnding(level);
AddUnarmedLevelAmmo(level);
}

Expand All @@ -126,6 +130,31 @@ private void UpdateAtlanteanPDP(TR1RCombinedLevel level, EnemyRandomizationColle
DataCache.SetPDPData(level.PDPData, TR1Type.ShootingAtlantean_N, TR1Type.ShootingAtlantean_N);
}

private void HideTrexDeath(TR1RCombinedLevel level)
{
if (!Settings.HideDeadTrexes || !level.Data.Models.ContainsKey(TR1Type.TRex))
{
return;
}

// Push T-rexes down on death, which ultimately disables their collision. Shift the final frame
// to the absolute maximum so it's not visible.
TRSetPositionCommand cmd = new()
{
Y = (short)level.Data.Rooms.Max(r => Math.Abs(r.Info.YBottom - r.Info.YTop)),
};

void UpdateModel(TRModel model)
{
TRAnimation deathAnimation = model.Animations[_trexDeathAnimation];
deathAnimation.Commands.Add(cmd);
deathAnimation.Frames[^1].OffsetY = short.MaxValue;
}

UpdateModel(level.Data.Models[TR1Type.TRex]);
UpdateModel(level.PDPData[TR1Type.TRex]);
}

private void AdjustTihocanEnding(TR1RCombinedLevel level)
{
if (!level.Is(TR1LevelNames.TIHOCAN)
Expand All @@ -139,6 +168,17 @@ private void AdjustTihocanEnding(TR1RCombinedLevel level)
level.Data.Entities.AddRange(TR1ItemAllocator.TihocanEndItems);
}

private static void AdjustScionEnding(TR1RCombinedLevel level)
{
if (level.Data.Models.ContainsKey(TR1Type.ScionPiece4_S_P)
&& (level.Data.Models.ContainsKey(TR1Type.TRex) || level.Data.Models.ContainsKey(TR1Type.Adam)))
{
// Ensure the scion is shootable in Atlantis. This is handled in OG with an environment condition,
// but support for PDP isn't there yet.
level.PDPData.ChangeKey(TR1Type.ScionPiece4_S_P, TR1Type.ScionPiece3_S_P);
}
}

private void AddUnarmedLevelAmmo(TR1RCombinedLevel level)
{
if (!level.Script.RemovesWeapons)
Expand Down
36 changes: 31 additions & 5 deletions TRRandomizerCore/Resources/TR1/Locations/enemy_relocations.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,39 @@
"TargetType": 18
}
],
"LEVEL6.PHD": [
{
"X": 36352,
"Y": -4352,
"Z": 37376,
"Room": 27,
"EntityIndex": 67,
"TargetType": 18
},
{
"X": 81408,
"Y": -4096,
"Z": 39424,
"Room": 6,
"Angle": 0,
"EntityIndex": 21,
"TargetType": 18
},
{
"X": 50688,
"Y": -2048,
"Z": 32256,
"Room": 19,
"EntityIndex": 26,
"TargetType": 18
}
],
"LEVEL7A.PHD": [
{
"X": 42496,
"Y": -8448,
"Z": 40448,
"Room": 15,
"Angle": -32768,
"X": 40448,
"Y": -5632,
"Z": 42496,
"Room": 14,
"EntityIndex": 21,
"TargetType": 18
},
Expand Down
6 changes: 6 additions & 0 deletions TRRandomizerCore/TRRandomizerController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,12 @@ public bool RelocateAwkwardEnemies
set => LevelRandomizer.RelocateAwkwardEnemies = value;
}

public bool HideDeadTrexes
{
get => LevelRandomizer.HideDeadTrexes;
set => LevelRandomizer.HideDeadTrexes = value;
}

public BirdMonsterBehaviour BirdMonsterBehaviour
{
get => LevelRandomizer.BirdMonsterBehaviour;
Expand Down
1 change: 1 addition & 0 deletions TRRandomizerCore/TRRandomizerType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ public enum TRRandomizerType
BlankTracks,
TextureSwap,
Wireframe,
HideDeadTrexes,
}
1 change: 1 addition & 0 deletions TRRandomizerCore/TRVersionSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ internal class TRVersionSupport
TRRandomizerType.GlitchedSecrets,
TRRandomizerType.HardSecrets,
TRRandomizerType.HiddenEnemies,
TRRandomizerType.HideDeadTrexes,
TRRandomizerType.Item,
TRRandomizerType.KeyItems,
TRRandomizerType.Secret,
Expand Down
24 changes: 22 additions & 2 deletions TRRandomizerView/Model/ControllerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class ControllerOptions : INotifyPropertyChanged
private bool _useRewardRoomCameras;
private uint _minSecretCount, _maxSecretCount;
private BoolItemControlClass _includeKeyItems, _allowReturnPathLocations, _includeExtraPickups, _randomizeItemTypes, _randomizeItemLocations, _allowEnemyKeyDrops, _maintainKeyContinuity, _oneItemDifficulty;
private BoolItemControlClass _crossLevelEnemies, _protectMonks, _docileWillard, _swapEnemyAppearance, _allowEmptyEggs, _hideEnemies, _removeLevelEndingLarson, _giveUnarmedItems, _relocateAwkwardEnemies, _unrestrictedEnemyDifficulty;
private BoolItemControlClass _crossLevelEnemies, _protectMonks, _docileWillard, _swapEnemyAppearance, _allowEmptyEggs, _hideEnemies, _removeLevelEndingLarson, _giveUnarmedItems, _relocateAwkwardEnemies, _hideDeadTrexes, _unrestrictedEnemyDifficulty;
private BoolItemControlClass _persistTextures, _randomizeWaterColour, _retainLevelTextures, _retainKeySpriteTextures, _retainSecretSpriteTextures, _retainEnemyTextures, _retainLaraTextures;
private BoolItemControlClass _changeAmbientTracks, _includeBlankTracks, _changeTriggerTracks, _separateSecretTracks, _changeWeaponSFX, _changeCrashSFX, _changeEnemySFX, _changeDoorSFX, _linkCreatureSFX, _randomizeWibble;
private BoolItemControlClass _persistOutfits, _removeRobeDagger, _allowGymOutfit;
Expand Down Expand Up @@ -2517,6 +2517,16 @@ public BoolItemControlClass RelocateAwkwardEnemies
}
}

public BoolItemControlClass HideDeadTrexes
{
get => _hideDeadTrexes;
set
{
_hideDeadTrexes = value;
FirePropertyChanged();
}
}

public BirdMonsterBehaviour BirdMonsterBehaviour
{
get => _birdMonsterBehaviour;
Expand Down Expand Up @@ -3162,6 +3172,12 @@ public ControllerOptions()
HelpURL = "https://github.com/LostArtefacts/TR-Rando/blob/master/Resources/Documentation/ENEMIES.md#awkward-enemies",
};
BindingOperations.SetBinding(RelocateAwkwardEnemies, BoolItemControlClass.IsActiveProperty, randomizeEnemiesBinding);
HideDeadTrexes = new()
{
Title = "Hide dead T-rexes",
Description = "T-rexes retain collision on death in TR1R, so this option will move them out of the way when killed.",
};
BindingOperations.SetBinding(HideDeadTrexes, BoolItemControlClass.IsActiveProperty, randomizeEnemiesBinding);
ProtectMonks = new BoolItemControlClass()
{
Title = "Avoid having to kill allies",
Expand Down Expand Up @@ -3467,7 +3483,7 @@ public ControllerOptions()
};
EnemyBoolItemControls = new()
{
_crossLevelEnemies, _docileWillard, _protectMonks, _swapEnemyAppearance, _allowEmptyEggs, _hideEnemies, _relocateAwkwardEnemies, _removeLevelEndingLarson, _giveUnarmedItems,_allowEnemyKeyDrops, _unrestrictedEnemyDifficulty
_crossLevelEnemies, _docileWillard, _protectMonks, _swapEnemyAppearance, _allowEmptyEggs, _hideEnemies, _relocateAwkwardEnemies, _hideDeadTrexes, _removeLevelEndingLarson, _giveUnarmedItems,_allowEnemyKeyDrops, _unrestrictedEnemyDifficulty
};
TextureBoolItemControls = new()
{
Expand Down Expand Up @@ -3565,6 +3581,7 @@ private void AdjustAvailableOptions()

_protectMonks.IsAvailable = !IsTR1;
_docileWillard.IsAvailable = IsTR3;
_hideDeadTrexes.IsAvailable = IsHideDeadTrexesTypeSupported;

_includeKeyItems.IsAvailable = IsKeyItemTypeSupported;
_maintainKeyContinuity.IsAvailable = IsKeyContinuityTypeSupported;
Expand Down Expand Up @@ -3694,6 +3711,7 @@ public void Load(TRRandomizerController controller)
ProtectMonks.Value = _controller.ProtectMonks;
DocileWillard.Value = _controller.DocileWillard;
RelocateAwkwardEnemies.Value = _controller.RelocateAwkwardEnemies;
HideDeadTrexes.Value = _controller.HideDeadTrexes;
BirdMonsterBehaviours = Enum.GetValues<BirdMonsterBehaviour>();
BirdMonsterBehaviour = _controller.BirdMonsterBehaviour;
DragonSpawnTypes = Enum.GetValues<DragonSpawnType>();
Expand Down Expand Up @@ -4010,6 +4028,7 @@ public void Save()
_controller.ProtectMonks = ProtectMonks.Value;
_controller.DocileWillard = DocileWillard.Value;
_controller.RelocateAwkwardEnemies = RelocateAwkwardEnemies.Value;
_controller.HideDeadTrexes = HideDeadTrexes.Value;
_controller.BirdMonsterBehaviour = BirdMonsterBehaviour;
_controller.DragonSpawnType = DragonSpawnType;
_controller.SwapEnemyAppearance = SwapEnemyAppearance.Value;
Expand Down Expand Up @@ -4257,6 +4276,7 @@ public void Unload()
public bool IsKeyItemTexturesTypeSupported => IsRandomizationSupported(TRRandomizerType.KeyItemTextures);
public bool IsWaterColourTypeSupported => IsRandomizationSupported(TRRandomizerType.WaterColour);
public bool IsAtlanteanEggBehaviourTypeSupported => IsRandomizationSupported(TRRandomizerType.AtlanteanEggBehaviour);
public bool IsHideDeadTrexesTypeSupported => IsRandomizationSupported(TRRandomizerType.HideDeadTrexes);
public bool IsHiddenEnemiesTypeSupported => IsRandomizationSupported(TRRandomizerType.HiddenEnemies);
public bool IsLarsonBehaviourTypeSupported => IsRandomizationSupported(TRRandomizerType.LarsonBehaviour);
public bool IsClonedEnemiesTypeSupported => IsRandomizationSupported(TRRandomizerType.ClonedEnemies);
Expand Down

0 comments on commit 1c1658a

Please sign in to comment.