Faster Movement Along Trade Routes

Uighur_Caesar

Comandante en Jefe
Joined
Mar 14, 2015
Messages
1,227
Location
Florida
A civ I'm trying to make is supposed to give +2 Movement to Settlers (and colonists if playing with JFD's CCC) that start their turn on one of your trade routes. I'm trying to use Tomatekh's Garamantes' code as a reference since it gives units starting on their trade routes +1 movement and no rough terrain penalties, but I'm having a hard time understanding it, particularly the strTradeRouteStr stuff. Could someone please help me understand what's going on in it and what changes I would need to make for my UA to work?

Spoiler :
Code:
local pNoTerrainCost = GameInfoTypes.PROMOTION_IGNORE_TERRAIN_COST;
local pChariotRoute	= GameInfoTypes.PROMOTION_LIBYAN_CHARIOT_ROUTE;
local pNoMovement = GameInfoTypes.PROMOTION_ROUGH_TERRAIN_ENDS_TURN;
local pWood = GameInfoTypes.PROMOTION_WOODSMAN;

local fForest = GameInfoTypes.FEATURE_FOREST;
local fJungle = GameInfoTypes.FEATURE_JUNGLE;

local uCargo = GameInfoTypes.UNIT_CARGO_SHIP;
local uCaravan = GameInfoTypes.UNIT_CARAVAN;
local uChariot = GameInfoTypes.UNIT_CHARIOT_ARCHER
local uWarChariot = GameInfoTypes.UNIT_EGYPTIAN_WARCHARIOT
local uHitChariot = GameInfoTypes.UNIT_HITTITE_MOD_THREE_MAN_CHARIOT

function GetTradeRouteString(pPlot, pPlayer, pUnit)
	local strTradeRouteStr = "";
	local astrTradeRouteStrings = pPlayer:GetInternationalTradeRoutePlotToolTip(pPlot);			
	for i,v in ipairs(astrTradeRouteStrings) do	
		if (strTradeRouteStr == "") then
			strTradeRouteStr = strTradeRouteStr .. Locale.ConvertTextKey("TXT_KEY_TRADE_ROUTE_TT_PLOT_HEADING");
		else
			strTradeRouteStr = strTradeRouteStr .. "[NEWLINE]";
		end
		strTradeRouteStr = strTradeRouteStr .. v.String;
	end	
	return strTradeRouteStr;
end

GameEvents.UnitSetXY.Add( 
function(iPlayerID, iUnitID, iX, iY)
	local pPlot = Map.GetPlot(iX, iY)
	local pPlayer = Players[iPlayerID]
	local pUnit = pPlayer:GetUnitByID(iUnitID)
	if pPlot then
		if (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ANCIENT_LIBYA_MOD) then
			if (pUnit:GetUnitType() ~= uCargo) and (pUnit:GetUnitType() ~= uCaravan) then
				if (pUnit:GetDomainType() == DomainTypes.DOMAIN_LAND) and not pUnit:IsEmbarked() then 
					local strTradeRouteStr = GetTradeRouteString(pPlot, pPlayer, pUnit)
					if strTradeRouteStr ~= "" then		
						if (pPlayer:IsHuman()) then --Might confuse AI movement?
							if not pUnit:IsHasPromotion(pNoTerrainCost) then
								if not pUnit:IsHasPromotion(pChariotRoute) then
									pUnit:SetHasPromotion(pChariotRoute, true)
								end
							end	
							if (pUnit:GetUnitType() == uChariot) or (pUnit:GetUnitType() == uWarChariot) or (pUnit:GetUnitType() == uHitChariot) then
								if pUnit:IsHasPromotion(pNoMovement) then
									pUnit:SetHasPromotion(pNoMovement, false)
								end
							end						
						end
					elseif strTradeRouteStr == "" then
						if (pPlayer:IsHuman()) then
							if pUnit:IsHasPromotion(pChariotRoute) then
								pUnit:SetHasPromotion(pChariotRoute, false)
								if pPlot:IsRoughGround() and not pPlot:IsRoute() then
									if not pUnit:IsHasPromotion(pWood) then
										pUnit:ChangeMoves(-60)
									elseif pUnit:IsHasPromotion(pWood) then
										if (pPlot:GetFeatureType() ~= fForest) and (pPlot:GetFeatureType() ~= fJungle) then
											pUnit:ChangeMoves(-60)
										end
									end
								end
							end
							if (pUnit:GetUnitType() == uChariot) or (pUnit:GetUnitType() == uWarChariot) or (pUnit:GetUnitType() == uHitChariot) then
								if not pUnit:IsHasPromotion(pNoMovement) then
									pUnit:SetHasPromotion(pNoMovement, true)
									if pPlot:IsRoughGround() and not pPlot:IsRoute() then
										local MovesLeft = pUnit:GetMoves();
										pUnit:ChangeMoves(-MovesLeft)
									end
								end
							end		
						end
					end
				end
			end
		end
	end
end);

