* Beta release: Reclaim stopper widget

* Beta release: Reclaim stopper widget

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

Moderator: Moderators

User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

* Beta release: Reclaim stopper widget

Post by Floris »

It needs some more testing

Example video:
http://www.youtube.com/watch?v=jwwnBpt_u2I

Features:
- It tries to reclaim buildings till 2% or 3%, but it varies depending on your ping, system speed and how many reclaimers you use (it makes predictions)
- Hold the 'q' key down when giving the reclaim command will activate it
- It supports multiple reclaimer units too. (results may vary in %)
- It has a clear graphical indicator which buildings are going to be reclaimed by this widget
- I tested it on a relatively fast pc, so on slow machines/late game situations it might be more buggy, plz let me know if and when this is the case

Any contributions in the form of bugreports, suggestions or written code adjustments are welcome!



----------------------------------------------------------------------------
Since I tech a lot and do that in the company of a rezbot I want it to be effective as possible. I use the rezbot to reclaim solars, but not fully. I leave these buildings at the lowest health possible so I can reclaim them instantly when I need the metal. Then after that the same for adv solars, and maybe even a fusion to upgrade quicker to adv fusion.

For this reason I need to have this widget.

The rezbot needs to stop reclaiming the building when it has 1% health left and skip to the next queued command in line.

A problem I have is that until now I never saw LUA code and lack the knowledge to make it all happen. But I started anyway, and this is what I got already:
-- removed --
Last edited by Floris on 04 Oct 2021, 02:11, edited 9 times in total.
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Reclaim stopper widget

Post by knorke »

You need to figure the % of each wreck a reclaimer is reclaiming. Just getting all wrecks is not needed, you only need the ones being reclaimed by your own reclaimers.
Here someone started something similiar but did not finish it seems:
http://springrts.com/phpbb/viewtopic.php?f=23&t=24593
Maybe you can combine with yours.

also you can use

Code: Select all

[code]bla
to keep formating[/code]
or even better pastebin.ca and select "lua synthax"

Your reclaim-stopper-code should not be in DrawWorld()
DrawWorld is called whenever spring renders a new scene and usually used to draw UI stuff.
Instead use GameFrame (frame) and then you can even chose to only check for reclaimers every n-th frame or so: http://answers.springlobby.info/questio ... -explained
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: Reclaim stopper widget

Post by Floris »

Well this is not about wreckage, but about operational buildings.
(see below: nr. 3 is the big problem here)


1. First I need to know how I can store the reclaimer (unitID) combined with the building (unitID) when the 'Q' key is hold down while the reclaim command/que is given. (something with arrays)

2. (no problem) I know when a building has 1 % health left

3. Then I need to know how I can stop the reclaimer (I stored) and let it move on with the next command in their queue
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Reclaim stopper widget

Post by knorke »

you could store reclaimers like:
local reclaimers = {}
and then do
reclaimer[reclaimerUnitID] = unitIDthatIsBeingReclaimed

to delete the entry just set it to nil (=nothing, void)

About Q being held down when command is given:
Spring.GetKeyState
http://springrts.com/wiki/Lua_UnsyncedR ... ot-.29Keys

Use that in
AllowCommand()
http://springrts.com/wiki/LuaCallinReturn#Unit-Specific:
Something like
if (cmdTag == CMD.RECLAIM and Spring.GetKeyState ("q") == true) then bla end


3) no idea, but is possible. Probally use Spring.GetUnitCommands, then edit the returned to table (delete first entry) and put it back somehow
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: Reclaim stopper widget

Post by Floris »

Alright

I already found out I needed Spring.GetKeyState before I guess, but I cant find the documentation that explains how to use it.

Does Spring.GetKeyState('q') returns true if it is pressed?

But with that knowledge i cant do anything yet. With what call-in can this function be used? Like the call-in that is triggered when a reclaim command is given: function widget:CommandsChanged() ?

But then i alsno need to find out what units are selected and at which unit is clicked and that it is a reclaim command, not a repair commadn for example.


Eeeks, help!?
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Reclaim stopper widget

Post by knorke »

With what call-in can this function be used?
I would use in the callin-function that is called whenver a unit is given a new command, I think that is AllowCommand()


Does Spring.GetKeyState('q') returns true if it is pressed?
Yes. I would think so, though you might have to use "q", "Q" or 'Q' maybe.
Or maybe the scancode (a number) of the letter.(unlikely)
alsno need to find out what units are selected
No, AllowCommand will be called for every unit that is given a new order, so no need to get selected unit.
at which unit is clicked and that it is a reclaim command
reclaim target:
http://springrts.com/phpbb/viewtopic.php?f=23&t=24593 see post by Niobium
But I think reclaim target will be somewhere in the paremeters in AllowCommand anyway.
http://springrts.com/wiki/Lua_CMDs

