Skip to content

Commit

Permalink
RE CV: fix enemy respawning
Browse files Browse the repository at this point in the history
  • Loading branch information
IntelOrca committed Mar 23, 2024
1 parent 29a2350 commit 5d82fba
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 13 deletions.
64 changes: 52 additions & 12 deletions IntelOrca.Biohazard.BioRand/EnemyRandomiser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ internal class EnemyRandomiser
private readonly IEnemyHelper _enemyHelper;
private readonly DataManager _dataManager;
private EnemyPosition[] _enemyPositions = new EnemyPosition[0];
private HashSet<byte> _killIdPool = new HashSet<byte>();
private Queue<byte> _killIds = new Queue<byte>();
private HashSet<ushort> _killIdPool = new HashSet<ushort>();
private Queue<ushort> _killIds = new Queue<ushort>();
private Dictionary<byte, EmbeddedEffect> _effects = new Dictionary<byte, EmbeddedEffect>();
private List<CvEnemyAssets> _cvEnemies = new List<CvEnemyAssets>();

Expand Down Expand Up @@ -121,7 +121,7 @@ private void HarvestEnemyAssets(RdtId rdtId, short enemyType, short variant, int
_cvEnemies.Add(new CvEnemyAssets(enemyType, variant, model, motion, texture));
}

public byte GetNextKillId()
public ushort GetNextKillId()
{
if (_killIds.Count == 0)
{
Expand All @@ -136,30 +136,46 @@ public byte GetNextKillId()
private void SetupRandomEnemyPlacements()
{
_enemyPositions = _enemyPositions.Shuffle(_rng);
for (byte i = 0; i < 255; i++)
_killIdPool.Add(i);
var maxEnemyIds = _version == BioVersion.BiohazardCv ? 384 : 255;
for (var i = 0; i < maxEnemyIds; i++)
_killIdPool.Add((ushort)i);

var reservedEnemyIds = _enemyHelper.GetReservedEnemyIds();
foreach (var enemyId in reservedEnemyIds)
_killIdPool.Remove(enemyId);

foreach (var rdt in _gameData.Rdts)
{
byte[] killIds;
ushort[] killIds;
if (_enemyPositions.Any(x => x.RdtId == rdt.RdtId))
{
// Exclude IDs which belong to special enemies like tyrants or bosses
killIds = rdt.Enemies
.Where(x => !_enemyHelper.IsEnemy(x.Type) || _enemyHelper.IsUniqueEnemyType(x.Type))
.Select(x => x.KillId)
.Select(x => (ushort)x.KillId)
.ToArray();
}
else
{
// Exclude IDs which belong to static enemy rooms
killIds = rdt.Enemies
.Select(x => x.KillId)
.ToArray();
if (_version == BioVersion.BiohazardCv)
{
killIds = rdt.AllOpcodes
.Where(x => x.Opcode == 0x22)
.Select(opcode =>
{
var data = ((UnknownOpcode)opcode).Data;
var id = (ushort)((data[2] << 8) | data[1] & 0xFF);
return id;
})
.ToArray();
}
else
{
killIds = rdt.Enemies
.Select(x => (ushort)x.KillId)
.ToArray();
}
}
_killIdPool.RemoveMany(killIds);
}
Expand Down Expand Up @@ -614,6 +630,30 @@ private void RandomiseRoom(Rng rng, RandomizedRdt rdt, MapRoomEnemies enemySpec,
var enemyType = _rng.NextOf(possibleTypes);
var assets = _cvEnemies.FirstOrDefault(x => x.EnemyType == enemyType);
var placements = GetRandomPlacements(rdt.RdtId, rng, enemySpec, enemyType);
var killIds = placements.Select(x => GetNextKillId()).ToArray();

foreach (var opcode in rdt.AllOpcodes.Where(x => x.Opcode == 0x0D))
{
rdt.Nop(opcode.Offset);
}
foreach (var opcode in rdt.AllOpcodes.Where(x => x.Opcode == 0x22))
{
rdt.Nop(opcode.Offset);
}
for (var i = 0; i < killIds.Length; i++)
{
var killId = killIds[i];
rdt.AdditionalOpcodes.Add(new UnknownOpcode(0, 0x22, new byte[] {
(byte)i,
(byte)(killId & 0xFF),
(byte)(killId >> 8)
}));
rdt.AdditionalFrameOpcodes.Add(new UnknownOpcode(0, 0x0D, new byte[] {
(byte)i,
(byte)(killId & 0xFF),
(byte)(killId >> 8)
}));
}

rdt.PostModifications.Add(() =>
{
Expand Down Expand Up @@ -768,15 +808,15 @@ private SceEmSetOpcode[] GenerateRandomEnemies(Rng rng, RandomizedRdt rdt, MapRo
}

var killId = GetNextKillId();
var newEnemy = CreateEnemy(enemyId, killId, ep);
var newEnemy = CreateEnemy(enemyId, (byte)killId, ep);
enemyOpcodes.Add(newEnemy);
enemies.Add(newEnemy);
enemyId++;

var dependencies = _enemyHelper.GetEnemyDependencies(enemyType);
foreach (var d in dependencies)
{
newEnemy = CreateEnemy(enemyId, killId, ep);
newEnemy = CreateEnemy(enemyId, (byte)killId, ep);
enemyOpcodes.Add(newEnemy);
enemies.Add(newEnemy);
}
Expand Down
2 changes: 1 addition & 1 deletion IntelOrca.Biohazard.BioRand/Events/PlotBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public CsEnemy AllocateEnemy(byte? type = null, bool hasGlobalId = true)
if (id == 255)
throw new InvalidOperationException();

var globalId = hasGlobalId ? _enemyRandomiser?.GetNextKillId() ?? 255 : (byte)255;
var globalId = (byte)(hasGlobalId ? _enemyRandomiser?.GetNextKillId() ?? 255 : 255);
type ??= EnemyType ?? Re2EnemyIds.ZombieRandom;
var position = _enemyPositions.Next();
var enemyHelper = _enemyRandomiser?.EnemyHelper ?? new Re2EnemyHelper();
Expand Down

0 comments on commit 5d82fba

Please sign in to comment.