GetCorrespondingDeactivator() public static méthode

public static GetCorrespondingDeactivator ( EEnemyID activator ) : EEnemyID
activator EEnemyID
Résultat EEnemyID
Exemple #1
0
        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);
        }
Exemple #2
0
        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
        }