From this thread you can probally steal stuff as well:
http://springrts.com/phpbb/viewtopic.php?f=23&t=24846

I cant find the documentation that explains how to use it.
There is none :roll:
Only way is trial&error to search forum, read engine source or other widgets.
Did I mention trial&error?
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: Reclaim stopper widget

Post by Floris »

Yey, got it almost finished,

Everything works, exept the part that stops/inserts the queue.

- First I backup the reclaimers queue with: Spring.GetUnitCommands()
- Then I give it a STOP command with :Spring.GiveOrderToUnit(unitId, CMD.STOP, {}, {})
- But here it fails: Spring.GiveOrderToUnit(unitId, CMD.INSERT, ..., ....
it says the parameters are incorrect, i tried: CMD.OPT_SHIFT and currentCommand.options already

my source is this info: http://springrts.com/wiki/Lua_CMDs


Anmy clue what I can do?


see the whole part below: (it starts with looping every reclaimer that is reclaiming the unit)
for reclaimerUnitID,value in next,targetUnitReclaimers,nil do
local unitCommands = Spring.GetUnitCommands(reclaimerUnitID)
local queuePlace = 0
Spring.GiveOrderToUnit(reclaimerUnitID, CMD.STOP, {}, {});
if #unitCommands > 1 then
for i=1,#unitCommands do
if i > 1 then
local currentCommand = unitCommands
Spring.GiveOrderToUnit(reclaimerUnitID, CMD.INSERT, {queuePlace,currentCommand.id,CMD.OPT_SHIFT,currentCommand.params}, {"alt"});
queuePlace = queuePlace-1
end
end
end
targetUnits[targetUnitID][reclaimerUnitID] = nil
end
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: Reclaim stopper widget

Post by Niobium »

Floris wrote:...
I wouldn't use stop commands or insert commands when you just want to remove the reclaim order. The best way of which is:

Spring.GiveOrderToUnit(uID, CMD.REMOVE, {reclaimCmd.tag}, 0)
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: Reclaim stopper widget

Post by Floris »

Thank you 2, I've tried to do something with that function myself but it didnt work, this is so much easier!


The widget is functional now although it's reclaim speed differs on each server/client. There is a delay that makes the reclaimers reclaim too long sometimes, so it lacks the acuracy to stop it at values like 0...3%
The delay can be 5% too late, but thats only me testing.


Problem with multiple reclaimers:
In LUA you can rount the rows in a table/array by adding a hash in front of the variable name. Thats really nice, but I couldnt use it anywher else than in an if statement. I want to use it to multiply the minimum reclaimheath by the number of reclaimers. If I can't do this then the target unit is reclaimed before I can stop it.



I have been thinking of another approach:
- after reclaiming the first 50% you have a pretty good idea how much time the other 50% will take to reclaim and you can time when to abort, or say the last 10% will be reclaimed by a single reclaimer which you imediately test its reclaimspeed somehow. Maybe measuring the amounth of health per second. and stop right in time. (but then... would the stop cmd delay swtill happen?)


Anny suggestions, knowhow or tips in that direction? Cause i dont feel the widget is reliable enough for the masses.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: Reclaim stopper widget

Post by Niobium »

Floris wrote:The widget is functional now although it's reclaim speed differs on each server/client. There is a delay that makes the reclaimers reclaim too long sometimes, so it lacks the acuracy to stop it at values like 0...3%
The delay can be 5% too late, but thats only me testing.
Units reclaim at the same rate they would build, so you can work out exact times. The problem is that when you give the command to remove reclaim orders, that command has to travel to the server before it is processed, so obviously you need to account for this delay.

Code: Select all

local _, _, _, _, _, myPing = spGetPlayerInfo(spGetMyPlayerID())
The code above will give an estimate of your current ping, which will get you a fair bit of accuracy, just add 50-100ms to it for your calculations and you'll be good.
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Reclaim stopper widget

Post by knorke »

which you imediately test its reclaimspeed somehow. Maybe measuring the amounth of health per second. and stop right in time.
Easier, You can read all properties of a unit, also its reclaimSpeed.
For the solars you would want to read their buildTime.
http://springrts.com/wiki/Lua_UnitDefs
Then you could calculate how long it takes to reclaim the unit. Maybe health or cost also influences how long it takes to reclaim something. The ETA widget might be good to look at.
User avatar
manolo_
Posts: 1370
Joined: 01 Jul 2008, 00:08

Re: Reclaim stopper widget

Post by manolo_ »

floris upload the widget when you are done, i will upp it then to the wdb, because it is a good idea
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: Reclaim stopper widget

Post by Floris »

Alright, will do manolo!


1) I still need to know how I can use #arrayvariable anywhere else than just as comparison in an if statement.