GameEvents.PlayerDoTurn.Add(
function(iPlayer)
    local pPlayer = Players[iPlayer];
	local iCurrentTurn = Game.GetGameTurn()
	if (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ANCIENT_LIBYA_MOD) then
		for pUnit in pPlayer:Units() do		
			if (pUnit:GetUnitType() ~= uCargo) and (pUnit:GetUnitType() ~= uCaravan) then
				if (pUnit:GetDomainType() == DomainTypes.DOMAIN_LAND) and not pUnit:IsEmbarked() then 
					local pPlot = pUnit:GetPlot()
					local strTradeRouteStr = GetTradeRouteString(pPlot, pPlayer, pUnit)				
					if strTradeRouteStr ~= "" then	
						if (pPlayer:IsHuman()) then		
							if not pUnit:IsHasPromotion(pNoTerrainCost) then
								if not pUnit:IsHasPromotion(pChariotRoute) then
									pUnit:SetHasPromotion(pChariotRoute, true)
								end
							end	
							if (pUnit:GetUnitType() == uChariot) or (pUnit:GetUnitType() == uWarChariot) or (pUnit:GetUnitType() == uHitChariot) then
								if pUnit:IsHasPromotion(pNoMovement) then
									pUnit:SetHasPromotion(pNoMovement, false)
								end
							end		
						end	
						if pUnit:GetMoves() ~= 0 then				
							local pMax = pUnit:MaxMoves();
							pUnit:SetMoves(pMax + 60);
							--AI Handicap
							if not (pPlayer:IsHuman()) then
								if (pUnit:GetGameTurnCreated() == iCurrentTurn) then
									if not pUnit:IsHasPromotion(pNoTerrainCost) then
										if not pUnit:IsHasPromotion(pChariotRoute) then
											pUnit:SetHasPromotion(pChariotRoute, true)
										end
									end	
								end
							end
							--
						end
					elseif strTradeRouteStr == "" then
						if (pPlayer:IsHuman()) then
							if pUnit:IsHasPromotion(pChariotRoute) then
								pUnit:SetHasPromotion(pChariotRoute, false)
							end
							if (pUnit:GetUnitType() == uChariot) or (pUnit:GetUnitType() == uWarChariot) or (pUnit:GetUnitType() == uHitChariot) then
								if not pUnit:IsHasPromotion(pNoMovement) then
									pUnit:SetHasPromotion(pNoMovement, true)
								end
							end
						end
					end
				end
			end
			--AI Handicap
			if not (pPlayer:IsHuman()) then
				if (pUnit:GetGameTurnCreated() ~= iCurrentTurn) then
					if pUnit:IsHasPromotion(pChariotRoute) then
						pUnit:SetHasPromotion(pChariotRoute, false)
					end
				end
			end
			--
		end
	end
end);
 
I'm having a hard time understanding it, particularly the strTradeRouteStr stuff

There is no out-of-the-box "is this plot a trade route" method. However, you can work out if a plot is a trade route, and that's what the GetTradeRouteString() function is doing. In the standard game, when you mouse-over a plot, it displays a list of trade routes that pass through that plot. The GetTradeRouteString() function uses the standard player method - pPlayer:GetInternationalTradeRoutePlotToolTip(pPlot) - for getting the individual trade route tooltips, pastes them all together, and returns them as a single string (hence the str at the start of the variables)

The code in the UnitSetXY() and PlayerDoTurn() event handlers then does a simple check to see if the combined tooltip contains anything, to decide if the plot has at least one trade route

Code:
local strTradeRouteStr = GetTradeRouteString(pPlot, pPlayer, pUnit)
if strTradeRouteStr ~= "" then
	-- Unit on a trade route
elseif strTradeRouteStr == "" then
	-- Unit NOT on a trade route
end

The elseif is unnecessary as strTradeRouteStr will either contain something (~= "") or it won't, so can be replaced with just an else

Code:
local strTradeRouteStr = GetTradeRouteString(pPlot, pPlayer, pUnit)
if strTradeRouteStr ~= "" then
	-- Unit on a trade route
else
	-- Unit NOT on a trade route
end

And we don't actually care what's in the plot trade route tooltip strings, just that at least one exists, so we can rewrite the function to test for a trade route passing through a specific plot as

Code:
function HasTradeRoute(pPlot, pPlayer)
	return (#pPlayer:GetInternationalTradeRoutePlotToolTip(pPlot) > 0)
end

which gets the trade route tooltips into an array (the pPlayer:GetInternationalTradeRoutePlotToolTip (pPlot) bit), counts them (the # bit), and tests for there being at least one (the > 0 bit)

The test within the the two event handlers can then be rewritten as

Code:
if HasTradeRoute(pPlot, pPlayer) then
	-- Unit on a trade route
elseif strTradeRouteStr == "" then
	-- Unit NOT on a trade route
end

which even if you don't understand how the HasTradeRoute() function works, is somewhat clearer in its purpose

HTH

W
 
Back
Top Bottom