Hehe, I was just watching it play out with a similar thought, although I added teamID to see if it was limited to my team or not.

The error only happens with Nukes, Fighters, and Bombers, all of which are included in GetAllUnits(). I wonder if the problem lies in they way some (not all O_o) Nukes, Fighters, and Bombers recive an ID in the 60000+ range instead of using the next available number. Then when it tried to change the condition, it uses the normal id vs the 60000+ id..

Please use version 1.56 instead, and let me know if your problem persists.Also, Ids in the 60k+ range are deliberate, however there was a bug with theconversion in an earlier version (probably 1.51b2 is affected, too).

Cheers,Robin

2009/8/7 Kai K.

> Hi Guys,>>>> in the current version 1.51(build2) all calls to retrieve unit IDs return> wrong ids for Fighters and Bombers. The returned IDs are in the 60000+> range, Using these ids as arguments does not work, however using the ids> show during debug mode does.>>>> Anyone noticed this as well? This might be a solution to Spooqs question> posted last month or so.>>>> With best regards

Update: I have implemented a workaround; simply create a new entry for non-existent units when thy die (vs when they are first seen). This isn't ideal, but get's rid of the errors.

Only seems to happen with enemy Fighters/Bombers and my own Nukes (some, not all).

Hopefully this won't affect coding down the road (like calculating success ratio for hitting cities, keeping track of enemy bombers spotted/downed, and the number of fighters in a give area -to determine fleet strength/airbase proximity-, etc)

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.

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).

Loops through enemy ships that aren't dead, loops through my ships that are within a certain distance and then gives my ship (one that's not moving already) a new x,y based on the enemy ship's x,y. I.e., keep my ships exactly 11 units away from your ships. Once one of my ships is moving, loop through my ships again, find any close to that moving ship, and follow it into battle (keep formation).

if main_unit_table[b].Team ~= us and main_unit_table[b].Condition ~= "Killed" and (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 and (main_unit_table[c].Type == "Carrier" or main_unit_table[c].Type == "BattleShip") then

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 and (main_unit_table[d].Type == "Carrier" or main_unit_table[d].Type == "BattleShip") 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 -- For end YieldLongTask() end end end end -- For End YieldLongTask()end

I think I may have broken the code though since I haven't tested it and had extra stuff at the end. You could make it more readable by turning the chunky if statements into a function, particularly since it seems to change the similar properties.

EDIT: And yeah, what martin said.

EDIT2: Whoops, broken whitespace.

Uplink help: Check out the Guide or FAQ.
Latest Uplink patch is v1.55.

Ok, I'm trying to get a grasp on using functions instead of IF statements. I'm trying to figure out how to use your suggested code to return different/multiple types (there are 9 types). This doesn't work (it only displays carriers).

Edit2: Ok, I think I found part of the problem; it seems I had two BattleShips as part of the same fleet (by accident) even though my intention is to have no two ships in the same fleet. Therefore, trying to give orders to one ship in the fleet crossed with trying to give separate orders to the other ship (which you can't do). I still believe the other half of the issue is because I don't know how to tell it to only respond to the closest enemy ship.

Any ideas on how to implement this (determine which enemy ship is nearest to each of my ships as I give them orders)?

I've decided to kind of 'start over' and rework all of my code to clean things up a bit and hopefully work out a solution to the above along the way.

My first step was to re-replace the original co-routine with martin's and once again found it to be fast. However, on my work laptop (2.1 Core2 Duo, 2GB, X2300 Mobility Radeon) every time RadarSweep() was called and the CPU sent out multiple planes at once, it would 'hiccup' (go from 60 to 40+ fps). This didn't happen when multiple ships/ground units appeared at the same time, only with planes and only when there were multiple ones. When I replaced the co-routine, it improved slightly, but was still there. On my home computer, it almost always hangs instantly (with new co-routine) no matter the vsync setting. When it doesn't hang, it does everything super fast (e.g. places all ships instantly so they become six-ship fleets, unintentionally).