Getting an error I cannot figure out...

Craig_Sutter

Deity
Joined
Aug 13, 2002
Messages
2,773
Location
Calgary, Canada
This is just a short bit of code to return money and withdraw faith for units designated religious. Line with error is colored red in the code.

This is using Machiavelli's unit created event code... I have used it numerous times and have not had any problems with it... but this instance is proving to be problematic.

Error in log (repeated many many times):

Spoiler :

[1254763.855] Runtime Error: C:\Users\doms\Documents\My Games\Sid Meier's Civilization 5\MODS\The Viking Age for BNW (v 3)\LUA/Units.lua:116: attempt to index local 'city' (a nil value)


and code:

Code:
--converts gold cost of religious units to faith amount

function faithpurchase( iPlayer, iUnit )
	
	local player = Players[iPlayer]	
	local unit = player:GetUnitByID( iUnit )
	local plot = unit:GetPlot()
	local city = plot:GetPlotCity()
	[COLOR="Red"]local cost = city:GetUnitPurchaseCost(iUnit)[/COLOR]
	local iBer_Warrior = GameInfoTypes.UNIT_BERSERKER_WARRIOR
	local iBerserker = GameInfoTypes.UNIT_BERSERKER
	
	if iUnit == iBer_Warrior or iUnit == iBerserker then

	player:ChangeGold( cost )
	player:ChangeFaith(-(2*cost))

	end


end

LuaEvents.SerialEventUnitCreatedGood.Add( faithpurchase )

Thank-you in advance.
 
Not every unit created will be created in a city - which your code assumes.

You also mix-and-match the interpretation of iUnit - either as the unique id of a player's unit (which it is I believe) or as the numerical type of the unit.
 
Code:
function faithpurchase( iPlayer, iUnit )
	
	local player = Players[iPlayer]	
	local unit = player:GetUnitByID( iUnit )
	local plot = unit:GetPlot()
	local iUnitType = unit:GetUnitType()

	if plot:IsCity() then

		local city = plot:GetPlotCity()
		local cost = city:GetUnitPurchaseCost(iUnitType)
		local iBer_Warrior = GameInfoTypes.UNIT_BERSERKER_WARRIOR
		local iBerserker = GameInfoTypes.UNIT_BERSERKER
	
		if iUnitType == iBer_Warrior or iUnitType == iBerserker then

			player:ChangeGold( cost )
			player:ChangeFaith(-(2*cost))

		end
	-- else (you could decide what if anything to do here if the plot is not a city plot)
	end


end

LuaEvents.SerialEventUnitCreatedGood.Add( faithpurchase )
The problem here is that you have no way of knowing whether or not the unit was purchased or built by hammers unless the unit can only be purchased with gold as an inherent property of the unit. And since you are only interested in certain specific units, the code ought to be redrafted to run as:
Code:
local iBer_Warrior = GameInfoTypes.UNIT_BERSERKER_WARRIOR
local iBerserker = GameInfoTypes.UNIT_BERSERKER

function faithpurchase( iPlayer, iUnit )
	local unit = Players[iPlayer]:GetUnitByID( iUnit )
	local iUnitType = unit:GetUnitType()
	
	if iUnitType == iBer_Warrior or iUnitType == iBerserker then

		local player = Players[iPlayer]	
		local plot = unit:GetPlot()

		if plot:IsCity() then

			local city = plot:GetPlotCity()
			local cost = city:GetUnitPurchaseCost(iUnitType)
	
			player:ChangeGold( cost )
			player:ChangeFaith(-(2*cost))

		-- else (you could decide what if anything to do here if the plot is not a city plot)
		end
	end
end

LuaEvents.SerialEventUnitCreatedGood.Add( faithpurchase )
There are other speed enhancing and simplication methods that could likely be applied to the code, but as you had trouble understanding how to adapt to your needs last time I 'went there' I won't go into them. One has to have code one can understand and manipulate later (if needed) after all, so it does no good to discuss methods you don't yet appear to feel comfortable with.

----------------------------------------------------------------------------

One final thought, though. What if player's current faith is insufficient to cover the adjustment being made? I'm not sure how the game reacts to attempts to make faith go into negative values.
 
One final thought, though. What if player's current faith is insufficient to cover the adjustment being made? I'm not sure how the game reacts to attempts to make faith go into negative values.

It will go negative, and work its way back to 0 and then positive. However, there really should be a check for player:GetFaith() >= 2*cost in there somewhere
 
Back
Top Bottom