2) I've got another question. Senna just told me nano's build 10% slower if they guard a builder.
Now I need to know if it's possible to disable the nanos/builders from healing damaged units so they can patrol and build at full speed.
(If this is not possible then the player has to mannually select the nanos and rightclick on the initiated buildings and then shift-rightclick on the builder again so it still uses 100% nanopower without auto-healing the partially reclaimed buildings.)

3) To compensate reclaim stop delays cause of a high ping I need to know a little bit more about how to caculate the reclaim stop delay including the reclaimspeed or the reclaimer, the buildspeed of the building and the user's ping. Or even if I need to know and use the framerate at which the script is executed (with other words what the delay of function widget:DrawWorld() is)

thanks in advance!
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: Reclaim stopper widget

Post by Floris »

4) I m getting an error with the code below:

Error msg: "Attempt to index local 'unitCommand; (a number value) at line (x)

Code: Select all

local unitCommands = Spring.GetUnitCommands(reclaimerunitId)
if (#unitCommands>0) then 
  for unitCommandId,unitCommand in next,unitCommands,nil do
(x) if unitCommand.id == 90 then        -- if its a reclaim command
      ... more code here ...
    end
  end
end
Regret
Posts: 2086
Joined: 18 Aug 2007, 19:04

Re: Reclaim stopper widget

Post by Regret »

EDIT: stupidity removed.
Last edited by Regret on 08 Jan 2011, 00:57, edited 1 time in total.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: Reclaim stopper widget

Post by Niobium »

Floris wrote:1) I still need to know how I can use #arrayvariable anywhere else than just as comparison in an if statement.

2) I've got another question. Senna just told me nano's build 10% slower if they guard a builder.
Now I need to know if it's possible to disable the nanos/builders from healing damaged units so they can patrol and build at full speed.
(If this is not possible then the player has to mannually select the nanos and rightclick on the initiated buildings and then shift-rightclick on the builder again so it still uses 100% nanopower without auto-healing the partially reclaimed buildings.)

3) To compensate reclaim stop delays cause of a high ping I need to know a little bit more about how to caculate the reclaim stop delay including the reclaimspeed or the reclaimer, the buildspeed of the building and the user's ping. Or even if I need to know and use the framerate at which the script is executed (with other words what the delay of function widget:DrawWorld() is)
1) How to use in a loop

Code: Select all

for i = 1, #commands do
    local command = commands[i]
    <... do stuf with command ...>
end
2) Senna is incorrect. Guard is your best bet to avoid auto-heal.

3) :DrawWorld is called every time a frame is rendered, so if you are at 60 fps then :DrawWorld gets called 60 times per second. Having your code in :DrawWorld isn't the best place (unreliable calls per second, non-drawing code in drawing callin, etc), instead you should put it in :GameFrame(n), which gets called whenever spring updates anything (i.e. unit build progresses), between spring calling :GameFrame nothing in the game changes (so there is no need for additional checks in other callins)

My recommendation for check logic:

Code: Select all

myPing = myPing + 0.05
if targetHP/targetMaxHP - myPing * reclaimerSpeed/targetBuildTime < 0.01 then
    <issue remove-reclaim order>
    <stop watching this target-reclaimer pair>
end
Just need to adjust/test the 50ms ping adjustment and 0.01 target and you're done.

Also:
Regret wrote:Replace the previous line with

Code: Select all

for unitCommandId,unitCommand in ipairs(unitCommands) do
Don't use this, ipairs() is slow. Use the pattern in 1) instead.
Regret
Posts: 2086
Joined: 18 Aug 2007, 19:04

Re: Reclaim stopper widget

Post by Regret »

Niobium wrote:Don't use this, ipairs() is slow. Use the pattern in 1) instead.
I'm not sure what I was thinking when I suggested that, it's a simple array with ordered numbered indexes. T_T
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: Reclaim stopper widget

Post by Floris »

--- oh nevermind ---
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: Reclaim stopper widget

Post by Floris »

I finished it, it became really something very usefull.

No moar reclaiming accidently my fusion and be without e production!
8 mins fusion becomes closer to your everyday reality, at least for me.

- it tries to reclaim buildings till 2% or 3%, but it varies depending on your ping, system speed and how many reclaimers you use (it makes predictions)
- hold the 'q' key down when giving the reclaim command
- It supports multiple reclaimer units too. (results may vary in %)
- it has a nice graphical indicator of which buildings are going to be reclaimed by this widget
- i tested it on a relatively fast pc, so on slow machines/late game situations it might be more buggy, plz let me know if and when this is the case

Any contributions in the form of bugreports, suggestions or written code adjustments are welcome! And also more info on how/when to get this widget in the downloader when its bugfree.

Download and test it here:
---
Last edited by Floris on 04 Oct 2021, 02:11, edited 1 time in total.
User avatar
Floris
Posts: 611
Joined: 04 Jan 2011, 20:00

Re: * Beta release: Reclaim stopper widget

Post by Floris »

Ok beta testers please
Post Reply

Return to “Lua Scripts”