Skip to content

Commit

Permalink
Allocate fairer secret rewards
Browse files Browse the repository at this point in the history
Added some minimums and potentially some bonus secret rewards to be fairer to players. The Hive for example has one reward item by default, but could potentially have 5 secrets to collect.
  • Loading branch information
lahm86 committed Dec 1, 2023
1 parent eb7cafe commit 66159e4
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
3 changes: 2 additions & 1 deletion TRRandomizerCore/Editors/TR1RandoEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMoni
BasePath = wipDirectory,
BackupPath = backupDirectory,
SaveMonitor = monitor,
Settings = Settings
Settings = Settings,
ItemFactory = itemFactory,
}.Randomize(Settings.SecretRewardsPhysicalSeed);
}

Expand Down
42 changes: 35 additions & 7 deletions TRRandomizerCore/Randomizers/TR1/TR1SecretRewardRandomizer.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
using TRGE.Core;
using TRLevelControl.Helpers;
using TRLevelControl.Model;
using TRRandomizerCore.Helpers;
using TRRandomizerCore.Levels;
using TRRandomizerCore.Secrets;
using TRRandomizerCore.Utilities;

namespace TRRandomizerCore.Randomizers;

public class TR1SecretRewardRandomizer : BaseTR1Randomizer
{
private static readonly int _minRewardCount = 3;
private static readonly double _doubleRewardChance = (double)1 / 6;
private static readonly double _extraRewardChance = (double)1 / 3;

public ItemFactory<TR1Entity> ItemFactory { get; set; }

public override void Randomize(int seed)
{
_generator = new Random(seed);
Expand All @@ -34,20 +42,40 @@ private void RandomizeRewards(TR1CombinedLevel level)
return;
}

TRSecretMapping<TR1Entity> secretMapping = TRSecretMapping<TR1Entity>.Get(GetResourcePath(@"TR1\SecretMapping\" + level.Name + "-SecretMapping.json"));
TRSecretMapping<TR1Entity> secretMapping = TRSecretMapping<TR1Entity>.Get(GetResourcePath($@"TR1\SecretMapping\{level.Name}-SecretMapping.json"));

List<TR1Type> stdItemTypes = TR1TypeUtilities.GetStandardPickupTypes();
stdItemTypes.Remove(TR1Type.PistolAmmo_S_P); // Sprite/model not available
stdItemTypes.Remove(TR1Type.Pistols_S_P); // A bit cruel as a reward?

for (int i = 0; i < level.Data.Entities.Count; i++)
int secretRoom = RoomWaterUtilities.DefaultRoomCountDictionary[level.Name];
List<Location> rewardPositions = secretMapping.Rooms.First().RewardPositions;
List<int> rewardIndices = new(secretMapping.RewardEntities);

// Give at least one item per secret, never less than the original reward item count,
// and potentially some extra bonus items.
int rewardCount = Math.Max(rewardIndices.Count, level.Script.NumSecrets);
rewardCount = Math.Max(rewardCount, _minRewardCount);

if (_generator.NextDouble() < _extraRewardChance)
{
if (!secretMapping.RewardEntities.Contains(i))
{
continue;
}
rewardCount += level.Script.NumSecrets;
}
else if (_generator.NextDouble() < _doubleRewardChance)
{
rewardCount += 2 * level.Script.NumSecrets;
}

while (rewardIndices.Count < rewardCount)
{
TR1Entity item = ItemFactory.CreateItem(level.Name, level.Data.Entities, rewardPositions[_generator.Next(0, rewardPositions.Count)], true);
rewardIndices.Add(level.Data.Entities.IndexOf(item));
item.Room = (short)secretRoom;
}

level.Data.Entities[i].TypeID = stdItemTypes[_generator.Next(0, stdItemTypes.Count)];
foreach (int rewardIndex in rewardIndices)
{
level.Data.Entities[rewardIndex].TypeID = stdItemTypes[_generator.Next(0, stdItemTypes.Count)];
}
}
}

0 comments on commit 66159e4

Please sign in to comment.