[LUA] Handling unit gifting (between human players)

Lort Krassbeter

Chieftain
Joined
Mar 8, 2015
Messages
17
Location
Beyond Earth
Hi, just a quick question since I did not find anything about this:
Are there any events to handle unit gifting between human players or in general?
 
Not exactly. You just use Player.InitUnit to create a new unit of the right type, then Unit.Convert which will copy the old attributes and delete the old unit.

Thanks, but I am searching for a way to recognize the event of someone gifting a unit, so I can manipulate the unit that I get through this method. I don't think there is a dedicated event for this, but perhaps it can be deduced from another event with a special condition... Otherwise the only other way I can think of would be by listening to the button press when a player gifts a unit. But that would not be a good solution, if a mod implemented another gifting method.
 
The GameEvents.UnitPrekill hook fires whenever a unit is removed from the game for whatever reason. This includes any Unit:Convert(pOldUnit) as well as any Unit:Kill(). Any time a settler is used to found a city, any time a settler or worker is captured and thereby converted to a new player, any time a Great Person is used, etc. It works for all civs and whether or not the player is AI or human. I can't remember at the moment though whether it is BNW-only.

DarkScythe wrote most of the following that you can use to set up a 'listener' which will spit info into the lua.log file or into Live Tuner so you can get a better idea of how the event works and what data it gives under various conditions.
Code:
function PreKiller(iOwner, iUnit, iUnitType, iX, iY, bDelay, iKiller)
	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(PreKiller)
 
...but you still won't know why the unit was killed necessarily. As mentioned in the comments of DS's code, you can try to make assumptions based on where the unit is in relation to other units on the same tile.

I'm not sure what you'll find, though, when that event is called. Will a InitUnit'ed unit owned by the giftee be located on that tile when the Convert tries to kill it? If so, we might make the assumption that if you're at peace with the other player, it's going to be a gift (and if you're at war it's a melee kill)... (Does the OriginalOwner property survive a Convert/gifting?)

Or does the game use some other method [i.e., not a Convert], and that unit is already in the giftee's territory? In which case we can't really tell the difference between a gift and a disband... [putting aside ranged kills]
 
The GameEvents.UnitPrekill hook fires whenever a unit is removed from the game for whatever reason. This includes any Unit:Convert(pOldUnit) as well as any Unit:Kill(). Any time a settler is used to found a city, any time a settler or worker is captured and thereby converted to a new player, any time a Great Person is used, etc. It works for all civs and whether or not the player is AI or human. I can't remember at the moment though whether it is BNW-only.

DarkScythe wrote most of the following that you can use to set up a 'listener' which will spit info into the lua.log file or into Live Tuner so you can get a better idea of how the event works and what data it gives under various conditions.
Code:
function PreKiller(iOwner, iUnit, iUnitType, iX, iY, bDelay, iKiller)
	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(PreKiller)
Alright, thanks for the hint, will try to work it out from this if possible.
...but you still won't know why the unit was killed necessarily. As mentioned in the comments of DS's code, you can try to make assumptions based on where the unit is in relation to other units on the same tile.

I'm not sure what you'll find, though, when that event is called. Will a InitUnit'ed unit owned by the giftee be located on that tile when the Convert tries to kill it? If so, we might make the assumption that if you're at peace with the other player, it's going to be a gift (and if you're at war it's a melee kill)... (Does the OriginalOwner property survive a Convert/gifting?)

Or does the game use some other method [i.e., not a Convert], and that unit is already in the giftee's territory? In which case we can't really tell the difference between a gift and a disband... [putting aside ranged kills]
Yea, I think it is not clear through only this event, but I will try to combine it with Events.SerialEventUnitCreated so I know if it was a melee/ranged kill or a gift to the receiver.
 
Back
Top Bottom