Adding a new ability to a Civ Lua

chadm290

Chieftain
Joined
Apr 6, 2013
Messages
31
I have been stuck trying to make this work for me. What I want to do is for every kill a civ makes, I want to add 1 food to each of the civ's current cities. Here is my code so far:

Code:
function IfUnitIsDestroyed(playerID, unitID)
	--Need to add a condition that checks if the destroyed unit isn't the active player's settler
	local currentPlayer = Players[Game.GetActivePlayer()];
	local currentCiv = currentPlayer:GetCivilizationType();
	local civinfo = GameInfo.Civilizations[currentCiv];
	
	print("Civ: ", civinfo.Type);

	if civinfo.Type == GameInfo.Civilizations["CIVILIZATION_STRAWHAT"].Type then
		print("The Fierce Strawhats!")

		if playerID ~= GameInfo.currentPlayer then 
			print("Adding Food to Strawhat's cities")

			for pCity in Players[aCiv]:Cities() do
				local iCurrentFood = pCity:GetFood();
				pCity:SetFood(iCurrentFood + 1);
			end
		end
	end
end
Events.SerialEventUnitDestroyed.Add( IfUnitIsDestroyed );

What is happening now is that each time any civ makes a kill, it gets the food bonus. I think the problem lies with this code:
Code:
local currentPlayer = Players[Game.GetActivePlayer()];
	local currentCiv = currentPlayer:GetCivilizationType();
	local civinfo = GameInfo.Civilizations[currentCiv];
I think it keeps returning the human player's civ. I want the player whose turn is active. Please help. Thanks.
 
This will not be very easy, if it is even possible. Unless you are using a modded DLL SerialEventUnitDestroyed is an animation related event, not a gameplay related event. For example, SerialEventUnitDestroyed may not fire if the player doesn't have vision of the unit dying, or if quick combat is on, or if they are in strategic view. If a new patch for civ changes to the animation system the logic that fires SerialEventUnitDestroyed may change, disrupting any of your own code that hooks into SerialEventUnitDestroyed. SerialEventUnitDestroyed is not a safe event to hook into.

While I doubt it would work, I think the Korea scenario had an event that was something like "UnitKilledXY" that may be a gameplay event. I never investigated it closely so it may be a dead end.
 
Use global variable:
Code:
GameEvents.PlayerDoTurn.Add(function(iPlayer)
chadmPlayer = iPlayer;
end)

Then check everything.
You can also use ChangeFood(1) instead Get & Set.
 
Code:
function IfUnitIsDestroyed(playerID, unitID)
	local currentPlayer = Players[[COLOR="Red"]Game.GetActivePlayer()[/COLOR]];
	local currentCiv = currentPlayer:GetCivilizationType();
	local civinfo = GameInfo.Civilizations[currentCiv];
	
	if civinfo.Type == GameInfo.Civilizations["CIVILIZATION_STRAWHAT"].Type then
		if playerID ~= GameInfo.currentPlayer then 
			for pCity in Players[[COLOR="Red"]aCiv[/COLOR]]:Cities() do
				local iCurrentFood = pCity:GetFood();
				pCity:[COLOR="Red"]SetFood[/COLOR](iCurrentFood + 1);
			end
		end
	end
end
Events.SerialEventUnitDestroyed.Add( IfUnitIsDestroyed );
1) Game.GetActivePlayer is the ID of a human player, not the person who's turn it is.

2) Where is the variable aCiv coming from? I would expect this to either error out because of being nil or to always get the 0th player's cities (the 0th player being the human).

3) ChangeFood is what you want here.
 
I wonder if Events.SerialEventUnitSetDamage could be a better event to hook up. Just check if idamage >= 100 to make sure that the unit is dead.

However, you won't be able to know who kills the unit, so you may have to change your designed UA a bit (like if a unit is killed, food will be gained)

GameEvents.UnitKilledInCombat is another event you may be interested to. This events fires when a unit is killed. You know the killer civ and the killed civ, but you don't know exactly which unit gets killed - but it fits your UA well.
 
Thanks for the help! Here is what I am deciding to go with:

Code:
function OnUnitKilledInCombat(iPlayer, iKilledPlayer)
	local turnPlayer = Players[iPlayer];
	local currentCiv = turnPlayer:GetCivilizationType();
	local civinfo = GameInfo.Civilizations[currentCiv];

	if civinfo.Type == GameInfo.Civilizations["CIVILIZATION_THRILLER_BARK"].Type then
		local zombiechance = math.random(1, 100);

		if(zombiechance <= 25) then
			print("Free Zombie!");
			turnPlayer:AddFreeUnit(GameInfo.Units["UNIT_SHADOW_WARRIOR"].ID, UNITAI_DEFENSE);
		end
	end
end

GameEvents.UnitKilledInCombat.Add(OnUnitKilledInCombat)

This is code for another civ I am building, but it should work the same way. Thanks XXHE for the UnitKilledInCombat hint!
 
local zombiechance = math.random(1, 100);

Do not use math.random. It is not MP compatible. Use Map.Rand(number, "Log string"). It will return a number between 0 and number-1. (There's also getJonRandNum but that one doesn't appear to be exposed to lua. They work the same way anyway.)
 
local zombiechance = math.random(1, 100);

Do not use math.random. It is not MP compatible. Use Map.Rand(number, "Log string"). It will return a number between 0 and number-1. (There's also getJonRandNum but that one doesn't appear to be exposed to lua. They work the same way anyway.)

Thanks for the suggestion. I will use this instead.
 
Top Bottom