class TehSpawnsMut extends Mutator;

var bool interactionAdded;

function Mutate(string mutateString, PlayerController player)
{
    local SpawnManager manager;
    if (mutateString ~= "pathinfo") {
        ShowMeInfo(player);
    }
    if (mutateString ~= "doit")
    {
        manager = Spawn(class'SpawnManager');
        manager.Initialize();
    }
    if (mutateString ~= "predoit") {
        DoIt(player, false);
    }
    if (mutateString ~= "predoit2") {
        DoIt(player, true);
    }
    if (mutateString ~= "check") {
        CheckSin(player);
    }
    if (nextMutator != none) {
        nextMutator.Mutate(mutateString, player);
    }
}

function ShowMeInfo(PlayerController player)
{
    local int               nodeCount, volumeCount;
    local ZombieVolume      nextVolume;
    local NavigationPoint   nextNode;
    StopWatch(false);
    foreach AllActors(class'NavigationPoint', nextNode) {
        nodeCount += 1;
    }
    StopWatch(true);
    StopWatch(false);
    foreach AllActors(class'ZombieVolume', nextVolume) {
        volumeCount += 1;
    }
    StopWatch(true);
    player.ClientMessage("Path nodes count:" @ nodeCount);
    player.ClientMessage("`ZomvieVolume`s count:" @ volumeCount);
}

function CheckSin(PlayerController player)
{
    local int i;
    StopWatch(false);
    for (i = 0; i < 1000; i += 1) {
        sin(float(i));
    }
    StopWatch(true);
}

function doit(PlayerController player, bool nav)
{
    local int               iter;
    local int               totalZV, fullZV;
    local float             perc;
    local float             distance, maxDistance;
    local NavigationPoint   nextPoint, furthestPoint, selectedPoint;
    local ZombieVolume      nextVolume, isolatedVolume;
    maxDistance = -1;
    StopWatch(false);
    foreach AllActors(class'ZombieVolume', nextVolume)
    {
        distance = 1000000;
        selectedPoint = none;
        foreach AllActors(class'NavigationPoint', nextPoint)
        {
            iter += 1;
            if (VSize(nextPoint.location - nextVolume.location) < distance)
            {
                if (!FastTrace(nextPoint.location, nextVolume.location)) {
                    continue;
                }
                distance = VSize(nextPoint.location - nextVolume.location);
                selectedPoint = nextPoint;
            }
        }
        totalZV += 1;
        if (selectedPoint != none && nextVolume.Encompasses(selectedPoint)) {
            fullZV += 1;
        }
        //Log("Min distance:" @ distance);
        if (maxDistance < distance && selectedPoint != none)
        {
            maxDistance = distance;
            isolatedVolume = nextVolume;
            furthestPoint = selectedPoint;
        }
    }
    StopWatch(true);
    perc = (float(fullZV) / float(totalZV)) * 100;
    player.ClientMessage("Max ditance is:" @ maxDistance);
    player.ClientMessage("Iterations done:" @ iter);
    player.ClientMessage("Full volume percentage:" @ perc);
    if (nav) {
        player.SetLocation(furthestPoint.location);
    }
    else {
        player.SetLocation(isolatedVolume.location);
    }
}

simulated function Tick(float delta)
{
    local ReportInteraction myInteraction;
    local Player            localPlayer;
    if (role == Role_AUTHORITY) return;
    if (interactionAdded)       return;
    localPlayer = level.GetLocalPlayerController().player;
    if (localPlayer == none)    return;

    myInteraction = ReportInteraction(localPlayer.interactionMaster
        .AddInteraction("TehSpawns.ReportInteraction", localPlayer));
    if (myInteraction != none) {
        interactionAdded = true;
    }
}

defaultproperties
{
    //  Mutator description
    GroupName       = "Test mutators"
    FriendlyName    = "Zed spawner mutator"
    Description     = "Mutator that provides clients with information about how many zeds (and their spawn rate) are present on the map."
    bAddToServerPackages = true
    bAlwaysRelevant = true
    RemoteRole      = ROLE_SimulatedProxy
}