Check if trade unit's route is internal or external?

pineappledan

Deity
Joined
Aug 9, 2017
Messages
10,122
Location
Alberta, Canada
I have been stumped with a trade unit problem for a while now.

I am trying to make a Community Patch compatible civ. I want internal land trade units to claim neutral territory they pass over.

Community Patch settings:
API_LUA_EXTENSIONS = 1
API_TRADEROUTES = 1

I tried this code:
Code:
local iCanada = GameInfoTypes.CIVILIZATION_CANADA

function YorkFactoryExpress(iPlayer, iUnit, iX, iY)
    local pPlayer = Players[iPlayer]
    if pPlayer:GetCivilizationType() ~= iCanada then return end

    local pUnit = pPlayer:GetUnitByID(iUnit)
    if (pUnit == nil or pUnit:IsDelayedDeath()) then return end

    if pUnit:GetUnitType() == GameInfoTypes.UNIT_CARAVAN then

        if (Game.GetTradeRoute(pUnit:GetTradeRouteIndex()).ToCivilizationType == iCanada) then

        local pPlot = pUnit:GetPlot()
            if pPlot:GetOwner() == -1 then
                pPlot:SetOwner(pPlayer, pPlayer:GetCapitalCity():GetID(), 1, 1)
            end
        end
    end
end
Any attempt to use GetTradeRouteIndex() results in a CTD.

I tried using pUnit:LastMissionPlot():GetOwner() instead, to see if the destination city could be discerned that way, but no dice.

Anyone have any other ideas for how to check if the caravan is an internal trade route?
 
Last edited:
API_TRADEROUTES was originally added by me, and it's used in three mods I regularly play with, so I know the original code isn't broken.

If you're getting CTDs in VP, you'd be best to post in the VP sub-forum
 
I did. They told me my code was poorly optimized, then recommended that I attach the debugger to my civ game, then didn't tell me how to actually do that, then began ignoring my posts asking for explanation.

It could also be Game.GetTradeRoute(). If I comment out that line then the code works fine with no crash; the caravan claims territory it walks across as intended. I noticed infixo also made a trade UI mod which uses GetTradeRouteIndex() for VP, and I haven't heard people complaining of crashes, so I'm guessing there's something specific to how I'm trying to use this. Something specific to using the combination of these two functions, perhaps?
 
Last edited:
Unless you're a C++ programmer, attaching the debugger is a [insert derogatory word of choice] suggestion IMHO. Even if you jumped through all the hoops to do it, you're not going to understand what it's telling you.

Couple of suggestions
1) About the only way to crash Game.GetTradeRoute() [in my original code] is to send it an invalid trade route index. Now, while your code defends against that, it could still be that pUnit:GetTradeRouteIndex() is returning garbage, so split that line into
local iRouteIndex = pUnit:GetTradeRouteIndex();
print(string.format("Route index for unit %i of player %i is %i", pUnit:GetID(), pUnit:GetOwner(), iRouteIndex));
if (iRouteIndex == -1) then return; end
local pRoute = Game.GetTradeRoute(iRouteIndex);
if (pRoute == nil) then print(string.format("Route for unit %i of player %i is NIL", pUnit:GetID(), pUnit:GetOwner())); return; end
if (pRoute.ToCivilizationType == iCanada) then
etc
As this will defend against any possible garbage, and tell you when it happens!

2) Write/Test you mod against DLL-VMC v88 - the trade route API code in it has been stable for years. If your code works with it, then any crashes must be in the VP changes. At which point you'll need to decide what to do - debug VP on your own (by the sounds of it) or make compromises in your mod.

HTH
W

Edit: "while your code defends against that" - actually it doesn't … not fully. A caravan that has just been built, or has just finished it's assigned route and is waiting for another, won't have a valid route index, so will return -1 and that will crash the Game.GetTradeRoute() call
 
Last edited:
option 1 did it!
When the caravan first is created, it fires UnitSetXY, but doesn't have a trade route yet. The act of coming into existence fires the lua --> it returns a "-1" for traderouteindex() --> CTDs when that -1 is fed into Game.GetTradeRoute().

Thanks so much!
 
Top Bottom