public static GetCorrespondingDeactivator ( EEnemyID activator ) : EEnemyID | ||
activator | EEnemyID | |
Résultat | EEnemyID |
public byte TryReplaceActivator(List <EnemyType> newEnemies, byte id) { byte newId = id; bool foundNonActivator = false; foreach (EnemyType enemyType in newEnemies) { if (!enemyType.IsActivator) { newId = (byte)enemyType.ID; foundNonActivator = true; break; } } // Otherwise, switch to its corresponding deactivator(room will appear empty) if (!foundNonActivator) { newId = (byte)EnemyType.GetCorrespondingDeactivator(id); } return(newId); }
private void Execute(Patch Patch, Random r) { foreach (SpriteBankRoomGroup sbrg in RoomGroups) { // Skip processing the room if every sprite bank row is taken if (sbrg.IsSpriteRestricted && sbrg.SpriteBankRowsRestriction.Count >= 6) { continue; } // Create valid random combination of enemies to place List <EnemyType> newEnemies = GenerateEnemyCombinations(sbrg, r); // No enemy can fit in this room for some reason, skip this room (GFX will be glitched) if (newEnemies.Count == 0) { continue; } // For each enemy ID (in the room, in the room-group), change to a random enemy from the new set for (int i = 0; i < sbrg.Rooms.Count; i++) { Room room = sbrg.Rooms[i]; for (int j = 0; j < room.EnemyInstances.Count; j++) { EnemyInstance instance = room.EnemyInstances[j]; int randomIndex = r.Next(newEnemies.Count); EnemyType newEnemyType = newEnemies[randomIndex]; byte newId = (byte)newEnemyType.ID; // When placing the last enemy, If room contains an activator, manually change the last spawn in the room to be its deactivator if (j == room.EnemyInstances.Count - 1) { EEnemyID?activator = room.GetActivatorIfOneHasBeenAdded(); if (activator != null) { newId = (byte)EnemyType.GetCorrespondingDeactivator((EEnemyID)activator); } // Also, if this last instance is an activator, try to replace it if (EnemyType.CheckIsActivator(newId)) { newId = TryReplaceActivator(newEnemies, newId); // Update the new enemy type because it may require different graphics if (!EnemyType.CheckIsDeactivator(newId)) { newEnemyType = newEnemies.Where(x => (byte)x.ID == newId).First(); } } } sbrg.NewEnemyTypes.Add(newEnemyType); // TODO: This all should be refactored. Use a hashtable of EnemyTypes and abolish "EnemyID". // If room contains only this one enemy and it is an activator // TODO: How does Clash stage work with the Pipis? They don't break normally. if ((room.EnemyInstances.Count == 1 && instance.HasNewActivator())) { // Try to replace it with a non-activator enemy //newId = TryReplaceActivator(newEnemies, newId); } // Last-minute adjustments to certain enemy spawns switch ((EEnemyID)newId) { case EEnemyID.Shrink: double randomSpawner = r.NextDouble(); if (randomSpawner < CHANCE_SHRINKSPAWNER) { newId = (byte)EEnemyID.Shrink_Spawner; } break; case EEnemyID.Shotman_Left: if (instance.IsFaceRight) { newId = (byte)EEnemyID.Shotman_Right; } break; default: break; } // Update object with new ID for future use room.EnemyInstances[j].EnemyID = newId; // Change the enemy ID in the ROM int IDposition = Stage0EnemyIDAddress + instance.StageNum * StageLength + instance.Offset; Patch.Add(IDposition, newId, $"{sbrg.Stage.ToString("G")} Stage Enemy #{instance.Offset} ID (Room {instance.RoomNum}) {((EEnemyID)instance.EnemyID).ToString("G")}"); // Change the enemy Y pos based on Air or Ground category int newY = newEnemyType.YAdjust; newY += (newEnemyType.IsYPosAir) ? instance.YAir : instance.YGround; IDposition = Stage0EnemyYAddress + instance.StageNum * StageLength + instance.Offset; Patch.Add(IDposition, (byte)newY, $"{sbrg.Stage.ToString("G")} Stage Enemy #{instance.Offset} Y (Room {instance.RoomNum}) {((EEnemyID)instance.EnemyID).ToString("G")}"); } } // Change sprite banks for the room foreach (EnemyType e in sbrg.NewEnemyTypes) { for (int i = 0; i < e.SpriteBankRows.Count; i++) { int rowInSlotAddress = sbrg.PatternAddressStart + e.SpriteBankRows[i] * 2; int patternTblPtr1 = e.PatternTableAddresses[2 * i]; int patternTblPtr2 = e.PatternTableAddresses[2 * i + 1]; Patch.Add(rowInSlotAddress, (byte)patternTblPtr1, $"{sbrg.Stage.ToString("G")} Stage Sprite Bank Slot ? Row {e.SpriteBankRows[i]} Indirect Address 1"); Patch.Add(rowInSlotAddress + 1, (byte)patternTblPtr2, $"{sbrg.Stage.ToString("G")} Stage Sprite Bank Slot ? Row {e.SpriteBankRows[i]} Indirect Address 2"); } } } // end foreach sbrg }