From ed77f2a54bd21c87bc48837db556756036bb87ee Mon Sep 17 00:00:00 2001 From: Fx-Doo Date: Tue, 12 Jun 2018 21:27:00 +0200 Subject: [PATCH 1/2] Geo Handler implementation --- data/ai/geohandler.lua | 48 +++++++++++++++++++++++++ data/ai/preload/shard_null/map.lua | 13 +++++++ data/ai/preload/spring_cpp/map.lua | 25 +++++++++++++ data/ai/preload/spring_lua/geo.lua | 18 ++++++++++ data/ai/preload/spring_lua/map.lua | 23 +++++++++++- data/ai/preload/spring_lua/unittype.lua | 4 +++ data/ai/taskqueuebehaviour.lua | 15 ++++++++ 7 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 data/ai/geohandler.lua create mode 100644 data/ai/preload/spring_lua/geo.lua diff --git a/data/ai/geohandler.lua b/data/ai/geohandler.lua new file mode 100644 index 0000000..d0c1848 --- /dev/null +++ b/data/ai/geohandler.lua @@ -0,0 +1,48 @@ +GeoSpotHandler = class(Module) + + +function GeoSpotHandler:Name() + return "GeoSpotHandler" +end + +function GeoSpotHandler:internalName() + return "geospothandler" +end + +function GeoSpotHandler:Init() + self.geos = self.game.map:GetGeoSpots() +end + +function distance(pos1,pos2) + local xd = pos1.x-pos2.x + local zd = pos1.z-pos2.z + local yd = pos1.y-pos2.y + if yd < 0 then + yd = -yd + end + dist = math.sqrt(xd*xd + zd*zd + yd*yd*yd) + return dist +end + +function GeoSpotHandler:ClosestFreeGeo(unittype,position) + local pos = nil + local bestDistance = 10000 + geoCount = self.game.map:GeoCount() + for i,v in ipairs(self.geos) do + local p = v + local dist = distance(position,p) + if dist < bestDistance then + if self.game.map:CanBuildHere(unittype,p) then + --checking for unit positions + local spGetUnitsInRectangle = Spring.GetUnitsInRectangle + local radius = 100 + local units_found = spGetUnitsInRectangle(p.x - radius, p.z - radius, p.x + radius, p.z + radius) + if #units_found == 0 then + bestDistance = dist + pos = p + end + end + end + end + return pos +end diff --git a/data/ai/preload/shard_null/map.lua b/data/ai/preload/shard_null/map.lua index eb4349c..488c690 100644 --- a/data/ai/preload/shard_null/map.lua +++ b/data/ai/preload/shard_null/map.lua @@ -48,6 +48,19 @@ function map:GetMetalSpots() -- returns a table of spot positions return {} end +function map:GeoCount() -- returns the nubmer of metal spots + return 0 +end + +function map:GetGeo(idx) -- returns a Position for the given spot + return nil +end + +function map:GetGeoSpots() -- returns a table of spot positions + -- + return {} +end + function map:GetControlPoints() -- not sure this can be implemented in the Spring C++ AI interface return {} diff --git a/data/ai/preload/spring_cpp/map.lua b/data/ai/preload/spring_cpp/map.lua index 2ff3ad7..9f37a92 100644 --- a/data/ai/preload/spring_cpp/map.lua +++ b/data/ai/preload/spring_cpp/map.lua @@ -78,6 +78,31 @@ function map:GetMetalSpots() -- returns a table of spot positions return f end +function map:GeoCount() -- returns the nubmer of metal spots + local m = game_engine:Map() + return m:GeoCount() +end + +function map:GetGeo(idx) -- returns a Position for the given spot + local m = game_engine:Map() + return m:GetGeo(idx) +end + +function map:GetMetalSpots() -- returns a table of spot positions + -- + local m = game_engine:Map() + local fv = game_engine:Map():GetGeoSpots() + local count = m:GeoCount() + local f = {} + local i = 0 + while i < count do + table.insert( f, m:GetGeo(i) ) + i = i + 1 + end + --fv = nil + return f +end + function map:GetControlPoints() -- not sure this can be implemented in the Spring C++ AI interface return {} diff --git a/data/ai/preload/spring_lua/geo.lua b/data/ai/preload/spring_lua/geo.lua new file mode 100644 index 0000000..89910e9 --- /dev/null +++ b/data/ai/preload/spring_lua/geo.lua @@ -0,0 +1,18 @@ +local function GetGeos() + local geos = {} + local i = 1 + for ct, featureID in pairs(Spring.GetAllFeatures()) do + local featureDefID = Spring.GetFeatureDefID(featureID) + if FeatureDefs[featureDefID].geoThermal == true then + local x, y, z = Spring.GetFeaturePosition(featureID) + local spot = {x = x, z = z, y = Spring.GetGroundHeight(x,z)} + geos[i] = spot + i = i + 1 + end + end + return geos +end + +local spots = GetGeos() + +return spots diff --git a/data/ai/preload/spring_lua/map.lua b/data/ai/preload/spring_lua/map.lua index a0bce7a..48572dd 100644 --- a/data/ai/preload/spring_lua/map.lua +++ b/data/ai/preload/spring_lua/map.lua @@ -1,6 +1,6 @@ local map = {} map.spots = shard_include("spring_lua/metal") - +map.geos = shard_include("spring_lua/geo") -- function map:FindClosestBuildSite(unittype,builderpos, searchradius, minimumdistance) -- function map:CanBuildHere(unittype,position) -- function map:GetMapFeatures() @@ -100,6 +100,27 @@ function map:GetMetalSpots() -- returns a table of spot positions return f end +function map:GeoCount() -- returns the nubmer of metal spots + Spring.Echo("GetGeoCount") + return #self.geos +end + +function map:GetGeo(idx) + return self.geos[idx] +end + +function map:GetGeoSpots() -- returns a table of spot positions + local fv = self.geos + local count = self:GeoCount() + local f = {} + local i = 0 + while i < count do + table.insert( f, fv[i] ) + i = i + 1 + end + return f +end + function map:GetControlPoints() if self.controlPoints then return self.controlPoints end self.controlPoints = {} diff --git a/data/ai/preload/spring_lua/unittype.lua b/data/ai/preload/spring_lua/unittype.lua index ddca942..a22166b 100644 --- a/data/ai/preload/spring_lua/unittype.lua +++ b/data/ai/preload/spring_lua/unittype.lua @@ -74,6 +74,10 @@ function ShardUnitType:Extractor() return self.def.extractsMetal > 0 end +function ShardUnitType:Geothermal() + return self.def.needGeo +end + function ShardUnitType:ExtractorEfficiency() return self.def.extractsMetal end diff --git a/data/ai/taskqueuebehaviour.lua b/data/ai/taskqueuebehaviour.lua index a1e984f..1014064 100644 --- a/data/ai/taskqueuebehaviour.lua +++ b/data/ai/taskqueuebehaviour.lua @@ -167,6 +167,8 @@ function TaskQueueBehaviour:TryToBuild( unit_name ) local success = false if utype:Extractor() then success = self:BuildExtractor(utype) + elseif utype:Geothermal() then + success = self:BuildGeo(utype) elseif unit:Type():IsFactory() then success = self.unit:Internal():Build(utype) else @@ -259,6 +261,19 @@ function TaskQueueBehaviour:BuildOnMap(utype) return true end +function TaskQueueBehaviour:BuildGeo(utype) + -- find a free spot! + unit = self.unit:Internal() + p = unit:GetPosition() + p = self.ai.geospothandler:ClosestFreeGeo(utype,p) + if p == nil or self.game.map:CanBuildHere(utype,p) ~= true then + + self:OnToNextTask() + return false + end + return self.unit:Internal():Build(utype,p) +end + function TaskQueueBehaviour:BuildExtractor(utype) -- find a free spot! unit = self.unit:Internal() From 1432369e06c29202dfa94a983a4a68b91fc3661f Mon Sep 17 00:00:00 2001 From: Fx-Doo Date: Thu, 14 Jun 2018 12:55:40 +0200 Subject: [PATCH 2/2] Added buildfacing to ShardUnit:Build(t, p, f) f = f or 0 --> Defaults to 0 if f == nil --- data/ai/preload/spring_lua/unit.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/data/ai/preload/spring_lua/unit.lua b/data/ai/preload/spring_lua/unit.lua index f198f4a..947ac34 100644 --- a/data/ai/preload/spring_lua/unit.lua +++ b/data/ai/preload/spring_lua/unit.lua @@ -205,14 +205,15 @@ function ShardUnit:MoveAndPatrol(p) return true end -function ShardUnit:Build(t, p) -- IUnitType* +function ShardUnit:Build(t, p, f) -- IUnitType* if type(t) == "string" then -- local ai = Shard.AIs[1] -- t = ai.game:GetTypeByName(t) t = game:GetTypeByName(t) end + f = f or 0 if not p then p = self:GetPosition() end - Spring.GiveOrderToUnit( self.id, -t:ID(), { p.x, p.y, p.z }, {} ) + Spring.GiveOrderToUnit( self.id, -t:ID(), { p.x, p.y, p.z, f}, {} ) return true end