[LUA] Great People being used

The previous BNW patch (before the current "MP fix" patch) included a number of new Lua hooks, including:
(Hook) GameEvents.GreatPersonExpended(playerId, eGreatPersonType);
 
eGreatPersonType will match GameInfoTypes.UNIT_{something}, eg

Code:
  if (eGreatPersonType == GameInfoTypes.UNIT_ENGINEER) then
    -- A Great Engineer has been used
  end
 
Is there a way to determine where the great person has been expanded ?
 
Hmm, it doesn't look like it. GreatPersonExpended only takes the playerID and eGreatPersonType as its arguments, and every function that calls CvPlayer>>DoGreatPersonExpended also kills the unit immediately afterward.
 
GameEvents.UnitPrekill is a good bet at a place to start, though it is limited to BNW I believe. It may fire more than once for every unit removed from the game, but it does not always fire more than once for every type of unit-removal cause.

Even though it is referred to as "~Prekill" it is not just about a unit being killed in combat. From what I have seen from my testing it fires for any unit removed from the game for any reason. From what I remember it also "catches" using IGE to remove a unit from the game.

Some examples of when it fires (you would have to check to see if it fires for Great People Events such as creating a great work of art):
  1. when a settler is used to found a city. it fires twice.
  2. when one unit kills another in combat. it fires twice.
  3. when a unit is disbanded. it fires twice.
  4. when a civilian unit is captured. appears to only fire once.
  5. when a unit is removed using the Kill() method
The following is almost identical to the "listener" I borrowed from DarkScythe to test what data you get from the UnitPrekill hook. Note the info listed on what bDelay is when the function runs the 1st and 2nd times for the removal from the game of the same unit.
Code:
function PreKillListener(iOwner, iUnit, iUnitType, iX, iY, bDelay, iKiller)
	print("prekillListener: Dumping data..")
	print("iOwner: " .. iOwner)
	print("iUnit: " .. iUnit)
	print("iUnitType: " .. iUnitType .. " (" .. GameInfo.Units[iUnitType].Type .. ")")
	print("iX: " .. iX)
	print("iY: " .. iY)
	print("bDelay: " .. tostring(bDelay))
	-- bDelay returns true before unit is killed (before UnitKilledInCombat) and only has one unit on the plot
	-- bDelay returns false after the unit is killed (after UnitKilledInCombat) and an enemy melee unit may be on the same plot at this point
	print("iKiller: " .. iKiller)
end
GameEvents.UnitPrekill.Add(PreKillListener)
 
Nice! I hadn't noticed that before. Looks like that LuaHook is in all three DLLs, so it's compatible across the board.
 
Figuring it was better to reply here than to make a new thread, is there any way to make the GameEvents.UnitPrekill fire just once when a unit is killed?

To be more precise, I'm using it to ''respawn'' the killed Unit near the Capital, but I'm getting two of them. I use player:InitUnit(). Any solutions? :/
 
If you use the CanHaveUpgrade hook to store the id (player+unit) of units that are asking to upgrade you should be able to determine that a unit was "killed" as part of an upgrade process. Clear the store at the start of every players turn. There is a slight risk that you'll run into the use case "unit can upgrade, unit does not upgrade, unit is killed" in the same turn
 
If you use the CanHaveUpgrade hook to store the id (player+unit) of units that are asking to upgrade you should be able to determine that a unit was "killed" as part of an upgrade process. Clear the store at the start of every players turn. There is a slight risk that you'll run into the use case "unit can upgrade, unit does not upgrade, unit is killed" in the same turn

Is there a chance you (or anyone else) might be able to redirect me to an example, or a guide, or perhaps write it for me, if it's not too much of an issue? I'm not sure if I know what you mean.

Code:
function DJSH_TagmaRebirth(iOwner, iUnit, iUnitType, iX, iY, bDelay, iKiller)
	local player = Players[iOwner]
	local otherPlayer = Players[iKiller]
	local killedUnit = player:GetUnitByID(iUnit)
	local plot = Map.GetPlot(iX, iY)
	if killedUnit:IsHasPromotion(GameInfoTypes["PROMOTION_DJSH_TAGMA"]) then
		local capCity = player:GetCapitalCity()
		local killedUnitExperience = killedUnit:GetExperience()
		local killedUnitStrength = killedUnit:GetBaseCombatStrength()
		if JFD_GetRandom(1,100) <= 50 then
			if bDelay == false then
				respawnedUnit = player:InitUnit(iUnitType, capCity:GetX(), capCity:GetY())
				respawnedUnit:JumpToNearestValidPlot()
				respawnedUnit:ChangeExperience(killedUnitExperience)
				respawnedUnit:SetBaseCombatStrength(math.floor(killedUnitStrength + 1))
			end
		end
	end
end
GameEvents.UnitPrekill.Add(DJSH_TagmaRebirth)
 
Back
Top Bottom