Unit Resources Reqs

Wolfdog

Unit Butcher
Joined
Jun 29, 2012
Messages
660
Location
Australia
Hello, I am trying to make a lua script that stops a unit from being built unless it has met certain requirements. I know I can achieve this through xml but it I do not want it to apply to city states or barbarians so I need to use lua.

It half works in that it stops me from building the test unit (warrior) but as soon as I get iron I still can not build the unit. Thanks in advance.

Code:
function PlayerTrainWarrior(iPlayer, unitTypeID)
		local player = Players[iPlayer];
		local unitclass = GameInfoTypes[GameInfo.Units[unitTypeID].Class];
		local civtype = Players[iPlayer]:GetCivilizationType();
		if (unitclass ~= GameInfoTypes["UNITCLASS_WARRIOR"]) and (civtype ~= GameDefines.MAX_MAJOR_CIVS) and (player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_IRON"], true) > 0) then
			return true;
		end
	return false;
end
GameEvents.PlayerCanTrain.Add(PlayerTrainWarrior);
 
Try this 1st:
Code:
iIron = GameInfoTypes.RESOURCE_IRON
WarriorTypesTable = {}

--seek through units table and compile list of all units that are warrior-class but exclude the Barbarian Warrior
[COLOR="Blue"]for row in GameInfo.Units("Class == 'UNITCLASS_WARRIOR' AND Type ~= 'UNIT_BARBARIAN_WARRIOR'") do[/COLOR]
	table.insert(WarriorTypesTable, row.ID)
end

function CheckTableForMatch(TableName, CheckValue)
	for k,v in pairs(TableName) do
		if CheckValue == v then
			return true, k
		end
	end
	return false, "NONE"
end
function PlayerTrainWarrior(iPlayer, unitTypeID)
	local result = true
	local bUnitIsInTable, iPositionInTable = CheckTableForMatch(WarriorTypesTable, unitTypeID)
	if bUnitIsInTable then
		local player = Players[iPlayer];
		if not player:IsBarbarian() and not player:IsMinorCiv() then
			if player:GetNumResourceAvailable(iIron, true) <= 0 then
				result = false
			end
		end
	end
	return result;
end
GameEvents.PlayerCanTrain.Add(PlayerTrainWarrior);
The only thing I'm not certain of is the line in blue. It is using a quicker method that JFD recently showed me but I am not sure I have the structure quite correct. If it doesn't seem to run correctly, use this instead:
Code:
iIron = GameInfoTypes.RESOURCE_IRON
WarriorTypesTable = {}

--seek through units table and compile list of all units that are warrior-class but exclude the Barbarian Warrior
for row in GameInfo.Units() do
	if (row.Class == "UNITCLASS_WARRIOR") and (row.Type ~= "UNIT_BARBARIAN_WARRIOR") then
		table.insert(WarriorTypesTable, row.ID)
	end
end

function CheckTableForMatch(TableName, CheckValue)
	for k,v in pairs(TableName) do
		if CheckValue == v then
			return true, k
		end
	end
	return false, "NONE"
end
function PlayerTrainWarrior(iPlayer, unitTypeID)
	local result = true
	local bUnitIsInTable, iPositionInTable = CheckTableForMatch(WarriorTypesTable, unitTypeID)
	if bUnitIsInTable then
		local player = Players[iPlayer];
		if not player:IsBarbarian() and not player:IsMinorCiv() then
			if player:GetNumResourceAvailable(iIron, true) <= 0 then
				result = false
			end
		end
	end
	return result;
end
GameEvents.PlayerCanTrain.Add(PlayerTrainWarrior);

Important Edit
Right after I posted the above, I got to thinking about it, and I'm not sure when PlayerCanTrain actually runs. If it runs only when the mod loads and then never runs again, the code wouldn't work adaptively to real-time changes in conditions. It may be necessary to re-write and move the code into a CityCanTrain hook event as opposed to the PlayerCanTrain hook event.
 
Thanks LeeS, that worked a treat. Also I did try it with CityCanTrain hook event but it did not work. Cheers.:)
 
Back
Top Bottom