1require "common" 2 3local DebugEnabled = false 4 5local function EchoDebug(inStr) 6 if DebugEnabled then 7 game:SendToConsole("ScoutHandler: " .. inStr) 8 end 9end 10 11ScoutHandler = class(Module) 12 13function ScoutHandler:Name() 14 return "ScoutHandler" 15end 16 17function ScoutHandler:internalName() 18 return "scouthandler" 19end 20 21function ScoutHandler:Init() 22 self.spotsToScout = {} 23 self.lastCount = {} 24 self.sameCount = {} 25 self.usingStarts = {} 26end 27 28function ScoutHandler:ScoutLos(scoutbehaviour, position) 29 local los 30 if ai.maphandler:IsUnderWater(position) and unitTable[scoutbehaviour.name].sonarRadius == 0 then 31 -- treat underwater spots as surface spots if the scout has no sonar, so that it moves on 32 local lt = ai.loshandler:AllLos(position) 33 if lt[2] then 34 los = 2 35 else 36 los = 0 37 end 38 else 39 los = ai.loshandler:GroundLos(position) 40 end 41 return los 42end 43 44function ScoutHandler:ClosestSpot(scoutbehaviour) 45 local unit = scoutbehaviour.unit:Internal() 46 local position = unit:GetPosition() 47 local mtype = scoutbehaviour.mtype 48 if mtype == nil then mtype = "air" end 49 if network == nil then network = 1 end 50 -- initializing the necessary tables if they're not yet 51 if self.spotsToScout[mtype] == nil then self.spotsToScout[mtype] = {} end 52 if self.spotsToScout[mtype][network] == nil then self.spotsToScout[mtype][network] = {} end 53 if self.usingStarts[mtype] == nil then self.usingStarts[mtype] = {} end 54 if self.usingStarts[mtype][network] == nil then self.usingStarts[mtype][network] = false end 55 if self.lastCount[mtype] == nil then self.lastCount[mtype] = {} end 56 if self.lastCount[mtype][network] == nil then self.lastCount[mtype][network] = 0 end 57 if self.sameCount[mtype] == nil then self.sameCount[mtype] = {} end 58 if self.sameCount[mtype][network] == nil then self.sameCount[mtype][network] = 0 end 59 -- filling table of spots to scout if empty 60 if #self.spotsToScout[mtype][network] == 0 then 61 if not self.usingStarts[mtype][network] then 62 if ai.startLocations[mtype] ~= nil then 63 if ai.startLocations[mtype][network] ~= nil then 64 -- scout all probable start locations first 65 EchoDebug(unit:Name() .. " got starts") 66 for i, p in pairs(ai.startLocations[mtype][network]) do 67 table.insert(self.spotsToScout[mtype][network], p) 68 end 69 end 70 end 71 -- true even if no start locations were in network, so that it moves onto using metals/geos next 72 self.usingStarts[mtype][network] = true 73 elseif self.usingStarts[mtype][network] then 74 -- then use metal and geo spots 75 EchoDebug(unit:Name() .. " got metals and geos") 76 for i, p in pairs(ai.scoutSpots[mtype][network]) do 77 table.insert(self.spotsToScout[mtype][network], p) 78 end 79 self.usingStarts[mtype][network] = false 80 end 81 end 82 EchoDebug(mtype .. " " .. network .. " has " .. #self.spotsToScout[mtype][network] .. " spots") 83 -- find the closest spot 84 local pos = nil 85 local index = nil 86 local bestDistance = 10000 87 for i, p in ipairs(self.spotsToScout[mtype][network]) do 88 local los 89 if ai.maphandler:IsUnderWater(p) and unitTable[scoutbehaviour.name].sonarRadius == 0 then 90 -- treat underwater spots as surface spots if the scout has no sonar, so that it moves on 91 local lt = ai.loshandler:AllLos(p) 92 if lt[2] then 93 los = 2 94 else 95 los = 0 96 end 97 else 98 los = ai.loshandler:GroundLos(p) 99 end 100 if los == 2 or los == 3 or not ai.targethandler:IsSafePosition(p, unit, 1) then 101 table.remove(self.spotsToScout[mtype][network], i) 102 else 103 local dist = Distance(position, p) 104 if dist < bestDistance then 105 bestDistance = dist 106 pos = p 107 index = i 108 end 109 end 110 end 111 -- make sure we're not getting quixotic 112 if #self.spotsToScout[mtype][network] == self.lastCount[mtype][network] then 113 self.sameCount[mtype][network] = self.sameCount[mtype][network] + 1 114 if self.sameCount[mtype][network] > 15 then 115 -- if the last spots can't be scouted for some reason, just clear the list to repopulate it 116 self.spotsToScout[mtype][network] = {} 117 end 118 else 119 self.sameCount[mtype][network] = 0 120 end 121 self.lastCount[mtype][network] = #self.spotsToScout[mtype][network] 122 if pos ~= nil then 123 EchoDebug("and spot found") 124 pos.y = 0 125 else 126 EchoDebug("but NO spot found") 127 end 128 return pos 129end