Closed ForbodingAngel closed 8 years ago
A couple of ideas 1) Add a new behaviour to the engineers that gets high priority temporarily when UnitIdle has been called enough times. When activated, the behaviour would move them randomly away from their current position. 2) Modify taskqueuebehaviour to move the engineers around at the end of every taskqueue loop.
I'm glad it's working!
1) Honestly I don't know how to do that 2) Actually, after every completed task would do nicely, but once again, don't know how to do it. Do you have any examples?
Me too! :-D
Sidenote: I used to have the ability to insert waits (x number of frames/seconds/etc) before they progressed to the next item in the list but I don't have the line anywhere anymore. Do you happen to do anything similar in BA that I could use?
Thanks so much for making shard as a luaai a reality <3
Tbh I have a lot of issues with the taskqueue's repeating and no controls on how many of each building gets built. I will likely just make ai specific buildings and use unitrestricted to limit them. Crude, but it works :-)
about wait, it appears you would put something like this in the taskqueue:
{action = "wait", frames = 30}
see https://github.com/eronoobos/ShardSpringLua/blob/master/luarules/gadgets/ai/taskqueuebehaviour.lua#L112
Speaking of which, an action would probably be a good way to move your engineers around. I'll just expand the default taskqueuebehaviour to include a "move" action. You would then just insert something like this into your taskqueue:
{action = "move", x = 100, y = 200, z = 300}
While I'm at it, how about this also:
{action = "moverelative", x = math.random(-100, 100), y = math.random(-100, 100), z = math.random(-100, 100)}
i leave it up to you to give it a better random relative position
A BuildWithLimitedNumber function for taskqueues:
function BuildWithLimitedNumber(tmpUnitName, maxNumber)
if tmpUnitName == DummyUnitName then return DummyUnitName end
if maxNumber == 0 then return DummyUnitName end
local myUnits = game:GetUnits()
if myUnits then
local count = 0
for i = 1, #myUnits do
local myUnit = myUnits[i]
if myUnit:Name() == tmpUnitName then
count = count + 1
if count == maxNumber then
return DummyUnitName
end
end
end
end
return tmpUnitName
end
actually, make that
{ action = "move", position = {x=1, y=2, z=3} }
(or "moverelative")
this is just for consistency with how Shard deals with positions
https://github.com/eronoobos/ShardSpringLua/commit/41fbd6d5b4c468c8e48f2f9b06d95ed3551e31d2
let me know how it goes
Jesus, did you just pretty much solve all my issues? lol
I'll give it a shot, thanks :-D
That's what the boot behaviour is for, to take control and wait for the unit to leave the factory. A variation may choose to instead wait for the idle order, then issue a move order, and relinquish control on the second idle so that it goes elsewhere
But I'd rather not conflate task queues and solving this problem, especially when the boot behaviour was built for this very reason
Instead I believe a proper solution comes from the building algorithm.
Specifically, I would create a module that created a grid of points, and counted the units closest to each point to create a density map. Then, when building, the builder wouldn't search from its own location, it would first find the closest four points on the grid, and start the search from the highest density point, ignoring any that have more than a certain threshold to prevent overpopulation.
The result should be an expanding base that never gets too clogged, a natural upper limit on how far the building algorithm should search ( grid size/2 ), and a framework on which to hang weights and incentives, or other logic such as for defenses, etc
Of note, the attack handler module already has similar code, that code could be extracted out into another module, and we'd get all the additional benefits, such as negatively weighting areas by enemy forces, which would also prevent Shard from sending constructors into these areas to build inane things. It also simplifies attacking into the new problem of flattening that map and increasing density ( where enemy areas are negative density )
That indeed is a much better solution. And curse you, I am tempted to write it.
Regarding a variation on boot behaviour: If boot behaviour was activated every time the unit went idle, wouldn't that prevent taskqueues from ever building anything?
Boot behaviour is never meant to run once it's done it's job, which at the moment is to wait a number of frames to give the unit time to exit the factory, once it's ran it never runs again
Yes. I meant in the (unwritten) variation you suggested, which would activate when the unit is idle, and issue a move order away from itself.
Oh I see, every other idle.
This is my biggest issue. Shard engineers will sit in one spot just building stuff, many times not even leaving the build pad. That's not good at all :'(
Halp?
Got it working BTW. It was my customizations that were breaking it (you were right).