AIUnitTypes = { "ant", "ant", "ant", "zombie", "zombie", "zombie", "zombie", "zombie" } freeForAllTime = 6 freeForAllTimeReached = 0 countNumberOfHumanPlayers = function() local count = 0 Utils.Do(Player.GetPlayers(nil), function(p) if not p.IsNonCombatant and not p.IsBot then count = count + 1 end end) return count end countTotalNumberOfDerricks = function() local count = 0 Utils.Do(Map.NamedActors, function(a) if a.Type == "oilb" then count = count + 1 end end) return count end countMaxNumerOfDerricksPerPlayer = function(numDerricks, numPlayers) offset = 4 -- the 4 derricks at the center of this particular map... return math.floor(0.5 + (numDerricks - offset) / numPlayers) end isGreedyPlayer = function(player, numDerricks, maxNum) print(" isGreedy check: " ..player.InternalName .. ", " .. tostring(numDerricks) .. " >? " .. tostring(maxNum)) if numDerricks > maxNum then return true else return false end end numberOfHumanPlayers = countNumberOfHumanPlayers() totalNumberOfDerricks = countTotalNumberOfDerricks() maxNumerOfDerricksPerPlayer = countMaxNumerOfDerricksPerPlayer(totalNumberOfDerricks, numberOfHumanPlayers) Media.DisplayMessage("There are " .. tostring(totalNumberOfDerricks - 4) .. " oil derricks for " .. tostring(numberOfHumanPlayers) .. " human players") Media.DisplayMessage("Don't take more than " .. tostring(maxNumerOfDerricksPerPlayer) .. " oil derricks in the first " .. tostring(freeForAllTime) .. " minutes.\nDon't be greedy!") findClosestWaypoint = function(cPos) result = nil closestDist = 9999999 Utils.Do(Map.NamedActors, function(a) if a.Type == "waypoint" then d = (a.Location.X - cPos.X)^2 + (a.Location.Y - cPos.Y)^2 if d < closestDist then closestDist = d result = a.Location end end end) return result end getNumberOfOilDerricks = function(player) local count = 0 Utils.Do(player.GetActorsByType("oilb"), function(a) count = count + 1 end) return count end countOilDerricks = function() print("Main loop. GameTime: " .. tostring(DateTime.GameTime)) if DateTime.GameTime > DateTime.Minutes(freeForAllTime) then if freeForAllTimeReached == 0 then Media.DisplayMessage(tostring(freeForAllTime) .. " Minutes are over. Feel free to take all remaining oil derricks now.") freeForAllTimeReached = 1 end return end ignores={["Neutral"]=1, ["Creeps"]=1, ["Everyone"]=1} Utils.Do(Player.GetPlayers(nil), function(player) if ignores[player.InternalName] or player.IsBot then return end numDerricks = getNumberOfOilDerricks(player) print("Player: " .. player.InternalName .. " got " .. numDerricks .. " oilb") print(" He got " .. player.KillsCost .. " kills") if isGreedyPlayer(player, numDerricks, maxNumerOfDerricksPerPlayer) then punish(player) end end) print(" ") Trigger.AfterDelay(DateTime.Seconds(30), countOilDerricks) end punish = function(player) Media.DisplayMessage("Player " .. player.Name .. " is greedy!") target = player.GetActorsByType("oilb")[1] if target then closestWaypoint = findClosestWaypoint(target.Location) SendAIUnits({ closestWaypoint, target.Location }, AIUnitTypes, 50) else print("weird...") end end SendAIUnits = function(entryPath, unitTypes, interval) print("sending AI units!") local units = Reinforcements.Reinforce(Player.GetPlayer("Creeps"), unitTypes, entryPath, interval) end WorldLoaded = function() -- first run after 10 ticks should not harm as long as no dericks are pre-assigned. but it makes testing easier. Trigger.AfterDelay(10, countOilDerricks) end