difficulty=Map.LobbyOption("difficulty")
tanktypes=Map.LobbyOption("tanktypes")
infantrytypes=Map.LobbyOption("infantrytypes")
toxiclevel=Map.LobbyOption("toxiclevel")
FactoryVehicle=Map.LobbyOption("FactoryVehicle")
FactoryWar=Map.LobbyOption("FactoryWar")
showtoxidicy=Map.LobbyOption("showtoxidicy")

function setDifficulty()

    toxicAdjustment=1

    if toxic_enabled==1 then
        toxicAdjustment=3
    end

    if difficulty=="noob" then
        difficultyHandicap=0.6
        maxLimit=(6*HandicapAdjustment)*toxicAdjustment
        mcvLimit=(12*HandicapAdjustment)*toxicAdjustment
    elseif difficulty=="easy" then
        difficultyHandicap=0.8
        maxLimit=(10*HandicapAdjustment)*toxicAdjustment
        mcvLimit=(14*HandicapAdjustment)*toxicAdjustment
    elseif difficulty=="normal" then
        difficultyHandicap=1
        maxLimit=(14*HandicapAdjustment)*toxicAdjustment
        mcvLimit=(18*HandicapAdjustment)*toxicAdjustment
    elseif difficulty=="extreme" then
        difficultyHandicap=1.2
        maxLimit=(20*HandicapAdjustment)*toxicAdjustment
        mcvLimit=(30*HandicapAdjustment)*toxicAdjustment
    else
        difficultyHandicap=1.5
        maxLimit=99
        mcvLimit=99
    end
end

function theBots()
    return Player.GetPlayers(function(player)
        return player.IsBot==true;
    end);
end

function theUltimateBots()
    return Player.GetPlayers(function(player)
        return player.IsBot==true and player.HasPrerequisites({"ultimateaienabled"});
    end);
end

function theHumans()
    return Player.GetPlayers(function(player)
        return player.IsBot==false and player.IsNonCombatant==false;
    end);
end

function thePlayers()
    return Player.GetPlayers(function(player)
        return player.IsNonCombatant==false;
    end);
end

function thePlayersAndCreeps()
    return Player.GetPlayers(function(player)
        return true
    end);
end

--Random Testing
function getActorsAround(actorselected,actorsToFind,distance)
    actorList=Map.ActorsInCircle(actorselected.CenterPosition,WDist.FromCells(distance),function(a)
        return a.Type==actorsToFind
    end)

    return actorList
end

--messaging system
function readmessages()

    messagescount=tablelength(messages)

    resetmessagestimer=messagescount*3+1

    if messagescount>0 then
        for i=tablelength(messages),1,-1 do
            Trigger.AfterDelay(DateTime.Seconds(i*3),function()
                Media.DisplayMessage (messages[i],"Mission",HSLColor.Red)
            end)
        end
    else
        Media.DisplayMessage ("No Messages to Display","Mission",HSLColor.Red)
    end

    Trigger.AfterDelay(DateTime.Seconds(resetmessagestimer),function()
        messages={}
    end)
end

--message loop
function readmessagesloop()

    if loopcounter<6 then

        messagescount=tablelength(messagesloop)

        resetmessagestimer=messagescount*3+1

        if messagescount>0 then
            for i=tablelength(messagesloop),1,-1 do
                Trigger.AfterDelay(DateTime.Seconds(i*3),function()
                    Media.DisplayMessage (messagesloop[i],"Mission",HSLColor.Red)
                end)
            end
        else
            --Media.DisplayMessage ("No Loop Messages to Display", "Mission", HSLColor.Red)
        end

        Trigger.AfterDelay(5000,readmessagesloop)
        loopcounter=loopcounter+1
    end
end

