Diligent Constructors widget

Diligent Constructors widget

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
User avatar
Beherith
Posts: 5145
Joined: 26 Oct 2007, 16:21

Diligent Constructors widget

Post by Beherith »

Diligent Constructors

Makes idle constuction units repair allied units and reclaim any unresurrectable features, and resurrect units if able. It makes them do it only inside their own build radius, so it works in tandem with hold position.

Code: Select all


function widget:GetInfo()
	return {
		name        = "Diligent Constructors",
		desc        = "Makes idle constuction units repair and reclaim any unresurrectable features, resurrect units if possible.",
		author        = "Beherith",
		date        = "March 20, 2016",
		license        = "GNU GPL, v2 or later",
		layer        = 0,
		enabled        = true  --  loaded by default?
	}
end

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

local CMD_PASSIVE            = 34571
local CMD_MOVE_STATE        = CMD.MOVE_STATE
local CMD_REPEAT            = CMD.REPEAT
local CMD_PATROL            = CMD.PATROL
local CMD_FIGHT                = CMD.FIGHT
local CMD_STOP                = CMD.STOP
local CMD_RECLAIM                = CMD.RECLAIM
local CMD_REPAIR               = CMD.REPAIR
local CMD_RESURRECT             = CMD.RESURRECT
local CMD_WAIT           = CMD.WAIT
local spGetGameFrame        = Spring.GetGameFrame
local spGetMyTeamID            = Spring.GetMyTeamID
local spGetTeamUnits        = Spring.GetTeamUnits
local spGetUnitCommands        = Spring.GetUnitCommands
local spGetUnitDefID        = Spring.GetUnitDefID
local spGetUnitPosition        = Spring.GetUnitPosition
local spGiveOrderToUnit        = Spring.GiveOrderToUnit
local spGetSpectatingState    = Spring.GetSpectatingState
local spGetUnitPosition    = Spring.GetUnitPosition
local spGetFeaturesInSphere = Spring.GetFeaturesInSphere
local spGetFeatureResurrect = Spring.GetFeatureResurrect
local spGetFeatureDefID = Spring.GetFeatureDefID
local spGetUnitTeam = Spring.GetUnitTeam
local spGetUnitHealth = Spring.GetUnitHealth


local hmsx = Game.mapSizeX/2
local hmsz = Game.mapSizeZ/2

local myTeamID = spGetMyTeamID()
local myAllyTeamID = Spring.GetMyAllyTeamID()

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
local watchedUnits={}

local function IsMobileBuilder(ud)
	return ud and ud.isBuilder and ud.canMove
end


function widget:PlayerChanged()
	if spGetSpectatingState() then
		widgetHandler:RemoveWidget()
	end
end

function widget:Initialize()
	if spGetSpectatingState() then
		widgetHandler:RemoveWidget()
	end
end


function widget:UnitCreated(unitID, unitDefID, unitTeam)
	if unitTeam ~= myTeamID then
		return
	end
end

function widget:UnitGiven(unitID, unitDefID, unitTeam)
	widget:UnitCreated(unitID, unitDefID, unitTeam)
end

function ReclaimRepairResurrect(unitID, unitDefID, unitTeam)
	-- Spring.Echo('widget:ReclaimRepairResurrect',unitID, unitDefID, unitTeam)
	local x,y,z = spGetUnitPosition(unitID)
	local buildDistance = UnitDefs[unitDefID].buildDistance 
	local closeFeatures = spGetFeaturesInSphere(x,y,z,buildDistance)
	if closeFeatures ~= nil then
		for i, closeFeatureID in ipairs(closeFeatures) do
			 -- Spring.Echo('closeFeatureID',closeFeatureID,FeatureDefs[Spring.GetFeatureDefID(closeFeatureID)].resurrectable,Spring.GetFeatureResurrect(closeFeatureID))
			local featureResID = spGetFeatureResurrect(closeFeatureID)
			if FeatureDefs[spGetFeatureDefID(closeFeatureID)].resurrectable ~= 1  and ( featureResID == nil or featureResID == "") then
				spGiveOrderToUnit(unitID, CMD_RECLAIM,  { Game.maxUnits + closeFeatureID} , {})
				return
			end
		end
	end
	
	local closeUnits = Spring.GetUnitsInSphere(x,y,z,buildDistance)
	if closeUnits ~= nil then
		for i, closeUnitID in ipairs(closeUnits) do
			if closeUnitID ~= unitID and spGetUnitTeam(closeUnitID) == myTeamID then
				local health, maxHealth = spGetUnitHealth(closeUnitID)
				if health and health < maxHealth then
				-- Spring.Echo('REPAIR')
					spGiveOrderToUnit(unitID, CMD_REPAIR,  { closeUnitID} , {})
					return
				end
			end
		end
	end
	
	if closeFeatures ~= nil and UnitDefs[unitDefID].canResurrect then
		for i, closeFeatureID in ipairs(closeFeatures) do
			local featureResID = spGetFeatureResurrect(closeFeatureID)
			if  featureResID ~= nil and featureResID ~= ""  then
			-- Spring.Echo('RESURRECT')
				spGiveOrderToUnit(unitID, CMD_RESURRECT,  { Game.maxUnits + closeFeatureID} , {})
				return
			end
		end
	end
end

function widget:UnitCommand(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOpts, cmdTag)
	-- Spring.Echo(Spring.GetGameFrame(),"widget:UnitCommand",unitID, unitDefID, unitTeam,CMD[cmdID], cmdParams, cmdOpts, cmdTag)
	if unitTeam == myTeamID and watchedUnits[unitID]~=nil and cmdID ~= CMD_WAIT then -- this ignores the WAIT WAIT (will probably screw stuff up, but hey :p)
		-- Spring.Echo('UnitCommand clearing unit',unitID)
		watchedUnits[unitID]= nil
	end
end

function widget:UnitDestroyed(unitID, unitDefID, unitTeam, attackerID, attackerDefID, attackerTeam)
	if watchedUnits[unitID] ~= nil then
		watchedUnits[unitID] = nil
	end
end

function widget:GameFrame(n)
	for unitID, watchstate in pairs(watchedUnits) do
		if (watchstate.lastupdate + watchstate.delay )<=n then
			-- Spring.Echo("slacker is:",unitID,watchstate.lastupdate, watchstate.delay)
			watchedUnits[unitID].lastupdate = n
			watchedUnits[unitID].delay = watchstate.delay+3
			ReclaimRepairResurrect(unitID, watchstate.udID, watchstate.ut)
		end
	end
end
function widget:UnitIdle(unitID, unitDefID, unitTeam)
    if unitTeam ~= myTeamID then
        return
    end
	-- Spring.Echo('widget:UnitIdle',unitID, unitDefID, unitTeam)
	if IsMobileBuilder(UnitDefs[unitDefID]) then
		watchedUnits[unitID]={lastupdate = spGetGameFrame(), delay = 5, udID = unitDefID, ut= unitTeam}
		ReclaimRepairResurrect(unitID, unitDefID, unitTeam)
    end
end

EDIT: the more I play with this widget, the more holes I find in my logic... But its still better than nothing.
Post Reply

Return to “Lua Scripts”