Page 1 of 1

Auto reclaim heal assist

Posted: 20 Dec 2010, 11:07
by klapmongool
Hey all,

I have a problem with this widget: http://widgets.springrts.de/springinfo/index.php#186. It does what is intended to do just fine, however it has an undesired effect as well. It sets a factory command which causes newly built units to move back into the factory. Can factories be exempt from the selection by this script?

-----------------------------------
-- Author: Johan Hanssen Seferidis
--
-- Comments: Sets all idle units that are not selected to fight. That has as effect to reclaim if there is low metal
-- , repair nearby units and assist in building if they have the possibility.
-- If you select the unit while it is being idle the widget is not going to take effect on the selected unit.
--
-------------------------------------------------------------------------------------

function widget:GetInfo()
return {
name = "Auto Reclaim/Heal/Assist",
desc = "Makes idle unselected builders/rez/com/nanos to reclaim metal if metal bar is not full, repair nearby units and assist in building",
author = "Pithikos",
date = "Nov 21, 2010",
license = "GPLv3",
layer = 0,
enabled = true --enable automatically
}
end

--------------------------------------------------------------------------------------
local echo = Spring.Echo
local getUnitPos = Spring.GetUnitPosition
local orderUnit = Spring.GiveOrderToUnit
local getUnitTeam = Spring.GetUnitTeam
local isUnitSelected = Spring.IsUnitSelected
local getGameSeconds = Spring.GetGameSeconds
local gameInSecs = 0
local lastOrderGivenInSecs= 0
local idleReclaimers={} --reclaimers because they all can reclaim

myTeamID=-1;

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


--Initializer
function widget:Initialize()
--disable widget if I am a spec
local _, _, spec = Spring.GetPlayerInfo(Spring.GetMyPlayerID())
if spec then
widgetHandler:RemoveWidget()
return false
end
myTeamID=Spring.GetMyTeamID() --get my team ID
end


--Give reclaimers the FIGHT command every second
function widget:GameFrame()
gameInSecs=math.floor(getGameSeconds()) --gives the time in seconds(rounded)
--echo("Time in secs: "..gameInSecs.." Last order given at: "..lastOrderGivenInSecs) --¤debug
if (gameInSecs>lastOrderGivenInSecs) then
for unitID in pairs(idleReclaimers) do
local x, y, z = getUnitPos(unitID) --get unit's position
if (not isUnitSelected(unitID)) then --if unit is not selected
orderUnit(unitID, CMD.FIGHT, { x, y, z }, {}) --command unit to reclaim
end
lastOrderGivenInSecs=gameInSecs --record the time that command was given
end
end
end


--Add reclaimer to the register
function widget:UnitIdle(unitID, unitDefID, unitTeam)
if (myTeamID==getUnitTeam(unitID)) then --check if unit is mine

if (UnitDefs[unitDefID]["canReclaim"]) then --check if unit can reclaim
idleReclaimers[unitID]=true --add unit to register
lastRegiInSecs=gameInSecs
--echo("Registering unit "..unitID.." as idle")
end

end
end


--Unregister reclaimer once it is given a command
function widget:UnitCommand(unitID)
--echo("Unit "..unitID.." got a command") --¤debug
for reclaimerID in pairs(idleReclaimers) do
if (reclaimerID==unitID) then
idleReclaimers[reclaimerID]=nil
--echo("Unregistering unit "..reclaimerID.." as idle")
end
end
end

Re: Auto reclaim heal assist

Posted: 20 Dec 2010, 11:22
by knorke
untested, try changing

Code: Select all

if (UnitDefs[unitDefID]["canReclaim"]) then --check if unit can reclaim
to

Code: Select all

if (UnitDefs[unitDefID]["canReclaim"] and not UnitDefs[unitDefID].type == "Factory") then --check if unit can reclaim and is not a factory
The loop in
function widget:UnitCommand(unitID)
seems unneeded btw. It is looping through all reclaimers every time any unit gets any command.
idleReclaimers[unitID]=nil
Might be enough. Or maybe
if (idleReclaimers and idleReclaimers[unitID]) then idleReclaimers[unitID] = nil end

Re: Auto reclaim heal assist

Posted: 20 Dec 2010, 12:13
by klapmongool
Hmm, I tried the first part of what you suggested, and some variations to it. It seems to have an error though (the widget wont appear in f11 anymore).

Re: Auto reclaim heal assist

Posted: 20 Dec 2010, 18:59
by knorke
ok, this works for me:

Code: Select all

--Add reclaimer to the register
function widget:UnitIdle(unitID, unitDefID, unitTeam)
if (myTeamID==getUnitTeam(unitID)) then --check if unit is mine
local unittype = UnitDefs[unitDefID].type  --***
--Spring.Echo ("unit type=" .. unittype) --***
if (unittype == "Factory") then return end --no factories ***
if (UnitDefs[unitDefID]["canReclaim"]) then --check if unit can reclaim and is not a factory
	--if (UnitDefs[unitDefID]["canReclaim"]) then --check if unit can reclaim
	idleReclaimers[unitID]=true --add unit to register
	lastRegiInSecs=gameInSecs
	--echo("Registering unit "..unitID.." as idle")
	end

end
end
The lines with *** are new.
Factories no longer get a fight command set to themself.

But I have to say the original widget behaves a bit strange. Maybe because I did reload the widget a few times but builders would only moved to reclaim when "triggered" by other events. ie conbots sit next to wrecks -> do not start reclaiming. Then I make a windmill with the com and they start reclaiming? Maybe it was just the "do not move selected units" but it was a bit strange. But even manually giving a fight-command directly on the unit never triggered reclaiming for me (tested in BA 7.19), I had to click the ground next to it...

Anyway that is all unchanged and if you replace the UnitIdle function with above thing everything will work as before just that it does nothing with factories.

Re: Auto reclaim heal assist

Posted: 21 Dec 2010, 11:36
by klapmongool
It works, thanks!

About the strange behaviour; the widget probably could be less buggy but actually in normal gameplay what you describe isnt a problem (you'll be issuing commands anyway).