--Ref Setup
function setupRefs()

    facts=Map.ActorsInBox(Map.TopLeft,Map.BottomRight,function(actor)
        return actor.Type=="fact" or actor.Type=="mcv"
    end)

    Utils.Do(facts,function(a)

        -- Media.DisplayMessage (""..a.Owner.Name, "Mission", HSLColor.Red)
        if a.Owner~=castlePlayer then
            actorOwner=a.Owner
            --Media.DisplayMessage (""..actorOwner.Name, "Mission", HSLColor.Red)

            toCapture={}
            toCapture={"silo","powr"}

            Utils.Do(toCapture,function(z)
                actorsToCapture=getActorsAround(a,z,20)

                Utils.Do(actorsToCapture,function(b)
                    b.Owner=actorOwner
                end)
            end)
        end
    end)

    --Create Refs
    Trigger.AfterDelay(DateTime.Seconds(1),function()
        powrs=Map.ActorsInBox(Map.TopLeft,Map.BottomRight,function(actor)
            return
            actor.Type=="silo"
        end)

        Utils.Do(powrs,function(a)

            actorOwner=a.Owner
            originalLocation=a.Location
            newLocation=originalLocation+CVec.New(0,1)

            if actorOwner.InternalName~="Creeps" then
                Actor.Create("proc",true,{Owner=actorOwner,Location=newLocation})
            end

            --Media.DisplayMessage (""..actorOwner.InternalName, "Mission", HSLColor.Red)
            -- Media.DisplayMessage(""..newLocation, "Mission", HSLColor.Red)
        end)

    end)

    Trigger.AfterDelay(DateTime.Seconds(2),function()
        creepActors=getAllCreeps()
        removeactors(creepActors)
        --Media.DisplayMessage(""..#creepActors, "Mission", HSLColor.Red)

    end)
end

--Remove Boxes in Table
function removeactors(a)
    Utils.Do(a,function(unit)
        unit.Destroy()
    end)
    return
end

function getClosetActor(actorselected,actorsToFind)
    actorList=Map.ActorsInCircle(actorselected.CenterPosition,WDist.FromCells(50),function(a)
        return a.Type==actorsToFind
    end)

    return actorList[1]
end

function getAllActors(a)

    theActors=Map.ActorsInBox(Map.TopLeft,Map.BottomRight,function(actor)
        return actor.Type==a
    end)

    return theActors
end

function getAllCreeps()

    targets=Utils.Where(Creeps.GetActors(),function(actor)
        return
        actor.Type=="powr" or actor.Type=="silo"
    end)
    return targets
end

----START OF AI REINFORCEMENTS ---

function createNewMcv(quantity)
    if quantity==nil then
        quantity=1
    end
    Trigger.AfterDelay(DateTime.Seconds(10),function()
        for z,thePlayer in ipairs(AIPlayers) do
            Actor.Create("mcv",true,{Owner=thePlayer,Location=thePlayer.HomeLocation+CVec.New(0,3)});
        end
        quantity=quantity-1
        if quantity>0 then
            createNewMcv(quantity)
        end
    end)
end

function createRandomInfantryPerBuilding(quantity)
    if quantity==nil then
        quantity=1
    end

    countLimit=0

    for z,thePlayer in ipairs(AIPlayers) do
        theProducers=thePlayer.GetActorsByTypes({"barr","tent"});

        Utils.Do(theProducers,function(theUnits)
            if countLimit<maxLimit then
                if (infantrytypes~="normal") then
                    toProduceTanks={infantrytypes}
                else
                    if (difficulty=="easy" or difficulty=="noob") then
                        toProduceTanks={"e1","e1","e1","e1","e1","e1","e3"}
                    else
                        toProduceTanks={"e1","e1","e1","e3","e3"}
                    end
                end
                randomUnit=Utils.RandomInteger(1,#toProduceTanks+1)
                randomTank=toProduceTanks[randomUnit];
                --if randomTank ~= nil then
                --Media.DisplayMessage("Producing "..randomTank, "Mission", HSLColor.Red)
                --else
                --Media.DisplayMessage("Producing nil", "Mission", HSLColor.Red)
                --end
                -- Media.DisplayMessage("hello1", "Mission", HSLColor.Red)
                theTank=Actor.Create(randomTank,true,{Owner=thePlayer,Location=theUnits.Location+CVec.New(0,2)});
                theTank.Move(theUnits.RallyPoint)
                countLimit=countLimit+1
            end
        end)
    end
    quantity=quantity-1
    if quantity>0 then
        --Media.DisplayMessage("hello2", "Mission", HSLColor.Red)
        createRandomInfantryPerBuilding(quantity)
    end
end

function createRandomTankPerBuilding(quantity)
    if quantity==nil then
        quantity=1
    end

    countLimit=0

    for z,thePlayer in ipairs(AIPlayers) do
        theProducers=thePlayer.GetActorsByTypes({"weap"});

        Utils.Do(theProducers,function(theUnits)
            if countLimit<maxLimit then

                --if (tanktypes == "demolition") then
                if (tanktypes~="normal") then
                    toProduceTanks={tanktypes}
                elseif (doomsdayenabled==1) then
                    toProduceTanks={"4tnk","4tnk","4tnk","4tnk","3tnk","3tnk","3tnk","ctnk","ctnk","v2rl","mrj","arty","mgg","v2rl","arty"}
                else
                    if (difficulty=="easy" or difficulty=="noob") then
                        toProduceTanks={"jeep","apc","1tnk","ftrk","jeep","apc","1tnk","ftrk","jeep","apc","1tnk","ftrk","4tnk","ctnk","v2rl","2tnk","2tnk","1tnk","3tnk","mrj","2tnk","arty","mgg","mrj","v2rl","2tnk","arty","3tnk","2tnk","stnk","dtrk"}
                    elseif (difficulty=="normal") then
                        toProduceTanks={"apc","apc","1tnk","1tnk","ftrk","4tnk","3tnk","3tnk","ctnk","v2rl","2tnk","2tnk","2tnk","1tnk","3tnk","2tnk","arty","mgg","mrj","v2rl","2tnk","arty","3tnk","mrj","stnk","dtrk"}
                    else
                        toProduceTanks={"apc","1tnk","ftrk","4tnk","4tnk","ctnk","v2rl","2tnk","2tnk","1tnk","3tnk","mrj","2tnk","arty","mgg","mrj","v2rl","2tnk","arty","3tnk","mrj","stnk","dtrk"}
                    end
                end
                randomUnit=Utils.RandomInteger(1,#toProduceTanks+1)
                randomTank=toProduceTanks[randomUnit];
                --if randomTank ~= nil then
                --Media.DisplayMessage("Producing "..randomTank, "Mission", HSLColor.Red)
                --else
                --Media.DisplayMessage("Producing nil", "Mission", HSLColor.Red)
                --end
                -- Media.DisplayMessage("hello1", "Mission", HSLColor.Red)
                theTank=Actor.Create(randomTank,true,{Owner=thePlayer,Location=theUnits.Location+CVec.New(0,2)});
                theTank.Move(theUnits.RallyPoint)
                countLimit=countLimit+1
            end
        end)

    end
    quantity=quantity-1
    if quantity>0 then
        --Media.DisplayMessage("hello2", "Mission", HSLColor.Red)
        createRandomTankPerBuilding(quantity)
    end
end

function spawnUnits(spawnUnitType,spawnUnitOwner,spawnUnitLocation)
    theActor=Actor.Create(spawnUnitType,true,{Owner=spawnUnitOwner,Location=spawnUnitLocation});

    if spawnUnitType~="mcv" then
        if spawnUnitType=="qtnk" or spawnUnitType=="mgg" or spawnUnitType=="mrj" or spawnUnitType=="thf" then
            --theActor.Move(CaptureMiddle.Location)
        else
            --theActor.AttackMove(CaptureMiddle.Location)
        end
    end
end

function sendRepeatWave(unitsTier,quantity,repeatTime)

    if repeatTime==nil then
        repeatTime=120
    end

    sendAttackWave(unitsTier,quantity)

    --Set Next Wave
    Trigger.AfterDelay(DateTime.Seconds(repeatTime),function()
        sendRepeatWave(unitsTier,quantity,repeatTime)
    end)
end

function sendAttackWave(unitsTier,quantity)

    if repeatWave==nil then
        local repeatWave=0
    end
    if unitsTier==nil then
        unitsTier=tier1Tanks
    end

    --bug for ai production
    for z,thePlayer in ipairs(AIPlayers) do

        if #thePlayer.GetActors()>1 then

            if (unitsTier==tierMcv) then
                if (countMcvs(thePlayer)>=mcvLimit) then
                    return
                end
            end

            if quantity==nil or quantity==0 then
                quantityToProduce=7
            else
                quantityToProduce=quantity
            end

            --currentSpawn = thePlayer.HomeLocation + CVec.New(-5,-5)
            currentSpawn=thePlayer.HomeLocation+CVec.New(-1,-1)

            while quantityToProduce>0 do
                randomUnit=Utils.RandomInteger(1,#unitsTier+1)
                --Media.DisplayMessage("".. randomUnit, "Mission", HSLColor.Red)

                spawnUnits(unitsTier[randomUnit],thePlayer,currentSpawn)

                quantityToProduce=quantityToProduce-1

                if currentSpawn==spawnPoint1 then
                    currentSpawn=spawnPoint2
                elseif currentSpawn==spawnPoint2 then
                    currentSpawn=spawnPoint3
                elseif currentSpawn==spawnPoint3 then
                    currentSpawn=spawnPoint4
                elseif currentSpawn==spawnPoint4 then
                    currentSpawn=spawnPoint1
                end
            end
        end
    end
end

function createHarv()
    if quantity==nil then
        quantity=1
    end
    if toxic_enabled then
        Trigger.AfterDelay(DateTime.Seconds(10),function()
            for z,thePlayer in ipairs(AIPlayers) do
                if thePlayer.Cash<2500 then
                    Actor.Create("harv",true,{Owner=thePlayer,Location=thePlayer.HomeLocation+CVec.New(0,2)});
                end
            end
            createHarv()
        end)
    else
        Trigger.AfterDelay(DateTime.Seconds(25),function()
            for z,thePlayer in ipairs(AIPlayers) do
                if thePlayer.Cash<1500 then
                    Actor.Create("harv",true,{Owner=thePlayer,Location=thePlayer.HomeLocation+CVec.New(0,2)});
                end
            end
            createHarv()
        end)

    end
end

function createEngineers(quantity)--
    if quantity==nil then
        quantity=1
    end

    sendAttackWave(tierEngineers,#theHumans())
    sendAttackWave(tierThief,#theHumans())

    if (difficulty~="easy" and difficulty~="noob" and difficulty~="normal") then
        sendAttackWave(tierSpy,#theHumans())
    end

    Trigger.AfterDelay(DateTime.Seconds(5),function()
        sendEngineers()
        if (difficulty~="easy" and difficulty~="noob") then
        end
    end)
    if quantity>0 then
        Trigger.AfterDelay(DateTime.Seconds(60),function()
            --Media.DisplayMessage("hello2", "Mission", HSLColor.Red)
            createEngineers(quantity)
            sendThief()
            sendSpy()
        end)
    end
end

--send engineers to cap middle
actorToTarget_Thief={"jeep","apc","1tnk","ftrk","v2rl","2tnk","arty","mgg","mrj","ttnk","3tnk","mrj","ctnk","stnk","4tnk","3tnk","mrj","dtrk","ctnk","stnk"}

function sendThief()

    for z,thePlayer in ipairs(AIPlayers) do
        local theUnits=thePlayer.GetActorsByType("thf");

        --Media.DisplayMessage("sendThief", "Mission", HSLColor.Red)

        if #theUnits>0 then
            Utils.Do(theUnits,function(unit)

                --actorToTarget = { "ectnk", "dtrk" }
                --actorToTarget = { "1tnk", "2tnk", "3tnk", "4tnk", "apc", "apoc", "arty", "batf", "ctnk", "ctrk", "dtrk", "ectnk", "ftnk", "ftrk", "hftk", "isu", "jeep", "katy", "mgg", "mrj", "msam", "panzer", "ptnk", "rtnk", "sherman", "stnk", "tnkd", "ttnk2", "v2rl", "v3rl" }

                unitToTarget=findClosestTargetAiNeutral(unit,actorToTarget_Thief)

                if unitToTarget~=nil then
                    --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                    unit.Stop()
                    unit.Move(unitToTarget.Location)
                    unit.Capture(unitToTarget)
                else
                    --Media.DisplayMessage("sendThief: no ectnk", "Mission", HSLColor.Red)
                    actorToTarget={"proc"}

                    unitToTarget=findClosestTargetAi(unit,actorToTarget)

                    if unitToTarget~=nil then
                        --Media.DisplayMessage("INFILTRATE: Type: "..unitToTarget.Type, "Mission", HSLColor.Red);
                        unit.Stop()
                        unit.Move(unitToTarget.Location)
                        unit.Infiltrate(unitToTarget)
                    end
                end
            end)
        end
    end
end

--send engineers to cap middle
function sendSpy()

    for z,thePlayer in ipairs(AIPlayers) do
        local theUnits=thePlayer.GetActorsByType("spy");

        actorToTarget={"powr","apwr","dome"}

        if #theUnits>0 then
            Utils.Do(theUnits,function(unit)
                unitToTarget=findClosestTargetAi(unit,actorToTarget)

                if unitToTarget~=nil then
                    --Media.DisplayMessage("hello5", "Mission", HSLColor.Red)
                    unit.Stop()
                    unit.DisguiseAsType("e1",unitToTarget.EffectiveOwner)
                    unit.Move(unitToTarget.Location)
                    unit.Infiltrate(unitToTarget)
                end
            end)
        end
    end
end

function findClosestTargetAi(searchActor,actorTypes)
    closestActor=nil
    distnceCloset=250000;

    if Utils.RandomInteger(1,3)==1 then
        for rr,enemyPlayer in ipairs(HumanPlayers) do
            if enemyPlayer~=searchActor.EffectiveOwner then
                if enemyPlayer.Team~=searchActor.EffectiveOwner.Team or enemyPlayer.Team==0 or searchActor.EffectiveOwner.Team==0 then
                    local actors=enemyPlayer.GetActorsByTypes(actorTypes);
                    for rr,actor in ipairs(actors) do
                        theDistance=actor.Location-searchActor.Location;
                        distanceMath=math.sqrt((theDistance.X*theDistance.X)+(theDistance.Y*theDistance.Y));
                        if distanceMath<=distnceCloset then
                            distnceCloset=distanceMath;
                            closestActor=actor;
                        end
                    end
                end
            end
        end
        if (closestActor==nil) then
            for rr,enemyPlayer in ipairs(AllBots) do
                if enemyPlayer~=searchActor.Owner then
                    if enemyPlayer.Team~=searchActor.Owner.Team or enemyPlayer.Team==0 or searchActor.Owner.Team==0 then
                        local actors=enemyPlayer.GetActorsByTypes(actorTypes);
                        for rr,actor in ipairs(actors) do
                            theDistance=actor.Location-searchActor.Location;
                            distanceMath=math.sqrt((theDistance.X*theDistance.X)+(theDistance.Y*theDistance.Y));
                            if distanceMath<=distnceCloset then
                                distnceCloset=distanceMath;
                                closestActor=actor;
                            end
                        end
                    end
                end
            end
        end
    else
        for rr,enemyPlayer in ipairs(AllBots) do
            if enemyPlayer~=searchActor.Owner then
                if enemyPlayer.Team~=searchActor.Owner.Team or enemyPlayer.Team==0 or searchActor.Owner.Team==0 then
                    local actors=enemyPlayer.GetActorsByTypes(actorTypes);
                    for rr,actor in ipairs(actors) do
                        theDistance=actor.Location-searchActor.Location;
                        distanceMath=math.sqrt((theDistance.X*theDistance.X)+(theDistance.Y*theDistance.Y));
                        if distanceMath<=distnceCloset then
                            distnceCloset=distanceMath;
                            closestActor=actor;
                        end
                    end
                end
            end
        end
        if (closestActor==nil) then
            for rr,enemyPlayer in ipairs(HumanPlayers) do
                if enemyPlayer~=searchActor.EffectiveOwner then
                    if enemyPlayer.Team~=searchActor.EffectiveOwner.Team or enemyPlayer.Team==0 or searchActor.EffectiveOwner.Team==0 then
                        local actors=enemyPlayer.GetActorsByTypes(actorTypes);
                        for rr,actor in ipairs(actors) do
                            theDistance=actor.Location-searchActor.Location;
                            distanceMath=math.sqrt((theDistance.X*theDistance.X)+(theDistance.Y*theDistance.Y));
                            if distanceMath<=distnceCloset then
                                distnceCloset=distanceMath;
                                closestActor=actor;
                            end
                        end
                    end
                end
            end
        end
    end
    return closestActor;
end

function findClosestTargetAiNeutral(searchActor,actorTypes)
    closestActor=nil
    distnceCloset=250000;

    local actors=Neutral.GetActorsByTypes(actorTypes);
    for rr,actor in ipairs(actors) do
        theDistance=actor.Location-searchActor.Location;
        distanceMath=math.sqrt((theDistance.X*theDistance.X)+(theDistance.Y*theDistance.Y));
        if distanceMath<=distnceCloset then
            distnceCloset=distanceMath;
            closestActor=actor;
        end
    end
    return closestActor;
end

actorToTargetAi={"agun","silo","hpad","weap","oilb","fcom","hosp","miss","bio","afld.ukraine","afld","powr","apwr","stek","barr","kenn","proc","tent","fix","dome","mslo","gap","iron","sam","atek","fact"}
actorToTargetNeutral={"ftur","gun","tsla","agun","pbox","hbox","silo","hpad","weap","oilb","fcom","hosp","miss","bio","afld.ukraine","afld","powr","apwr","stek","barr","kenn","proc","tent","fix","dome","mslo","gap","iron","sam","atek","fact"}

function sendEngineerNextTarget(u)
    local unit=u
    Trigger.AfterDelay(DateTime.Seconds(1),function()
        if not unit.IsDead then
            --actorToTarget = {"embsy","adept","mtsla","pris","pbox","ioncan", "silo", "afld.ukraine", "hpad", "weap", "htur", "oilb","fcom","hosp","miss","bio","fact","afld","powr","apwr","stek","barr","kenn","proc","tent","fix","dome","mslo","gap","spen","syrd","iron","pdox","agun","sam","atek","fact" }

            --local unitToTarget = findClosestTargetAiNeutral(unit,actorToTarget)
            local unitToTarget
            if Utils.RandomInteger(1,3)==1 then
                unitToTarget=findClosestTargetAi(unit,actorToTargetAi)
                if unitToTarget~=nil then
                    --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                    unit.Stop()
                    unit.Move(unitToTarget.Location)
                    unit.Capture(unitToTarget)
                else
                    unitToTarget=findClosestTargetAiNeutral(unit,actorToTargetNeutral)
                    if unitToTarget~=nil then
                        --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                        unit.Stop()
                        unit.Move(unitToTarget.Location)
                        unit.Capture(unitToTarget)
                    end
                end
            else

                unitToTarget=findClosestTargetAiNeutral(unit,actorToTargetNeutral)
                if unitToTarget~=nil then
                    --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                    unit.Stop()
                    unit.Move(unitToTarget.Location)
                    unit.Capture(unitToTarget)
                else
                    unitToTarget=findClosestTargetAi(unit,actorToTargetAi)
                    if unitToTarget~=nil then
                        --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                        unit.Stop()
                        unit.Move(unitToTarget.Location)
                        unit.Capture(unitToTarget)
                    end
                end
            end
        end
    end)
end

--send engineers to cap middle
function sendEngineers()
    --actorToTarget = {"embsy","adept","mtsla","pris","pbox","ioncan", "silo", "afld.ukraine", "hpad", "weap", "htur", "oilb","fcom","hosp","miss","bio","fact","afld","powr","apwr","stek","barr","kenn","proc","tent","fix","dome","mslo","gap","spen","syrd","iron","pdox","agun","sam","atek","fact" }
    for z,thePlayer in ipairs(AIPlayers) do
        local engineers=thePlayer.GetActorsByType("e6");
        Utils.Do(engineers,function(unit)

            local unitToTarget
            if Utils.RandomInteger(1,3)==1 then
                unitToTarget=findClosestTargetAi(unit,actorToTargetAi)
                if unitToTarget~=nil then
                    --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                    --Media.DisplayMessage("RandomInteger: 1 "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                    unit.Stop()
                    unit.Move(unitToTarget.Location)
                    unit.Capture(unitToTarget)
                    trigger(unit,unitToTarget)
                else
                    unitToTarget=findClosestTargetAiNeutral(unit,actorToTargetNeutral)
                    if unitToTarget~=nil then
                        --Media.DisplayMessage("RandomInteger: 1 "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                        --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                        unit.Stop()
                        unit.Move(unitToTarget.Location)
                        unit.Capture(unitToTarget)
                        trigger(unit,unitToTarget)
                    end
                end
            else
                unitToTarget=findClosestTargetAiNeutral(unit,actorToTargetNeutral)
                if unitToTarget~=nil then
                    --Media.DisplayMessage("RandomInteger: 2 "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                    --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                    unit.Stop()
                    unit.Move(unitToTarget.Location)
                    unit.Capture(unitToTarget)
                    trigger(unit,unitToTarget)
                else
                    unitToTarget=findClosestTargetAi(unit,actorToTargetAi)
                    if unitToTarget~=nil then
                        --Media.DisplayMessage("RandomInteger: 2 "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                        --Media.DisplayMessage("CAPTURE: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
                        unit.Stop()
                        unit.Move(unitToTarget.Location)
                        unit.Capture(unitToTarget)
                        trigger(unit,unitToTarget)
                    end
                end
            end

        end)
    end
end

function trigger(u,uT)
    local unit=u
    local unitToTarget=uT
    --Trigger.OnObjectiveCompleted(unit, function(p, id)
    --if not p.IsDead then
    --Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed")
    --end
    --end)
    Trigger.OnCapture(unitToTarget,function()
        if not unit.IsDead then
            --Media.DisplayMessage("CAPTURED: Type: "..unit.Type.." Loc: "..unit.Location.X..","..unit.Location.Y , "Mission", HSLColor.Red);
            --Media.DisplayMessage("CAPTURED: Type: "..unitToTarget.Type.." Loc: "..unitToTarget.Location.X..","..unitToTarget.Location.Y , "Mission", HSLColor.Red);
            sendEngineerNextTarget(unit)
        end
    end)
end

function aiCash()

    if toxic_enabled then
        Trigger.AfterDelay(DateTime.Seconds(10),function()
            for z,thePlayer in ipairs(AIPlayers) do
                if thePlayer.Cash<4000 then
                    thePlayer.Cash=thePlayer.Cash+2000
                end
            end
            aiCash()
        end)
    else
        Trigger.AfterDelay(DateTime.Seconds(20),function()
            for z,thePlayer in ipairs(AIPlayers) do
                if thePlayer.Cash<4000 then
                    thePlayer.Cash=thePlayer.Cash+500
                end
            end
            aiCash()
        end)
    end
end

--Tanks every 60s
function continuousProductionTanks()

    if (difficulty=="noob") then
        continuousDelay=90/ToxicHandicap
    elseif (difficulty=="easy") then
        continuousDelay=74/ToxicHandicap
    elseif (difficulty=="normal") then
        continuousDelay=65/ToxicHandicap
    else
        continuousDelay=45/ToxicHandicap
    end

    createRandomTankPerBuilding((4*HandicapAdjustment))
    Trigger.AfterDelay(DateTime.Seconds(continuousDelay),continuousProductionTanks)
end

--Infantry every 15s
function continuousProductionInfantry()

    if (difficulty=="noob") then
        continuousDelay=30/ToxicHandicap
    elseif (difficulty=="easy") then
        continuousDelay=25/ToxicHandicap
    elseif (difficulty=="normal") then
        continuousDelay=20/ToxicHandicap
    else
        continuousDelay=15/ToxicHandicap
    end

    createRandomInfantryPerBuilding((4*HandicapAdjustment))
    Trigger.AfterDelay(DateTime.Seconds(continuousDelay),continuousProductionInfantry)
end

function continuousProduction()
    continuousProductionTanks()
    continuousProductionInfantry()
end

function countMcvs(isPlayer)
    mcvCount=countbuildings("mcv",isPlayer)
    factCount=countbuildings("fact",isPlayer)
    totalMcvs=mcvCount+factCount
    return totalMcvs
end

-- Ultimate AI Functions (Before WorldLoaded) End

a=500 --nuke timer

NuclearStrikes=Map.LobbyOption("NuclearStrikes")

--check option selected
if (NuclearStrikes~="entry_1") then
    if (NuclearStrikes=="entry_2") then
        a=5
    else
        if (NuclearStrikes=="entry_3") then
            a=8
        else
            if (NuclearStrikes=="entry_4") then
                a=12
            else
                a=15
            end
        end
    end
end

rules=function()
    if (Cappoints~="entry_off") then
        if (Cappoints=="entry_1") then
            table.insert(messages,"OBJECTIVE: Capture the Communications Centre with an engineer and hold for timer amount")
            -- Media.DisplayMessage ("OBJECTIVE: Capture the Communications Centre with an engineer and hold for timer amount  ", "Mission", HSLColor.Red)
        else
            table.insert(messages,"OBJECTIVE: Capture all the Communications Centres with an engineer and hold for timer amount")
            -- Media.DisplayMessage ("OBJECTIVE: Capture all the Communications Centres with an engineer and hold for timer amount  ", "Mission", HSLColor.Red)
        end
    end
    if (NuclearStrikes~="entry_1") then
        Beaconmiddle()
        if (Cappoints~="entry_off") then
            table.insert(messages,"WARNING: Nuclear strike mode enabled, middle area will be nuked every 5-15 minutes")
            -- Media.DisplayMessage ("WARNING: Nuclear strike mode enabled, middle area will be nuked every 5-15 minutes", "Mission", HSLColor.Red)

        else
            table.insert(messages,"WARNING: Nuclear strike mode enabled, middle area will be nuked every 5-15 minutes")
            -- Media.DisplayMessage ("WARNING: Nuclear strike mode enabled, middle area will be nuked every 5-15 minutes", "Mission", HSLColor.Red)
        end
        Trigger.AfterDelay(DateTime.Seconds(5),function()
            nukemid()
        end)
    end
end

prepandfire=function()
    if (Nuker.HasProperty("ActivateNukePower")) then
        Media.DisplayMessage ("WARNING: Abomb preparing to launch in the middle","Mission",HSLColor.Red)
        Media.PlaySpeechNotification(USSR,"AbombPrepping")
        Trigger.AfterDelay(DateTime.Seconds(30),function()
            nukemid()
        end)
    end
end

delayedlaunch=function()
    Trigger.AfterDelay(DateTime.Minutes(a),function()
        prepandfire()
    end)
end

nukemid=function()
    Media.PlaySpeechNotification(USSR,"AbombLaunchDetected")
    --Middle Area
    Nuker.ActivateNukePower(CPos.New(57,55))
    Nuker.ActivateNukePower(CPos.New(65,55))
    Nuker.ActivateNukePower(CPos.New(73,55))

    Nuker.ActivateNukePower(CPos.New(57,73))
    Nuker.ActivateNukePower(CPos.New(65,73))
    Nuker.ActivateNukePower(CPos.New(73,73))
    Nuker.ActivateNukePower(CPos.New(48,60))
    Nuker.ActivateNukePower(CPos.New(48,68))

    Nuker.ActivateNukePower(CPos.New(80,60))
    Nuker.ActivateNukePower(CPos.New(80,68))
    --[[ Left Side ]]
    Nuker.ActivateNukePower(CPos.New(7,64))
    --[[ Right Side ]]
    Nuker.ActivateNukePower(CPos.New(123,64))
    --delayedparabombs()
    delayedlaunch()
end

--delayedtroopers=function()
--    Trigger.AfterDelay(DateTime.Seconds(15),function()
--
--        --Media.DisplayMessage ("Troops incoming", "Mission", HSLColor.Red)
--
--        ShockDrop.TargetParatroopers(SHOCKER1.CenterPosition,Angle.New(300))
--        ShockDrop2.TargetParatroopers(SHOCKER2.CenterPosition,Angle.New(300))
--        ShockDrop3.TargetParatroopers(SHOCKER3.CenterPosition,Angle.New(800))
--        ShockDrop4.TargetParatroopers(SHOCKER4.CenterPosition,Angle.New(800))
--
--    end)
--end

function tablelength(T)
    local count=0
    for _ in pairs(T) do count=count+1 end
return count
end

function toxicPlayersCheck()
    return Player.GetPlayers(function(player)
        return true
    end);
end

function setToxic()
    toxiccheck=1
    Utils.Do(toxicPlayersCheck(),function(thesePlayers)
        if toxiccheck==1 then
            if thesePlayers.HasPrerequisites({"toxic_enabled"}) then
                toxic_enabled=1
                -- Media.DisplayMessage ("Toxic Enabled", "Mission", HSLColor.Red)
                toxiccheck=2
            end
        end
    end)
end

WorldLoaded=function()
    doomsdayenabled=0
    Neutral=Player.GetPlayer("Neutral")
    Creeps=Player.GetPlayer("Creeps")
    Cappoints=Map.LobbyOption("Cappoints")
    NuclearStrikes=Map.LobbyOption("NuclearStrikes")
    toxic_enabled=0
    enablechecking=0
    playersingame={"Multi0","Multi1","Multi2","Multi3","Multi4","Multi5","Multi6","Multi7","Multi8"} -- Table of Potential Players
    actorstoupdate={"fact","weap","tent","barr","hpad","afld","afld.ukraine","kenn","spen","syrd"}
    messages={}
    messagesloop={}

    setToxic()

    ----START OF AI SETUP CODE After setToxic() ---

    AllPlayersIncludingCreeps=thePlayersAndCreeps();
    AllPlayers=thePlayers();
    AIPlayers=theUltimateBots();
    UltimateBotsCount=#theUltimateBots();
    AllBots=theBots();
    HumanPlayers=theHumans();
    HandicapAdjustment=#theHumans()/4
    HumansCount=#theHumans()
    ToxicHandicap=1

    --createwarriorant = "warriorant"
    --createfireant = "fireant"
    --creategiantant = "ant"

    tierEngineers={"e6","e6","e6","e6"}
    tierThief={"thf","thf","thf","thf"}
    tierSpy={"spy","spy","spy","spy"}
    tier1Tanks={"jeep","apc","1tnk","ftrk"}
    tier2Tanks={"v2rl","2tnk","arty","mgg","mrj","ttnk"}
    tier3Tanks={"3tnk","mrj","ctnk","stnk"}
    tier4Tanks={"4tnk","mrj","dtrk","ctnk","stnk"}


    tier0infantry={"e1"}
    tier1infantry={"e1","medi","dog","e1","e2","e3","e3r1","e4","mech","gnrl","shok","ant"}
    tier2infantry={"spy","thf","fireant"}
    tier3infantry={"e7","sniper","warriorant"}
    tierMcv={"mcv"}

    if HandicapAdjustment==0 then
        HandicapAdjustment=1
    end

    if toxic_enabled==1 then
        ToxicHandicap=HandicapAdjustment*2
    end

    ----END OF AI SETUP CODE After setToxic() ---

    playersingamecount=tablelength(playersingame)
    actorstoupdatecount=tablelength(actorstoupdate)

    --Media.DisplayMessage ("Total Players is " .. playersingame2, "Mission", HSLColor.Red)

    activeplayers={} -- Table for Active Players
    activeplayername={} -- Table for Active Players
    z=1
    for i=playersingamecount,1,-1 do

        playername=playersingame[i]

        if (Player.GetPlayer(playername)~=nil) then
            playerinfo=Player.GetPlayer(playername)
            activeplayers[z]=Player.GetPlayer(playername)
            --Media.DisplayMessage (playerinfo.InternalName, "Mission", HSLColor.Red)
            --activeplayername[i] = playername
            z=z+1
            if playerinfo.HasPrerequisites({"toxic_enabled"}) then
                toxic_enabled=1
            end
            i=i+1
            --message = playername .. " is here"
        end

        --Media.DisplayMessage ("Player  " .. message, "Mission", HSLColor.Red)
    end

    --activeplayerscount = tablelength(activeplayers) --Table of players currently in the game

    activeplayerscount=function()
        return tablelength(activeplayers)
    end

    --Media.DisplayMessage ("Active Players  " .. activeplayerscount(), "Mission", HSLColor.Red) --display total of players

    Beaconmiddle=function()
        Trigger.AfterDelay(DateTime.Seconds(5),function()
            Media.PlaySoundNotification(USSR,"Beacon")
            for i=activeplayerscount(),1,-1 do
                playeractive=activeplayers[i]
                playername=playeractive.InternalName
                Beacon.New(playeractive,MIDFOREST.CenterPosition,500)
                Radar.Ping(playeractive,MIDFOREST.CenterPosition,HSLColor.Aqua,500)
            end
        end)
    end

    Spawnspyplanemiddle=function()
        for i=activeplayerscount(),1,-1 do
            playeractive=activeplayers[i]
            playername=playeractive.InternalName
            spyplanemiddle1=Actor.Create(unittocreatespyplane1,true,{Owner=playeractive,Location=spymiddle.Location})
            spyplanemiddle1.Destroy()
        end
    end

    Spawnspyplanetemp=function()
        for i=activeplayerscount(),1,-1 do
            playeractive=activeplayers[i]
            playername=playeractive.InternalName
            spyplanemiddle2=Actor.Create(unittocreatespyplane1,true,{Owner=playeractive,Location=spymiddle.Location})
            tempspyplane1=Actor.Create(unittocreatespyplane1,true,{Owner=playeractive,Location=COMMLEFT.Location})
            tempspyplane2=Actor.Create(unittocreatespyplane1,true,{Owner=playeractive,Location=COMMRIGHT.Location})
            tempspyplane3=Actor.Create(unittocreatespyplane1,true,{Owner=playeractive,Location=BioUp1.Location})
            tempspyplane4=Actor.Create(unittocreatespyplane1,true,{Owner=playeractive,Location=BioUp2.Location})
            tempspyplane5=Actor.Create(unittocreatespyplane1,true,{Owner=playeractive,Location=BioDown1.Location})
            tempspyplane6=Actor.Create(unittocreatespyplane1,true,{Owner=playeractive,Location=BioDown2.Location})
            spyplanemiddle2.Destroy()
            tempspyplane1.Destroy()
            tempspyplane2.Destroy()
            tempspyplane3.Destroy()
            tempspyplane4.Destroy()
            tempspyplane5.Destroy()
            tempspyplane6.Destroy()
        end
    end

    Nuker=Actor.Create("nuker",false,{Owner=Creeps})
--    ShockDrop=Actor.Create("shockdrop",false,{Owner=Creeps})
--    ShockDrop2=Actor.Create("shockdrop",false,{Owner=Creeps})
--    ShockDrop3=Actor.Create("shockdrop",false,{Owner=Creeps})
--    ShockDrop4=Actor.Create("shockdrop",false,{Owner=Creeps})

    unittocreate="miss"
    unittocreate2="gmine"
    unittocreate3="POWR"
    unittocreatebio="bio"
    unittocreatetree1="tc05"
    unittocreatetree2="tc02"
    unittocreatespyplane1="camera.spyplane"
    createwarriorant="warriorant"
    createfireant="fireant"
    creategiantant="ant"

    --Spawnspyplanemiddle = function()
    --for i = activeplayerscount,1,-1 do
    ----playeractive = activeplayers[i]
    ----playername = activeplayername[i]
    ----spy0 = Actor.Create(unittocreatespyplane1, true, { Owner = playeractive, Location = spymiddle.Location})
    --
    --end
    --end

    -- Middle Only
    Spawncom1=function()
        comcentre1=Actor.Create(unittocreate,true,{Owner=Neutral,Location=COMMCENTER.Location})
    end

    -- 2 x Middle
    Spawncom2=function()
        comtopmid=Actor.Create(unittocreate,true,{Owner=Neutral,Location=comtopmid.Location})
        combotmid=Actor.Create(unittocreate,true,{Owner=Neutral,Location=combotmid.Location})
    end

    --middle + sides
    Spawncom3=function()
        comcentre1=Actor.Create(unittocreate,true,{Owner=Neutral,Location=COMMLEFT.Location})
        comcentre2=Actor.Create(unittocreate,true,{Owner=Neutral,Location=COMMRIGHT.Location})
        comcentre3=Actor.Create(unittocreate,true,{Owner=Neutral,Location=comtopmid.Location})
        comcentre4=Actor.Create(unittocreate,true,{Owner=Neutral,Location=combotmid.Location})
    end

    -- Sides
    Spawncom4=function()
        comcentre1=Actor.Create(unittocreate,true,{Owner=Neutral,Location=COMMLEFT.Location})
        comcentre2=Actor.Create(unittocreate,true,{Owner=Neutral,Location=COMMRIGHT.Location})
    end

    --trees for middle
    Spawntrees=function()
        tree1=Actor.Create(unittocreatetree1,true,{Owner=Neutral,Location=tc05left.Location})
        tree2=Actor.Create(unittocreatetree1,true,{Owner=Neutral,Location=tc05right.Location})
        tree3=Actor.Create(unittocreatetree2,true,{Owner=Neutral,Location=tc02middle.Location})
    end

    --trees for middle
    Biolabs=function()
        biolab1=Actor.Create(unittocreatebio,true,{Owner=Neutral,Location=BioUp1.Location})
        biolab2=Actor.Create(unittocreatebio,true,{Owner=Neutral,Location=BioUp2.Location})
        biolab3=Actor.Create(unittocreatebio,true,{Owner=Neutral,Location=BioDown1.Location})
        biolab4=Actor.Create(unittocreatebio,true,{Owner=Neutral,Location=BioDown2.Location})

        table.insert(messages,"WARNING: Bio Labs Enabled")
        -- Media.DisplayMessage ("WARNING: Bio Labs Enabled", "Mission", HSLColor.Red)
    end

    Spawnmines=function()
        extramine={}
        actornames={} -- Table for Active Players
        zerocount=0

        for i=311,273,-1 do

            minename="Tmine"..i
            actornames[zerocount]="Tmine"..i
            zerocount=zerocount+1
            -- Media.DisplayMessage (minename, "Mission", HSLColor.Red)
        end

        actornamescount=tablelength(actornames)
        -- actornamescount = "test"
        -- Media.DisplayMessage (actornamescount .. "", "Mission", HSLColor.Red)

        for i=actornamescount,1,-1 do

            actorname=actornames[i]
            if (actorname~=nil) then

                minename2=Map.NamedActor(actorname)
                -- Media.DisplayMessage (actorname .. "", "Mission", HSLColor.Red)
                extramine[i]=Actor.Create(unittocreate2,true,{Owner=Neutral,Location=minename2.Location})

            end
            i=i+1

        end
    end

    Spawnants=function()
        extramine={}
        for i=26,1,-1 do
            antname="Ant"..i
            antactor=Map.NamedActor(antname)

            if i<18 then
                if i<6 then
                    extramine[i]=Actor.Create(createwarriorant,true,{Owner=Creeps,Stance=AttackAnything,Location=antactor.Location})
                else
                    extramine[i]=Actor.Create(creategiantant,true,{Owner=Creeps,Stance=AttackAnything,Location=antactor.Location})
                end
            else
                extramine[i]=Actor.Create(createfireant,true,{Owner=Creeps,Stance=AttackAnything,Location=antactor.Location})
            end
            --Media.DisplayMessage (minename, "Mission", HSLColor.Red)
        end

        table.insert(messages,"Ants have escaped from the Bio Labs!")
        -- Media.DisplayMessage ("Ants have escaped from the Bio Labs!", "Mission", HSLColor.Red)
    end

    --bioenabled = 0
    --if activeplayers[1].HasPrerequisites({"bio_enabled"})
    --then
    --bioenabled = 1
    --Biolabs()
    --Spawnspyplanetemp()
    --
    --if (NuclearStrikes == "entry_1") then
    --Spawnants() -- Not working right now
    --end
    --end

    --if (Cappoints == "entry_off") then
    --Spawntrees()
    --else
    --
    --
    --if (Cappoints == "entry_1") then -- 1 x middle
    --Spawncom1()
    ----Spawnspyplanemiddle()
    --end
    --
    --if (Cappoints == "entry_1a") then -- 2 x middle
    --Spawncom2()
    --Spawntrees()
    --Spawnspyplanetemp()
    ----Spawnspyplanemiddle()
    --end
    --
    --if (Cappoints == "entry_2") then --middle + sides
    --Spawncom3()
    ----Spawnspyplanemiddle()
    --Spawnspyplanetemp()
    --end
    --
    --if (Cappoints == "entry_3") then --sides
    --Spawncom4()
    --Spawntrees()
    --Spawnspyplanetemp()
    --end
    --end

    --count buildings

    countbuildings=function(buildingtype,theplayer)
        local sams=theplayer.GetActorsByType(buildingtype)
        return #sams
    end

    debugactive=function()
        for i=activeplayerscount(),1,-1 do
            playeractive=activeplayers[i]
            playername=playeractive.InternalName
            --Media.DisplayMessage (playername, "Mission", HSLColor.Red)
        end
    end


    BuildingsCheck={}
    loop=0

    checkbuildings2=function()
        for i=activeplayerscount(),1,-1 do
            mcvscount=0
            playeractive=activeplayers[i]
            playername=playeractive.InternalName
            k=playeractive.Color

            for y=actorstoupdatecount,1,-1 do
                buildingtype=actorstoupdate[y]

                --Media.DisplayMessage (playername, "Mission", HSLColor.Red)

                factorycount=#playeractive.GetActorsByType(buildingtype)
                --factorycount = countbuildings(buildingtype, playeractive)

                if (factorycount>0) then
                    if (buildingtype=='weap') then
                        if (factorycount<NumReductionVehicle) then
                            --if (factorycount == 1) then
                            --display_color = HSLColor.Green
                            --else
                            --display_color = HSLColor.Orange
                            --end
                            Reduction=ReductionVehicle[factorycount]
                        else
                            Reduction=ReductionVehicle[NumReductionVehicle]
                            --display_color = HSLColor.Red
                        end
                    else
                        if (factorycount<NumReductionWar) then
                            --if (factorycount == 1) then
                            --display_color = HSLColor.Green
                            --else
                            --display_color = HSLColor.Orange
                            --end
                            Reduction=ReductionWar[factorycount]
                        else
                            Reduction=ReductionWar[NumReductionWar]
                            --display_color = HSLColor.Red
                        end
                    end
                    conditonname=buildingtype..Reduction
                    playeractive.GrantCondition(conditonname,1)
                    --if (loop==0) then
                else
                end
                if (show_toxidicy==1) then
                    if (BuildingsCheck[i*1000+y]~=factorycount) then
                        BuildingsCheck[i*1000+y]=factorycount
                        if (loop>100) then
                            if (factorycount~=0) then
                                Media.DisplayMessage ("#"..buildingtype.."="..factorycount.."  Build Speed="..Reduction.."%",playername,playeractive.Color)
                            else
                                Media.DisplayMessage ("#"..buildingtype.."="..factorycount,playername,playeractive.Color)
                            end
                        end
                    end
                end
                loop=loop+1
            end
        end
        --Media.DisplayMessage ("Total loops: "..totalloop.."  Loops: "..loop, "Mission", HSLColor.Red)
    end

    --toxicrules = Player.HasPrerequisites("toxic_enabled")
    --toxicrules = Map.LobbyOption("toxicrules")

    --if (NuclearStrikes ~= "entry_1") then
    --delayedtroopers()
    --if bioenabled == 1 then
    --Trigger.AfterDelay(DateTime.Seconds(30), function()
    --Spawnants()
    --end)
    --end
    --else
    --if (Cappoints ~= "entry_off") then
    --delayedtroopers()
    --end
    --end

    --end war fact check

    ----START OF AI REFINFORCEMENT CODE ---

    if UltimateBotsCount>0 then

        -- MCVs on repeat
        Trigger.AfterDelay(DateTime.Seconds(30),function()
            if (difficulty=="noob") then
                timerDelay=70
            elseif (difficulty=="easy") then
                timerDelay=50
            elseif (difficulty=="normal") then
                timerDelay=40
            else
                timerDelay=30
            end
            sendRepeatWave(tierMcv,1,timerDelay/HandicapAdjustment)
        end)

        --One off attacks
        Trigger.AfterDelay(DateTime.Seconds(110),function()
            Media.DisplayMessage("Enemy Troops Inbound","Mission",HSLColor.Red)
            if (difficulty=="noob") then
                sendAttackWave(tier0infantry,(15*HandicapAdjustment)*difficultyHandicap)
            elseif (difficulty=="easy") then
                sendAttackWave(tier0infantry,(20*HandicapAdjustment)*difficultyHandicap)
            elseif (difficulty=="normal") then
                sendAttackWave(tier0infantry,(30*HandicapAdjustment)*difficultyHandicap)
            else
                sendAttackWave(tier0infantry,(50*HandicapAdjustment)*difficultyHandicap)
            end
        end)

        Trigger.AfterDelay(DateTime.Seconds(220),function()
            Media.DisplayMessage("Enemy Troops Inbound","Mission",HSLColor.Red)
            if (difficulty=="noob") then
                sendAttackWave(tier0infantry,(10*HandicapAdjustment)*difficultyHandicap)
            elseif (difficulty=="easy") then
                sendAttackWave(tier0infantry,(15*HandicapAdjustment)*difficultyHandicap)
            elseif (difficulty=="normal") then
                sendAttackWave(tier0infantry,(20*HandicapAdjustment)*difficultyHandicap)
            else
                sendAttackWave(tier0infantry,(25*HandicapAdjustment)*difficultyHandicap)
            end
        end)

        Trigger.AfterDelay(DateTime.Seconds(330),function()
            Media.DisplayMessage("Enemy Troops Inbound","Mission",HSLColor.Red)
            if (difficulty=="easy" or difficulty=="noob") then
                sendAttackWave(tier0infantry,(60*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier1Tanks,(8*HandicapAdjustment)*difficultyHandicap)
            elseif (difficulty=="normal") then
                sendAttackWave(tier0infantry,(60*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier1Tanks,(8*HandicapAdjustment)*difficultyHandicap)
            else
                sendAttackWave(tier1infantry,(60*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2Tanks,(8*HandicapAdjustment)*difficultyHandicap)
            end
        end)

        Trigger.AfterDelay(DateTime.Seconds(420),function()
            --Start of Tank Waves
            Media.DisplayMessage("Enemy Tanks Inbound","Mission",HSLColor.Red)
            if (difficulty=="easy" or difficulty=="noob") then
                --Infantry
                sendAttackWave(tier1infantry,(80*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier1Tanks,(8*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2Tanks,(8*HandicapAdjustment)*difficultyHandicap)
            elseif (difficulty=="normal") then
                --Infantry
                sendAttackWave(tier1infantry,(90*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier1Tanks,(8*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2Tanks,(8*HandicapAdjustment)*difficultyHandicap)
            else
                --Infantry
                sendAttackWave(tier1infantry,(100*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2Tanks,(10*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier3Tanks,(10*HandicapAdjustment)*difficultyHandicap)
            end
            -- sendAttackWave(tier4Tanks,2*HandicapAdjustment)*difficultyHandicap)
        end)

        Trigger.AfterDelay(DateTime.Seconds(540),function()
            Media.DisplayMessage("Enemy Tanks Inbound","Mission",HSLColor.Red)
            if (difficulty=="easy" or difficulty=="noob") then
                --Infantry
                sendAttackWave(tier1infantry,(100*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2infantry,(4*HandicapAdjustment)*difficultyHandicap)
                --Tanks
                sendAttackWave(tier1Tanks,(6*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2Tanks,(6*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier3Tanks,(4*HandicapAdjustment)*difficultyHandicap)
                --sendAttackWave(tier4Tanks,(2*HandicapAdjustment)*difficultyHandicap)
            elseif (difficulty=="normal") then
                --Infantry
                sendAttackWave(tier1infantry,(100*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2infantry,(4*HandicapAdjustment)*difficultyHandicap)
                --Tanks
                sendAttackWave(tier1Tanks,(8*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2Tanks,(8*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier3Tanks,(6*HandicapAdjustment)*difficultyHandicap)
                --sendAttackWave(tier4Tanks,(2*HandicapAdjustment)*difficultyHandicap)
            else
                --Infantry
                sendAttackWave(tier1infantry,(120*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2infantry,(8*HandicapAdjustment)*difficultyHandicap)
                --Tanks
                sendAttackWave(tier1Tanks,(10*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier2Tanks,(8*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier3Tanks,(6*HandicapAdjustment)*difficultyHandicap)
                sendAttackWave(tier4Tanks,(4*HandicapAdjustment)*difficultyHandicap)
            end
        end)

        Trigger.AfterDelay(DateTime.Seconds(2),function()
            aiCash() -- Stream of cash for AI
            createHarv() -- If ran out of money then create Harvester
            createEngineers()
        end)

        doomsdayCountdown=600
        if (difficulty=="noob") then
            continuousCountdown=720
        elseif (difficulty=="easy") then
            continuousCountdown=600
        elseif (difficulty=="normal") then
            continuousCountdown=600
        elseif (difficulty=="extreme") then
            continuousCountdown=480
            doomsdayCountdown=480
        else
            doomsdayCountdown=480
            continuousCountdown=480
        end

        if toxic_enabled==1 then
            continuousCountdown=continuousCountdown*0.6
            doomsdayCountdown=doomsdayCountdown*0.6
        end

        Trigger.AfterDelay(DateTime.Seconds(continuousCountdown),function()
            Media.DisplayMessage("WARNING: Ultimate AI has ramped up production!","Mission",HSLColor.Red)
            continuousProduction()
            Trigger.AfterDelay(DateTime.Seconds(doomsdayCountdown),function()
                UserInterface.SetMissionText("TOXIC MODE ENABLED - DOOMSDAY ACTIVATED",HSLColor.Red)
                Media.DisplayMessage("WARNING: Doomsday Mode Has Been Activated, AI has MAXED production, you will not survive!","Mission",HSLColor.Red)
                doomsdayenabled=1
                HandicapAdjustment=HandicapAdjustment*1.25
            end)
        end)

        setDifficulty()
    end

    ----END OF AI REFINFORCEMENT CODE ---

    rules()

    --Media.DisplayMessage( "toxicrules: "..toxic_enabled, "Mission", HSLColor.Red)
    if toxic_enabled==1 then
        if FactoryWar=="Scheme1" then
            SchemeWar={"OFF (RA Default)","100,86,75,67,60,55,50"}
            ReductionWar={100,86,75,67,60,55,50}
        elseif FactoryWar=="Scheme2" then
            SchemeWar={"Poops Default","100,70,50,40,20,10,10,5"}
            ReductionWar={100,70,50,40,20,10,10,5}
        elseif FactoryWar=="Scheme3" then
            SchemeWar={"Ultimate Default","100,75,50,40,30,20,15,10,10,7,7,7,5,5,5,4,2,2,2,2,2,2,2,2,1"}
            ReductionWar={100,75,50,40,30,20,15,10,10,7,7,7,5,5,5,4,2,2,2,2,2,2,2,2,1}
        elseif FactoryWar=="Scheme4" then
            SchemeWar={"Zypres","100,90,80,70,60,50,40,35,30,25,20,16,13,12,11,10,9,8,7,6,5,4,3,2,1"}
            ReductionWar={100,90,80,70,60,50,40,35,30,25,20,16,13,12,11,10,9,8,7,6,5,4,3,2,1}
        end
        if FactoryVehicle=="Scheme1" then
            SchemeVehicle={"OFF (RA Default)","100,75,60,50"}
            ReductionVehicle={100,75,60,50}
        elseif FactoryVehicle=="Scheme2" then
            SchemeVehicle={"Poops Default","100,70,50,40,20,10,10,5"}
            ReductionVehicle={100,70,50,40,20,10,10,5}
        elseif FactoryVehicle=="Scheme3" then
            SchemeVehicle={"Ultimate Default","100,75,50,40,30,20,15,10,10,7,7,7,5,5,5,4,2,2,2,2,2,2,2,2,1"}
            ReductionVehicle={100,75,50,40,30,20,15,10,10,7,7,7,5,5,5,4,2,2,2,2,2,2,2,2,1}
        elseif FactoryVehicle=="Scheme4" then
            SchemeVehicle={"Zypres","100,90,80,70,60,50,40,35,30,25,20,16,13,12,11,10,9,8,7,6,5,4,3,2,1"}
            ReductionVehicle={100,90,80,70,60,50,40,35,30,25,20,16,13,12,11,10,9,8,7,6,5,4,3,2,1}
        end
        NumReductionWar=tablelength(ReductionWar)
        NumReductionVehicle=tablelength(ReductionVehicle)
        if FactoryVehicle~=nil then
            Media.DisplayMessage("FactoryVehicle Types: "..SchemeVehicle[1],"Mission",HSLColor.Red)
        else
            Media.DisplayMessage("FactoryVehicle Types: nil","Mission",HSLColor.Red)
        end
        if FactoryWar~=nil then
            Media.DisplayMessage("FactoryWar Types: "..SchemeWar[1],"Mission",HSLColor.Red)
        else
            Media.DisplayMessage("FactoryWar Types: nil","Mission",HSLColor.Red)
        end
        UserInterface.SetMissionText("TOXIC MODE ENABLED",HSLColor.Red)
        if SchemeWar[2]==SchemeVehicle[2] then
            table.insert(messages,"WARNING: Toxic Enabled: "..SchemeWar[1].."\nWar/Vehicles: "..SchemeWar[2].."\nMore Buildings = Faster Build Speed ("..tablelength(ReductionWar).." for Maximum Speed)")
            table.insert(messagesloop,"REMINDER: Toxic Enabled: "..SchemeWar[1].."\nWar/Vehicles: "..SchemeWar[2].."\nMore Buildings = Faster Build Speed ("..tablelength(ReductionWar).." for Maximum Speed)")
            --table.insert(messagesloop, "REMINDER: Toxic Rules ("..tablelength(ReductionWar) .." of each building for Maximum Speed)")
        else
            table.insert(messages,"WARNING: Toxic Enabled: "..SchemeWar[1].."\nWar:       "..SchemeWar[2].."\nVehicles:"..SchemeVehicle[2].."\nMore Buildings = Faster Build Speed ("..tablelength(ReductionWar).."/"..tablelength(ReductionVehicle).." for Maximum Speed)")
            table.insert(messages,"REMINDER: Toxic Enabled: "..SchemeWar[1].."\nWar:       "..SchemeWar[2].."\nVehicles:"..SchemeVehicle[2].."\nMore Buildings = Faster Build Speed ("..tablelength(ReductionWar).."/"..tablelength(ReductionVehicle).." for Maximum Speed)")
            --table.insert(messagesloop, "REMINDER: Toxic Rules ("..tablelength(ReductionWar).."/"..tablelength(ReductionVehicle).." of each building for Maximum Speed)")
        end
        enablechecking=1
    else
        table.insert(messages,"Standard Rules apply for maximum build speed (4 War/7 other buildings)")
    end

    --if toxiclevel ~= nil then
    --Media.DisplayMessage( "Toxicity Level: "..toxiclevel, "Mission", HSLColor.Red)
    --else
    --Media.DisplayMessage( "Toxicity Level: nil", "Mission", HSLColor.Red)
    --end

    show_toxidicy=0
    if showtoxidicy~=nil then
        if (showtoxidicy=='show_on') then
            Media.DisplayMessage("Show Build Time Speed Reduction: ON","Mission",HSLColor.Red)
            show_toxidicy=1
        else
            Media.DisplayMessage("Show Build Time Speed Reduction: OFF","Mission",HSLColor.Red)
        end
    else
        --Media.DisplayMessage( "showtoxidicy: nil", "Mission", HSLColor.Red)
    end

    --
    --if tanktypes ~= nil then
    --Media.DisplayMessage( "Tank Types: "..tanktypes, "Mission", HSLColor.Red)
    --else
    --Media.DisplayMessage( "Tank Types: nil", "Mission", HSLColor.Red)
    --end
    --
    --if infantrytypes ~= nil then
    --Media.DisplayMessage( "infantrytypes Types: "..infantrytypes, "Mission", HSLColor.Red)
    --else
    --Media.DisplayMessage( "infantrytypes Types: nil", "Mission", HSLColor.Red)
    --end
    --
    --Trigger.AfterDelay(DateTime.Seconds(2), function()
    --setupRefs()
    ---- Media.DisplayMessage( "Setup Refs", "Mission", HSLColor.Red)
    ----if (difficulty == "noob") then
    --removeactors(getAllActors("gap.defend"))
    --end
    --end)
    --read the messages

    readmessages()

    loopcounter=1
    Trigger.AfterDelay(5000,readmessagesloop)
    if UltimateBotsCount>0 then
        Trigger.AfterDelay(DateTime.Seconds(2),function()
            AdjustmentLevel=difficultyHandicap*HandicapAdjustment*toxicAdjustment
            Media.DisplayMessage("AI Difficulty Level "..AdjustmentLevel.." (Adjusted For Players/Difficulty)","Mission",HSLColor.Red)
        end)
    end

    --if UltimateBotsCount > 0 then
    --Trigger.AfterDelay(DateTime.Seconds(2), function()
    --AdjustmentLevel = difficultyHandicap*HandicapAdjustment*toxicAdjustment
    --table.insert(messages, "AI Difficulty Level "..AdjustmentLevel.." (Adjusted For Players/Difficulty)")
    --end)
    --end

    --local init_teleport
    --local TeleportNameIn
    --local TeleportActorIn
    --local TeleportNameOut
    --local TeleportActorOut
    --local Tile
    --local AreaSize
    --local Tile
    --local TeleportActorDiffX
    --local TeleportActorDiffY
    actor_speed = {}
    actor_speed["1tnk"]             = 8
    actor_speed["2tnk"]             = 10
    actor_speed["3tnk"]             = 12
    actor_speed["4tnk"]             = 16
    actor_speed["ant"]              = 4
    actor_speed["apc"]              = 6
    actor_speed["arty"]             = 8
    actor_speed["ctnk"]             = 8
    actor_speed["dog"]              = 3
    actor_speed["dtrk"]             = 6
    actor_speed["e1"]               = 2
    actor_speed["e2"]               = 3
    actor_speed["e3"]               = 3
    actor_speed["e3r1"]             = 3
    actor_speed["e4"]               = 3
    actor_speed["e6"]               = 3
    actor_speed["e7"]               = 3
    actor_speed["fireant"]          = 4
    actor_speed["ftrk"]             = 6
    actor_speed["gnrl"]             = 3
    actor_speed["harv"]             = 10
    actor_speed["jeep"]             = 6
    actor_speed["mcv"]              = 20
    actor_speed["mech"]             = 3
    actor_speed["medi"]             = 3
    actor_speed["mgg"]              = 6
    actor_speed["mrj"]              = 6
    actor_speed["shok"]             = 3
    actor_speed["sniper"]           = 3
    actor_speed["spy"]              = 3
    actor_speed["stnk"]             = 8
    actor_speed["thf"]              = 3
    actor_speed["ttnk"]             = 8
    actor_speed["v2rl"]             = 8
    actor_speed["warriorant"]       = 4
    actor_speed["zombie"]           = 5
    m_speed=8
    flits_teleport=function(a,m_Teleport,count,speed,m_teleported)
        local m_speed=speed
        local m_count=count
        local m_actor=a
        local m_actorId=tostring(m_actor)
        local m_TeleportNumber=m_Teleport
        --m_teleported=teleported[m_TeleportNumber]
        --Media.DisplayMessage("Count: "..m_count.." Actor: "..m_actorId,"Mission",HSLColor.Blue);
        Trigger.AfterDelay(DateTime.Seconds(0),function()
            if not m_actor.IsDead then
                m_actorId=tostring(m_actor)
                if m_teleported[m_actorId]~=nil then
                    m_teleported[m_actorId] = m_teleported[m_actorId] - 1
                    --Media.DisplayMessage("m_teleported["..m_actorId.."]="..m_teleported[m_actorId],"Mission",HSLColor.Blue);
                    resetter[m_TeleportNumber] = 10
                    if m_teleported[m_actorId] >= 0 then
                        flits_teleport(m_actor,m_TeleportNumber,0, m_speed, m_teleported)
                        return 
                    end
                    --Media.DisplayMessage("Deleting: "..m_actorId.." from list.","Mission",HSLColor.Blue);
                else
                    --Media.DisplayMessage("Not in list: "..m_actorId,"Mission",HSLColor.Blue);
                    return
                end
                --if m_teleported[m_actorId]~=nil then
                --    m_teleported[m_actorId] = nil
                --    --Media.DisplayMessage("Deleting: "..m_actorId.." from list.","Mission",HSLColor.Blue);
                --else
                --    Media.DisplayMessage("Not in list: "..m_actorId,"Mission",HSLColor.Blue);
                --    return
                --end
                --Media.DisplayMessage("Teleporting: "..m_actor.Type.."  ID: "..m_actorId,"Mission",HSLColor.Blue);
                X=m_actor.CenterPosition.X/Tile
                Y=m_actor.CenterPosition.Y/Tile
                --Media.DisplayMessage("Teleporting: "..m_actor.Type.."  from: "..X..","..Y,"Mission",HSLColor.Blue);

                TeleportActorIn     =Teleports_ActorsIn[m_TeleportNumber]           
                TeleportActorIn_BR  =Teleports_ActorsIn_BR[m_TeleportNumber]     
                TeleportActorOut    =Teleports_ActorsOut[m_TeleportNumber]
                TeleportActorDiffX  =Teleports_ActorsDiffX[m_TeleportNumber]
                TeleportActorDiffY  =Teleports_ActorsDiffY[m_TeleportNumber]
                Teleport_SizeX      =Teleports_SizeX[m_TeleportNumber]
                Teleport_SizeY      =Teleports_SizeY[m_TeleportNumber]

                --Next_m_TeleportNumber = (m_TeleportNumber) % 4 + 1
                --NEXT_X = Teleports_ActorsIn[Next_m_TeleportNumber].CenterPosition.X/Tile
                --NEXT_Y = Teleports_ActorsIn[Next_m_TeleportNumber].CenterPosition.Y/Tile

                dir_X=0
                dir_Y=0
                XX=X
                YY=Y
                if m_actor.IsIdle then
                    if TeleportActorDiffX > 0 then
                        dir_X = 1
                        XX=TeleportActorIn.CenterPosition.X/Tile
                        if (X>=TeleportActorIn.CenterPosition.X/Tile - 0.5 and X<=TeleportActorIn.CenterPosition.X/Tile + 0.5 and Y>=TeleportActorIn.CenterPosition.Y/Tile - 0.5 and Y<=TeleportActorIn_BR.CenterPosition.Y/Tile + 0.5) then
                            Xm = X+TeleportActorDiffX  + Teleport_SizeX + 3
                            Ym = Y+TeleportActorDiffY
                            m_actor.Stop()
                            NewP=CPos.New(Xm,Ym)
                            m_actor.Teleport(NewP)
                            NewP=CPos.New(XX,YY)
                            m_actor.Move(NewP)
                            --Media.DisplayMessage("Teleporting "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..X..","..Y.."  TO: "..Xm..","..Ym,"Mission",HSLColor.Blue);
                            --Media.DisplayMessage("Moving      "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..Xm..","..Ym.."  TO: "..XX..","..YY,"Mission",HSLColor.Blue);
                            if m_teleported[m_actorId]~=nil then
                                m_teleported[m_actorId]=nil
                            end
                            return
                        end
                    elseif TeleportActorDiffX < 0 then
                        dir_X = -1
                        XX=TeleportActorIn_BR.CenterPosition.X/Tile
                        if (X>=TeleportActorIn_BR.CenterPosition.X/Tile - 0.5 and X<=TeleportActorIn_BR.CenterPosition.X/Tile + 0.5 and Y>=TeleportActorIn.CenterPosition.Y/Tile - 0.5 and Y<=TeleportActorIn_BR.CenterPosition.Y/Tile + 0.5) then
                            Xm = X+TeleportActorDiffX - Teleport_SizeX - 3
                            Ym = Y+TeleportActorDiffY
                            m_actor.Stop()
                            NewP=CPos.New(Xm,Ym)
                            m_actor.Teleport(NewP)
                            NewP=CPos.New(XX,YY)
                            m_actor.Move(NewP)
                            --Media.DisplayMessage("Teleporting "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..X..","..Y.."  TO: "..Xm..","..Ym,"Mission",HSLColor.Blue);
                            --Media.DisplayMessage("Moving      "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..Xm..","..Ym.."  TO: "..XX..","..YY,"Mission",HSLColor.Blue);
                            if m_teleported[m_actorId]~=nil then
                                m_teleported[m_actorId]=nil
                            end
                            return
                        end
                    else 
                        dir_X = 0
                        XX=X
                    end    
                    if TeleportActorDiffY > 0 then
                        dir_Y = 1
                        YY=TeleportActorIn.CenterPosition.Y/Tile
                        --a=TeleportActorIn.CenterPosition.X/Tile - 0.5
                        --b=TeleportActorIn_BR.CenterPosition.X/Tile + 0.5
                        --c=TeleportActorIn.CenterPosition.Y/Tile - 0.5
                        --d=TeleportActorIn.CenterPosition.Y/Tile + 0.5
                        --Media.DisplayMessage("Area "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..a..","..b.."  TO: "..c..","..d,"Mission",HSLColor.Blue);

                        if (X>=TeleportActorIn.CenterPosition.X/Tile - 0.5 and X<=TeleportActorIn_BR.CenterPosition.X/Tile + 0.5 and Y>=TeleportActorIn.CenterPosition.Y/Tile - 0.5 and Y<=TeleportActorIn.CenterPosition.Y/Tile + 0.5) then
                            Xm = X+TeleportActorDiffX
                            Ym = Y+TeleportActorDiffY  + Teleport_SizeY + 3
                            m_actor.Stop()
                            NewP=CPos.New(Xm,Ym)
                            m_actor.Teleport(NewP)
                            NewP=CPos.New(XX,YY)
                            m_actor.Move(NewP)
                            --Media.DisplayMessage("Teleporting "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..X..","..Y.."  TO: "..Xm..","..Ym,"Mission",HSLColor.Blue);
                            --Media.DisplayMessage("Moving      "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..Xm..","..Ym.."  TO: "..XX..","..YY,"Mission",HSLColor.Blue);
                            if m_teleported[m_actorId]~=nil then
                                m_teleported[m_actorId]=nil
                            end
                            return
                        end
                    elseif TeleportActorDiffY < 0 then
                        dir_Y = -1
                        YY=TeleportActorIn_BR.CenterPosition.Y/Tile
                        if (X>=TeleportActorIn.CenterPosition.X/Tile - 0.5 and X<=TeleportActorIn_BR.CenterPosition.X/Tile + 0.5 and Y>=TeleportActorIn_BR.CenterPosition.Y/Tile - 0.5 and Y<=TeleportActorIn_BR.CenterPosition.Y/Tile + 0.5) then
                            Xm = X+TeleportActorDiffX
                            Ym = Y+TeleportActorDiffY  - Teleport_SizeY  - 3
                            m_actor.Stop()
                            NewP=CPos.New(Xm,Ym)
                            m_actor.Teleport(NewP)
                            NewP=CPos.New(XX,YY)
                            m_actor.Move(NewP)
                            --Media.DisplayMessage("Teleporting "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..X..","..Y.."  TO: "..Xm..","..Ym,"Mission",HSLColor.Blue);
                            --Media.DisplayMessage("Moving      "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..Xm..","..Ym.."  TO: "..XX..","..YY,"Mission",HSLColor.Blue);
                            if m_teleported[m_actorId]~=nil then
                                m_teleported[m_actorId]=nil
                            end
                            return
                        end
                    else 
                        dir_Y = 0
                        YY=Y
                    end    

                    --Media.DisplayMessage("Moving "..m_TeleportNumber..": "..m_actor.Type.."  ID: "..m_actorId.."  FROM: "..X..","..Y.."  TO: "..XX..","..YY,"Mission",HSLColor.Blue);
                
                    --m_actor.Stop()
                    NewP=CPos.New(XX,YY)
                    m_actor.Move(NewP)
                    --if m_teleported[m_actorId]~=nil then
                    --    m_teleported[m_actorId]=nil
                    --end
                    flits_teleport(m_actor,m_TeleportNumber,0, m_speed, m_teleported)
                else
                    --m_actor.Stop()
                    --flits_teleport(m_actor,m_TeleportNumber,0, m_speed, m_teleported)

                    if m_teleported[m_actorId]~=nil then
                        m_teleported[m_actorId]=nil
                    end
                end


            else
                m_actorId=tostring(m_actor)
                --Media.DisplayMessage("Actor ID: "..m_actorId.." is Dead","Mission",HSLColor.Blue);
                --Media.DisplayMessage("Teleporting: "..m_actor.Type.."  ID: "..m_actorId,"Mission",HSLColor.Blue);
                if m_teleported[m_actorId]~=nil then
                    m_teleported[m_actorId]=nil
                end
            end
        end)
    end

    resetter = {}
    teleported={}
    teleported[1]={}
    teleported[2]={}
    teleported[3]={}
    teleported[4]={}
    teleported[5]={}
    teleported[6]={}
    teleported[7]={}
    teleported[8]={}
    Teleports_ActorsIn={}
    Teleports_ActorsIn_BR={}
    Teleports_ActorsOut={}
    Teleports_ActorsDiffX={}
    Teleports_ActorsDiffY={}
    Teleports_SizeX={}
    Teleports_SizeY={}
    TeleportCount={}
    number_time={}
    Tile=WDist.FromCells(1).Length
    AreaSize=WVec.New(Tile*2.5,Tile*2.5,0)
    AreaHalfSize=WVec.New(Tile*0.5,Tile*0.5,0) --EEKS
    --AreaHalfSize=WVec.New(Tile*0.5,-Tile*0.25,0) --EEKS
    --AreaHalfSize=WVec.New(Tile*0.5,Tile*0.5,0)
    check_teleport=function(TeleportNumber)
        --Media.DisplayMessage("Checking teleports.","Mission",HSLColor.Green)

        if not init_teleport then
            init_teleport=1
            for i=1,4,1 do

                number_time[i]=5
                Oke = 1
                Media.DisplayMessage("Init teleport: "..i,"Mission",HSLColor.Green)

                TeleportNameIn="ActorTeleportIn_TL_"..i
                TeleportActorIn=Map.NamedActor(TeleportNameIn)

                TeleportNameIn="ActorTeleportIn_BR_"..i
                TeleportActorIn_BR=Map.NamedActor(TeleportNameIn)

                TeleportNameOut="ActorTeleportOut_TL_"..i
                TeleportActorOut=Map.NamedActor(TeleportNameOut)

                if TeleportActorIn~=nil and TeleportActorOut~=nil and TeleportActorIn_BR~=nil then
                    
                    x_i  = TeleportActorIn.CenterPosition.X/Tile        - 0.5
                    y_i  = TeleportActorIn.CenterPosition.Y/Tile        - 0.5
                    x_BR = TeleportActorIn_BR.CenterPosition.X/Tile+1   + 0.5
                    y_BR = TeleportActorIn_BR.CenterPosition.Y/Tile+1   + 0.5
                    x_o  = TeleportActorOut.CenterPosition.X/Tile       - 0.5
                    y_o  = TeleportActorOut.CenterPosition.Y/Tile       - 0.5

                    Teleports_ActorsDiffX[i]=x_o-x_i
                    Teleports_ActorsDiffY[i]=y_o-y_i

                    Teleports_SizeX[i]=x_BR-x_i
                    Teleports_SizeY[i]=y_BR-y_i

                    --TeleportActorDiffY=TeleportActorOut.CenterPosition.Y/Tile-TeleportActorIn.CenterPosition.Y/Tile

                    Teleports_ActorsIn[i] = TeleportActorIn
                    Teleports_ActorsIn_BR[i] = TeleportActorIn_BR
                    Teleports_ActorsOut[i] = TeleportActorOut

                    --Media.DisplayMessage("Teleport in/out location "..i..": "..x_i..","..y_i.." / "..x_o..","..y_o.." OK!","Mission",HSLColor.Blue);
                    TeleportCount[i]=0
                    resetter[i] = 10
                    if Oke == 1 then
                        --Teleported[i]={}
                        Trigger.AfterDelay(DateTime.Seconds(4+i),function()
                            check_teleport(i)
                        end)
                    --else
                    --    return
                    end
                    --return
                else
                    if TeleportActorIn == nil then
                        Media.DisplayMessage("Teleport in TL location:  TeleportActorIn_TL_"..i..": NOT OK! AAARGHHHHH!!!!","Mission",HSLColor.Blue);
                    elseif TeleportActorOut == nil then
                        Media.DisplayMessage("Teleport out location: TeleportActorOut_TL_"..i..": NOT OK! AAARGHHHHH!!!!","Mission",HSLColor.Blue);
                    elseif TeleportActorIn_BR == nil then
                        Media.DisplayMessage("Teleport in BR location: TeleportActorIn_BR_"..i..": NOT OK! AAARGHHHHH!!!!","Mission",HSLColor.Blue);
                    end
                    Oke = 0
                    --return
                end

            end
            return
        end

        if TeleportNumber == nil then 
            Media.DisplayMessage("TeleportNumber == nil","Mission",HSLColor.Blue);
        --else
            --Media.DisplayMessage("Checking TeleportNumber: "..TeleportNumber,"Mission",HSLColor.Blue);
        end 

        --facts=Map.ActorsInBox(Teleports_ActorsIn[TeleportNumber].CenterPosition-AreaSize,Teleports_ActorsIn[TeleportNumber].CenterPosition+AreaSize,function(actor)
        --facts=Map.ActorsInBox(Teleports_ActorsIn[TeleportNumber].CenterPosition - AreaHalfSize,Teleports_ActorsIn_BR[TeleportNumber].CenterPosition + AreaHalfSize,function(actor)



        number=0
        count=0
        local actorId=""
        local m_teleported=teleported[TeleportNumber]

        facts=Map.ActorsInBox(Teleports_ActorsIn[TeleportNumber].CenterPosition - AreaHalfSize,Teleports_ActorsIn_BR[TeleportNumber].CenterPosition + AreaHalfSize,function(actor)
            return  m_teleported[tostring(actor)]==nil and
                    actor.HasProperty("Move") and
                    actor.Type~="waypoint" and
                    actor.Type~="badr" and actor.CenterPosition.Z == 0
                    --and actor.Type~="badr.bomber" and actor.Type~="mig" and actor.Type~="yak" and 
                    --actor.Type~="heli" and actor.Type~="mh60" and actor.Type~="mh60" and  
                    --actor.Type~="chinook" and actor.Type~="hind" and actor.Type~="tran" and
                    --actor.Type~="u2" and actor.Type~="longbow" and actor.Type~="u2" --
        end)
        --Utils.Do(facts,function(actor)
        --    Media.DisplayMessage("actor.Type: "..actor.Type,"Mission",HSLColor.Blue);
        --end)


        Utils.Do(facts,function(actor)
            --if (actor.CenterPosition.Z ~= 0) then 
            --    Media.DisplayMessage("actor.Type: "..actor.Type.." actor.CenterPosition.Z = "..actor.CenterPosition.Z,"Mission",HSLColor.Blue);
            --    return
            --end
            number=number+1
            if not (m_TeleportNumber == 7 or m_TeleportNumber == 8) and number==1 and number_time[TeleportNumber]==4 then
                Media.PlaySound("chrotnk1.aud")
            end
            --if number==1 and number_time[TeleportNumber]==4 then
            --    Media.DisplayMessage("Teleporter "..TeleportNumber..": Activity Detected...","Mission",HSLColor.Blue);
            --end
            actorId=tostring(actor)
            --if actor_speed[actor.Type] ~= nil then
            --end
            --a_s = math.abs(Teleports_ActorsDiffX[TeleportNumber]) - 1
            a_s = 2
            --Media.DisplayMessage("Count: "..number.." Actor: "..actorId.."  speed = "..a_s,"Mission",HSLColor.Blue);
            if actor.IsIdle then
                if m_teleported[actorId]==nil then
                    count=count+1
                    --Media.DisplayMessage("Count: "..number.." Actor: "..actorId.." is idle.","Mission",HSLColor.Blue);

                    resetter[TeleportNumber] = 10
                    m_teleported[actorId]=a_s
                    --if not (m_TeleportNumber == 7 or m_TeleportNumber == 8) and count==1 then                     
                    --    Media.PlaySound("chrotnk1.aud")
                    --end
                    flits_teleport(actor,TeleportNumber,1, a_s, teleported[TeleportNumber])
                end
            else
                if m_teleported[actorId]==nil then
                    count=count+1
                    --Media.DisplayMessage("Count: "..number.." Actor: "..actorId.." is NOT idle.","Mission",HSLColor.Blue);

                    resetter[TeleportNumber] = 10
                    m_teleported[actorId]=a_s
                    --if not (m_TeleportNumber == 7 or m_TeleportNumber == 8) and count==1 then                     
                    --    Media.PlaySound("chrotnk1.aud")
                    --end
                    flits_teleport(actor,TeleportNumber,1, a_s, teleported[TeleportNumber])
                end
            end
        end)

        --TeleportCount[TeleportNumber]=tablelength(m_teleported)
        --if (TeleportCount[TeleportNumber]>0) then
        if (resetter[TeleportNumber]>0) then
            --Media.DisplayMessage("Teleporter: "..TeleportNumber.."  Active: "..resetter[TeleportNumber],"Mission",HSLColor.Blue);
            --if not number_time[TeleportNumber]==4 then
            --    Media.DisplayMessage("Teleporter: "..TeleportNumber.."  Active: "..resetter[TeleportNumber],"Mission",HSLColor.Blue);
            --    --Media.DisplayMessage("Teleporter "..TeleportNumber.."  Active","Mission",HSLColor.Blue);
            --end
            --Media.DisplayMessage("TeleportCount: "..TeleportCount[TeleportNumber],"Mission",HSLColor.Blue);

            --Utils.Do(teleported,function(MyId)
            --    Media.DisplayMessage("Teleporting list: ID: "..MyId,"Mission",HSLColor.Blue);
            --end)

            number_time[TeleportNumber]=0.2
            resetter[TeleportNumber] = resetter[TeleportNumber] - 1

            --Media.DisplayMessage("Teleporter: "..TeleportNumber.."  Resetter: "..resetter[TeleportNumber],"Mission",HSLColor.Blue);

            if (resetter[TeleportNumber] <= 0) then
                --m_TeleportCount = TeleportCount[TeleportNumber]

                --if not number_time[TeleportNumber]==4 then
                --    Media.DisplayMessage("Teleporter1: "..TeleportNumber.."  Slow on: resetter: "..resetter[TeleportNumber].."  number_time: "..number_time[TeleportNumber],"Mission",HSLColor.Blue);
                --    --Media.DisplayMessage("Teleporter "..TeleportNumber.."  Slow on","Mission",HSLColor.Blue);
                --end
                --TeleportCount[TeleportNumber]=0
                --m_teleported={}
                teleported[TeleportNumber]={}

                --number_time[TeleportNumber]=4
                --resetter[TeleportNumber] = 10
            end
        else
            --if number_time[TeleportNumber]~=5 then
            --    Media.DisplayMessage("Teleporter "..TeleportNumber.." Rest...","Mission",HSLColor.Blue);
            --end
            --if not number_time[TeleportNumber]==4 then
            --    Media.DisplayMessage("Teleporter2: "..TeleportNumber.."  Slow on: resetter: "..resetter[TeleportNumber].."  number_time: "..number_time[TeleportNumber],"Mission",HSLColor.Blue);
            --end
            number_time[TeleportNumber]=4
        end


        Trigger.AfterDelay(DateTime.Seconds(number_time[TeleportNumber]),function()
            check_teleport(TeleportNumber)
        end)

    end

    
    REVERSE=function(in_time)
        Media.DisplayMessage("Reversing direction in "..in_time.." seconds.","Mission",HSLColor.Yellow);
        Trigger.AfterDelay(DateTime.Seconds(in_time-30),function()
            Media.DisplayMessage("Reversing direction in 30 seconds.","Mission",HSLColor.Yellow);
            Trigger.AfterDelay(DateTime.Seconds(25),function()
                Media.DisplayMessage("Reversing direction in 5 seconds.","Mission",HSLColor.Yellow);
                Trigger.AfterDelay(DateTime.Seconds(5),function()
                    Media.DisplayMessage("Reversing direction for 45 seconds.","Mission",HSLColor.Yellow);
                    REVERSE_DIRECTION()
                end)
            end)
        end)
    end

    REVERSE_DIRECTION=function()
        if REVERSED_ON == 0 then
            REVERSED_ON=1
            Trigger.AfterDelay(DateTime.Seconds(40),function()
                Media.DisplayMessage("Returning normal direction in 5 seconds.","Mission",HSLColor.Yellow);
                Trigger.AfterDelay(DateTime.Seconds(5),function()
                    REVERSE_DIRECTION()
                end)
            end)
        else 
            Media.DisplayMessage("Returning normal direction.","Mission",HSLColor.Yellow);
            REVERSED_ON=0
            Trigger.AfterDelay(DateTime.Seconds(210),function()
                REVERSE(90)
            end)
        end
    end

    Trigger.AfterDelay(DateTime.Seconds(1),function()
        check_teleport()
    end)
--    REVERSED_ON=0
--    REVERSE(300)
end

SchemeWar={}
SchemeVehicle={}
ReductionWar={}
ReductionVehicle={}
NumReductionWar=0
NumReductionVehicle=0

-- Ticks for checkbulidings
Tick=function()
    if (enablechecking>0) then
        checkbuildings2()
    end
end
