It was painful but I think I managed to get something that works. It might be done better (for some reason I had to use isatdestination rather than moveconvoy so it's probably doing lots of unecessary tests but I'm not skilled enough so... feel free to try and edit/optimise.
As usual backup your files then in the relevant (named below) lua files:
I) in scriptamericaeuro 1936 find the convoy table where you'll add waypoints and waypoint lists:
1) For every US to France/UK route add what's in blue below
2) For Every US to USSR route add what's in blue below
3) For Every Suez to US or UK (and maybe GERMANY?) routes add what's in blue below
II) in RedAI_Global:
1) find the function AIUnitControl find AI: fleet an add what's in blue below
2) find the function IsAtDestination find AI: fleet an add what's in blue below
Then jump to the Convoy function near the end and add these functions
and
III) Then in Redsupplyroutes find the function InitConvoyUnit and add what’s in blue again near the end of the function
unit:SetMoves(0) -- don't move on first turn
return true
IV) Lastly find the Order types in RedDefineRules and add
I hope I didn't forget anything, good luck I've not seen a single convoy crash since.
Things worth checking for those better at coding than me:
1) Do the various waypoint/move things in moveconvoy or moveunit
2) Insert a distance test in IsAtDestination so that convoy don't check when they are 3 or more turns away from the harbour/waypoint
As usual backup your files then in the relevant (named below) lua files:
I) in scriptamericaeuro 1936 find the convoy table where you'll add waypoints and waypoint lists:
1) For every US to France/UK route add what's in blue below
Spoiler :
[US_TO_FRANCE] = ((snip))
RandomDestination = false, -- false : sequential try in destination list
((end snip))
RandomDestination = false, -- false : sequential try in destination list
WaypointList = { {X=35, Y=40}, }, -- waypoints
RandomWaypoint = false,
CivID = FRANCE, -- ((if France, other wise what you paste ends before Civ UK for instance))((end snip))
2) For Every US to USSR route add what's in blue below
Spoiler :
RandomDestination = false, -- false : sequential try in destination list
WaypointList ={ {X=33, Y=33}, {X=66, Y=76}, },
RandomWaypoint = false,
CivID = USSR,
3) For Every Suez to US or UK (and maybe GERMANY?) routes add what's in blue below
Spoiler :
RandomDestination = false, -- false : sequential try in destination list
WaypointList ={ {X=55, Y=23}, },
RandomWaypoint = false,
CivID = XXX,
CivID = XXX,
RandomWaypoint = false,
CivID = XXX,
II) in RedAI_Global:
1) find the function AIUnitControl find AI: fleet an add what's in blue below
Spoiler :
if g_UnitData[unitKey].OrderType then
if g_UnitData[unitKey].OrderType == RED_CONVOY or g_UnitData[unitKey].OrderType == RED_CONVOY_WAYP1 or g_UnitData[unitKey].OrderType == RED_CONVOY_WAYP2 then
MoveConvoy(unit)
elseif g_UnitData[unitKey].OrderType == RED_MOVE_TO_EMBARK then
MoveToEmbark(unit) -- reinforcement en route
if g_UnitData[unitKey].OrderType == RED_CONVOY or g_UnitData[unitKey].OrderType == RED_CONVOY_WAYP1 or g_UnitData[unitKey].OrderType == RED_CONVOY_WAYP2 then
MoveConvoy(unit)
elseif g_UnitData[unitKey].OrderType == RED_MOVE_TO_EMBARK then
MoveToEmbark(unit) -- reinforcement en route
2) find the function IsAtDestination find AI: fleet an add what's in blue below
Spoiler :
if g_UnitData[unitKey].OrderType == RED_CONVOY then ((snip: jump to the end of the red convoy part so that this if, and insert before the first elseif))
Dprint(" - Can't unload !", bDebug)
end
end
end
end
elseif g_UnitData[unitKey].OrderType == RED_MOVE_TO_EMBARK then((snip))
Dprint(" - Can't unload !", bDebug)
end
end
end
end
elseif g_UnitData[unitKey].OrderType == RED_CONVOY_WAYP1 then
local routeID = g_UnitData[unitKey].OrderReference
local firstWaypoint=GetConvoyFirstWaypoint(routeID)
local destination = g_UnitData[unitKey].OrderObjective
Dprint("Check if convoy has reached the first waypoint", bDebug)
local plotList = GetAdjacentPlots(plot, true) -- include central plot in list
for i, adjacentPlot in pairs(plotList) do
Dprint("begins proximity check("..firstWaypoint.X..","..firstWaypoint.Y, bDebug) if destination.X == adjacentPlot:GetX() and destination.Y == adjacentPlot:GetY() then
Dprint("At first waypoint", bDebug)
local secondWaypoint = GetNextConvoyWaypoint(routeID, firstWaypoint)
Dprint("Check if second waypoint exists", bDebug)
if secondWaypoint then
g_UnitData[unitKey].OrderType = RED_CONVOY_WAYP2
g_UnitData[unitKey].OrderObjective = secondWaypoint
MoveUnitTo (unit, GetPlot (secondWaypoint.X, secondWaypoint.Y ))
Dprint("Moving to second WP", bDebug)
else
g_UnitData[unitKey].OrderType = RED_CONVOY
local newdestination = GetConvoyDestination(routeID) -- wil print testing possible destination
g_UnitData[unitKey].OrderObjective = newdestination
MoveUnitTo (unit, GetPlot (newdestination.X, newdestination.Y ))
Dprint("Moves to destination", bDebug)
end
else
MoveUnitTo (unit, GetPlot (firstWaypoint.X, firstWaypoint.Y ))
Dprint("Moves to first waypoint", bDebug)
end
end
elseif g_UnitData[unitKey].OrderType == RED_CONVOY_WAYP2 then
local routeID = g_UnitData[unitKey].OrderReference
local firstWaypoint=GetConvoyFirstWaypoint(routeID)
local secondWaypoint = GetNextConvoyWaypoint(routeID, firstWaypoint)
g_UnitData[unitKey].OrderObjective = secondWaypoint
local destination = g_UnitData[unitKey].OrderObjective
Dprint("Check if second waypointis nearby", bDebug)
local plotList = GetAdjacentPlots(plot, true) -- include central plot in list
for i, adjacentPlot in pairs(plotList) do
if destination.X == adjacentPlot:GetX() and destination.Y == adjacentPlot:GetY() then
Dprint("At second WP", bDebug)
g_UnitData[unitKey].OrderType = RED_CONVOY
local newdestination = GetConvoyDestination(routeID)
g_UnitData[unitKey].OrderObjective = newdestination
MoveUnitTo (unit, GetPlot (newdestination.X, newdestination.Y ))
Dprint("Moving to destination", bDebug)
else
MoveUnitTo (unit, GetPlot (secondWaypoint.X, secondWaypoint.Y ))
Dprint("moving to second WP", bDebug)
end
end
local routeID = g_UnitData[unitKey].OrderReference
local firstWaypoint=GetConvoyFirstWaypoint(routeID)
local destination = g_UnitData[unitKey].OrderObjective
Dprint("Check if convoy has reached the first waypoint", bDebug)
local plotList = GetAdjacentPlots(plot, true) -- include central plot in list
for i, adjacentPlot in pairs(plotList) do
Dprint("begins proximity check("..firstWaypoint.X..","..firstWaypoint.Y, bDebug) if destination.X == adjacentPlot:GetX() and destination.Y == adjacentPlot:GetY() then
Dprint("At first waypoint", bDebug)
local secondWaypoint = GetNextConvoyWaypoint(routeID, firstWaypoint)
Dprint("Check if second waypoint exists", bDebug)
if secondWaypoint then
g_UnitData[unitKey].OrderType = RED_CONVOY_WAYP2
g_UnitData[unitKey].OrderObjective = secondWaypoint
MoveUnitTo (unit, GetPlot (secondWaypoint.X, secondWaypoint.Y ))
Dprint("Moving to second WP", bDebug)
else
g_UnitData[unitKey].OrderType = RED_CONVOY
local newdestination = GetConvoyDestination(routeID) -- wil print testing possible destination
g_UnitData[unitKey].OrderObjective = newdestination
MoveUnitTo (unit, GetPlot (newdestination.X, newdestination.Y ))
Dprint("Moves to destination", bDebug)
end
else
MoveUnitTo (unit, GetPlot (firstWaypoint.X, firstWaypoint.Y ))
Dprint("Moves to first waypoint", bDebug)
end
end
elseif g_UnitData[unitKey].OrderType == RED_CONVOY_WAYP2 then
local routeID = g_UnitData[unitKey].OrderReference
local firstWaypoint=GetConvoyFirstWaypoint(routeID)
local secondWaypoint = GetNextConvoyWaypoint(routeID, firstWaypoint)
g_UnitData[unitKey].OrderObjective = secondWaypoint
local destination = g_UnitData[unitKey].OrderObjective
Dprint("Check if second waypointis nearby", bDebug)
local plotList = GetAdjacentPlots(plot, true) -- include central plot in list
for i, adjacentPlot in pairs(plotList) do
if destination.X == adjacentPlot:GetX() and destination.Y == adjacentPlot:GetY() then
Dprint("At second WP", bDebug)
g_UnitData[unitKey].OrderType = RED_CONVOY
local newdestination = GetConvoyDestination(routeID)
g_UnitData[unitKey].OrderObjective = newdestination
MoveUnitTo (unit, GetPlot (newdestination.X, newdestination.Y ))
Dprint("Moving to destination", bDebug)
else
MoveUnitTo (unit, GetPlot (secondWaypoint.X, secondWaypoint.Y ))
Dprint("moving to second WP", bDebug)
end
end
elseif g_UnitData[unitKey].OrderType == RED_MOVE_TO_EMBARK then((snip))
Then jump to the Convoy function near the end and add these functions
Spoiler :
function GetConvoyFirstWaypoint(routeID, bForceSequential) -- return {X=x ,Y=y}
local bDebug = true
Dprint(" - Check convoy first waypoint...", bDebug)
local Waypoint = nil
local WaypointList = g_Convoy[routeID].WaypointList
if not WaypointList then
Dprint(" - no waypoints for this route...", bDebug)
return nil -- this route has no waypoint...
end
if g_Convoy[routeID].RandomWaypoint and not bForceSequential then
-- route use one random waypoint
Dprint(" - search random waypoint route...", bDebug)
local randPlot = math.random( 1, #waypointList )
Waypoint = WaypointList[randPlot]
else
-- route use fixed waypoint
Dprint(" - search first waypoint...", bDebug)
Waypoint = WaypointList[1]
end
return Waypoint
end
local bDebug = true
Dprint(" - Check convoy first waypoint...", bDebug)
local Waypoint = nil
local WaypointList = g_Convoy[routeID].WaypointList
if not WaypointList then
Dprint(" - no waypoints for this route...", bDebug)
return nil -- this route has no waypoint...
end
if g_Convoy[routeID].RandomWaypoint and not bForceSequential then
-- route use one random waypoint
Dprint(" - search random waypoint route...", bDebug)
local randPlot = math.random( 1, #waypointList )
Waypoint = WaypointList[randPlot]
else
-- route use fixed waypoint
Dprint(" - search first waypoint...", bDebug)
Waypoint = WaypointList[1]
end
return Waypoint
end
and
Spoiler :
function GetNextConvoyWaypoint(routeID, previousWaypoint, bForceSequential) -- return {X=x ,Y=y}
local bDebug = true
Dprint(" - testing next destination waypoint...", bDebug)
local sdwaypoint = nil
local WaypointList = g_Convoy[routeID].WaypointList
if not WaypointList then
Dprint(" - no waypoints for this route...", bDebug)
return nil -- this route has no waypoint... How do we get here ?
end
--if g_Convoy[routeID].RandomWaypoint and not bForceSequential then
-- route use one random waypoint
--Dprint(" - only one random waypoint for this route !", bDebug)
--return nil
--else
-- route use fixed waypoint
for i, Waypoint in ipairs(WaypointList) do
if Waypoint == previousWaypoint and i+1 <= #WaypointList then -- manquait un = ?
Dprint(" - set next waypoint !", bDebug)
sdwaypoint = WaypointList[i+1]
end
end
--end
return sdwaypoint
end
local bDebug = true
Dprint(" - testing next destination waypoint...", bDebug)
local sdwaypoint = nil
local WaypointList = g_Convoy[routeID].WaypointList
if not WaypointList then
Dprint(" - no waypoints for this route...", bDebug)
return nil -- this route has no waypoint... How do we get here ?
end
--if g_Convoy[routeID].RandomWaypoint and not bForceSequential then
-- route use one random waypoint
--Dprint(" - only one random waypoint for this route !", bDebug)
--return nil
--else
-- route use fixed waypoint
for i, Waypoint in ipairs(WaypointList) do
if Waypoint == previousWaypoint and i+1 <= #WaypointList then -- manquait un = ?
Dprint(" - set next waypoint !", bDebug)
sdwaypoint = WaypointList[i+1]
end
end
--end
return sdwaypoint
end
III) Then in Redsupplyroutes find the function InitConvoyUnit and add what’s in blue again near the end of the function
Spoiler :
unit:SetMoves(0) -- don't move on first turn
local firstWaypoint = GetConvoyFirstWaypoint(routeID)
Dprint(" - Tentative de création de point de navigation...", bDebug)
if not firstWaypoint then
Dprint(" - Pas de point de navigation...", bDebug)
else
g_UnitData[unitKey].OrderType = RED_CONVOY_WAYP1
g_UnitData[unitKey].OrderObjective = firstWaypoint
Dprint(" - Point de navigation créé...", bDebug)
end
Dprint(" - Tentative de création de point de navigation...", bDebug)
if not firstWaypoint then
Dprint(" - Pas de point de navigation...", bDebug)
else
g_UnitData[unitKey].OrderType = RED_CONVOY_WAYP1
g_UnitData[unitKey].OrderObjective = firstWaypoint
Dprint(" - Point de navigation créé...", bDebug)
end
return true
IV) Lastly find the Order types in RedDefineRules and add
Spoiler :
RED_CONVOY_WAYP1 = 10
RED_CONVOY_WAYP2 = 11
RED_CONVOY_WAYP2 = 11
I hope I didn't forget anything, good luck I've not seen a single convoy crash since.
Things worth checking for those better at coding than me:
1) Do the various waypoint/move things in moveconvoy or moveunit
2) Insert a distance test in IsAtDestination so that convoy don't check when they are 3 or more turns away from the harbour/waypoint