New table related problem (well, not technically new):
I now GetAllUnits () [Returns an array containing the unitIDs of all visible units. ] every tick, throw each instance of any 'new' units in a master table using the unitID as the key, and then perform all actions based on my master table (or tables within).
My issue now is trying with trying maneuver ships around I've found that it wants to give multiple orders to a single ship. I'm thinking the 'problem' is caused by the way I am telling it to give orders to ships, which is based on distance to enemy ships. Specifically, if myUnit is within 10-21 distance units of enemyUnit, then move to x,y. I don't yet know how to sort the tables so each of my ships moves based on which enemy ships is closest. Therefore, it seems to pick psuedo randomly from any number of enemy ships within 10-21 distance units vs the closest.
I think another piece of the problem comes from the fact that I have leaders and followers in order to keep formations intact during movement and wait for ships to become 'idle' (velocity of zero) before giving them status of a leader (all other surrounding ships become followers regardless of velocity). However, there are times when all ships come to a stop at the same time and perhaps searching through the tables happens so fast, multiple ships become leaders when I'm really only looking to have a couple.
I'm sure this is probably horribly ugly to anybody that has real knowledge of code, but here you go:
Sometimes this works all the way through the end of the game, but most of the time it hangs fairly quickly. It's definitely not combat related as I've ran it while allied to the cpu (allowing my ships to move without fighting/dieing). Feel free to criticize anything you see.
Code: Select all
main_unit_table = {}
function RadarSweep()
for loop, do some stuff like get new units, update old units, etc ...
main_unit_table[unit].Long = unit:GetLongitude()
main_unit_table[unit].Lat = unit:GetLatitude()
main_unit_table[unit].Speed = unit:GetVelocity()
main_unit_table[unit].Team = unit:GetTeamID()
main_unit_table[unit].Type = unit:GetUnitType()
end
MoveFleet()
end
function MoveFleet()
StartLongTask(function()
for b, v in pairs(main_unit_table) do
local us = GetOwnTeamID()
if main_unit_table[b].Team ~= us then
if main_unit_table[b].Condition ~= "Killed" then
if (main_unit_table[b].Type == "Carrier" or main_unit_table[b].Type == "BattleShip") then
local ex, ey = main_unit_table[b].Long, main_unit_table[b].Lat -- Get position of visible/alive enemy ship
for c, v in pairs(main_unit_table) do
if main_unit_table[c].Team == us then
if (main_unit_table[c].Type == "Carrier" or main_unit_table[c].Type == "BattleShip") then
local MyCVx, MyCVy = main_unit_table[c].Long, main_unit_table[c].Lat
if main_unit_table[c].Condition ~= "Killed" then
if (GetDistance(MyCVx, MyCVy, ex, ey) > 15 and GetDistance(MyCVx, MyCVy, ex, ey) < 21) then
if main_unit_table[c].Speed == 0 then -- Get position of non-dead non-moving unit
if MyCVx > ex then
CVx = ex + 11
else
CVx = ex - 11
end
if MyCVy > ey then
CVy = ey + 11
else
CVy = ey -11
end
if IsSea(CVx, CVy) then
c:SetMovementTarget(CVx, CVy) -- Set new x,y (move toward/away from enemy)
main_unit_table[c].Mode = "FleetLeader" -- Set unit as leader
--Start following========================================================
for d, v in pairs(main_unit_table) do -- combine close units into fleet, follow FleetLeader
if main_unit_table[d].Team == us then
if (main_unit_table[d].Type == "Carrier" or main_unit_table[d].Type == "BattleShip") then
local MyCVbx, MyCVby = main_unit_table[d].Long, main_unit_table[d].Lat
if main_unit_table[c].Condition ~= "Killed" then
if main_unit_table[d].Mode ~= "FleetLeader" then
if GetDistance(MyCVx, MyCVy, MyCVbx, MyCVby) < 16 then
local CVbx, CVby = MyCVbx + CVx - MyCVx, MyCVby + CVy - MyCVy
if IsSea(CVbx, CVby) then
d:SetMovementTarget(CVbx, CVby) -- Stay in formation with fleet leader
main_unit_table[d].Mode = "FleetFollower"
end
end
end
end
end
end
end -- For end
YieldLongTask()
end
end
end
end
end
end
end -- For End
YieldLongTask()
end
end
end
end -- For End
YieldLongTask()
end
)
end
I put in some whiteboard code to show which of my units was getting an order, which enemy unit/s it was responding to, and where exactly it was being told to go. Obviously, it will travel to the 'last' valid (IsSea = true) x,y it is given. I would expect to see only one line going from myUnit to one enemyUnit along with a single line showing the new x,y, instead of the multiple reactions seen here. A lot of the time it does work that way (got lucky with this image).