// The tag prefix for enemies spawned by this placeable
string sEnemyTagPrefix = "SPAWNED_ENEMY_";

// Maximum number of enemies on the map
int nMaxEnemies = 30;

// VFX to play when an enemy spawns
int nSpawnVFX = VFX_FNF_SUMMON_MONSTER_1;  // Effect number 36

// Delay between each enemy spawn in seconds
float fSpawnDelay = 3.0;

// Function to get a random ResRef from the placeable?s stored variables
string GetRandomResRef(object oPlaceable)
{
    int nMaxResRefs = 3;  // Adjust this if you add more ResRef variables
    int nIndex = Random(nMaxResRefs) + 1; // Randomly pick 1, 2, or 3
    return GetLocalString(oPlaceable, "sResRef" + IntToString(nIndex));
}

// Function to count the number of active spawned enemies
int CountEnemies()
{
    int nCount = 0;
    object oCreature = GetFirstObjectInArea();

    while (GetIsObjectValid(oCreature))
    {
        if (GetTag(oCreature) == sEnemyTagPrefix) // Check if the tag matches enemy prefix
        {
            nCount++;
        }
        oCreature = GetNextObjectInArea();
    }

    return nCount;
}

// Function to spawn a single enemy
void SpawnEnemy(object oPlaceable)
{
    // Get a random ResRef from the placeable
    string sResRef = GetRandomResRef(oPlaceable);

    // Ensure we have a valid ResRef to spawn
    if (sResRef == "") return;

    // Get the custom waypoint tag from the placeable or use a default if not set
    string sWaypointTag = GetLocalString(oPlaceable, "sSpawnWaypointTag");
    if (sWaypointTag == "") sWaypointTag = "ENEMY_SPAWN_POINT";

    // Find the waypoint with the specified tag
    object oSpawnPoint = GetObjectByTag(sWaypointTag);
    if (GetIsObjectValid(oSpawnPoint))
    {
        // Play VFX at the spawn location
        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(nSpawnVFX), GetLocation(oSpawnPoint));

        // Create the enemy at the waypoint
        object oEnemy = CreateObject(OBJECT_TYPE_CREATURE, sResRef, GetLocation(oSpawnPoint));

        // Set the enemy's tag to track them
        SetTag(oEnemy, sEnemyTagPrefix + IntToString(GetLocalInt(oPlaceable, "nEnemyID")));
        SetLocalInt(oPlaceable, "nEnemyID", GetLocalInt(oPlaceable, "nEnemyID") + 1);
    }
}

// Function to turn on the spawner
void TurnOnSpawner(object oPlaceable)
{
    SetLocalInt(oPlaceable, "bIsActive", TRUE);
    SendMessageToPC(GetFirstPC(), "The spawner has been activated.");
}

// Function to spawn multiple enemies with a delay
void SpawnEnemiesWithDelay(object oPlaceable, int nEnemiesToSpawn)
{
    int i;
    float fDelay;

    // Loop through each enemy to be spawned
    for (i = 0; i < nEnemiesToSpawn; i++)
    {
        // Calculate the delay for each enemy
        fDelay = i * fSpawnDelay;
        DelayCommand(fDelay, SpawnEnemy(oPlaceable));
    }
}


void main()
{
    // Get the placeable running this script
    object oPlaceable = OBJECT_SELF;

    // Check if the placeable is active
    if (GetLocalInt(oPlaceable, "bIsActive") != TRUE)
    {
        // If not active, do nothing
        return;
    }

    // Stop if the placeable has been destroyed
    if (!GetIsObjectValid(oPlaceable)) return;

    // Count current spawned enemies
    int nCurrentEnemies = CountEnemies();

    // Calculate how many enemies need to be spawned
    int nEnemiesToSpawn = nMaxEnemies - nCurrentEnemies;

    // Spawn enemies with delay if below maximum count
    if (nEnemiesToSpawn > 0)
    {
        SpawnEnemiesWithDelay(oPlaceable, nEnemiesToSpawn);
    }
}
