Notifications for Wonder Units

Chrisy15

Flower, Beautiful
Joined
Jul 9, 2015
Messages
2,137
Hi

I've recently added a Wonder Unit (<MaxGlobalInstances>1</MaxGlobalInstances>) to my mod, and I was wanting a notification to pop up, like what you get for building a wonder. Having looked at Firaxis' code, I decided to have a go, but I've got no real idea what I'm doing. Can anyone help?

What I came up with:
Spoiler :

Code:
print("300 Notification is working!");
local is300Ready = false;
function Is300Ready(iPlayer)
	local pPlayer = Players[iPlayer];
	if PlayerCanTrain (pPlayer, GameInfoTypes["UNIT_300"]) == true then
		is300Ready = true;
		GameEvents.PlayerDoTurn.Remove(Is300Ready);
	end
end
GameEvents.PlayerDoTurn.Add(Is300Ready);

function Is300Built(iPlayer)
	local pPlayer = Players[iPlayer]
	if (PlayerCanTrain(pPlayer, GameInfoTypes["UNIT_300"]) == false) and (is300Ready == true) then
		local portraitIndex = GameInfo.Units["UNIT_300"].PortraitIndex;
		IconHookup( portraitIndex, 80, GameInfo.Units["UNIT_300"].IconAtlas, instance.WonderConstructedAlphaAnim );
		GameEvents.PlayerDoTurn(iPlayer).Remove(Is300Built);
	end
	if iExtraGameData ~= -1 then
		CivIconHookup (iExtraGameData, 45, instance.CivIcon, instance.CivIconBH, instance.CivIconShadow, false, true );
		instance.WonderSmallCivFrame:SetHide(false);
		GameEvents.PlayerDoTurn.Remove(Is300Built);
	end
end
GameEvents.PlayerDoTurn.Add(Is300Built);

Also, a notification for the unit dying would be nice, although there may be issues with that if the unit upgrades.
 
Unless you are doing advanced notifications by adding your own "finger" into a framework, the easiest way to send a notification is

Code:
pPlayer:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, "Some text", "Heading")

Which will give you a generic exclamation notification. Obviously you should change "Some text" and "Heading" to something relevant!

You can't directly hook up your own icons into the notification fingers, although you may be able to re-purpose an existing notification type that will load the unit's icon for you from its unit type if given the correct additional parameters
 
Thanks for the tip Whoward, but I'm still a bit stuck.
I came across Machiavelli24's Lua snippet (http://forums.civfanatics.com/downloads.php?do=file&id=23175), and tried to use that, but I think I'm having trouble with getting the Unit ID. Any suggestions?
Code:
function The300Built (playerID, unitID, hexVec, unitType, cultureType, civID, primaryColor, secondaryColor, unitFlagIndex, fogState, selected, military, notInvisible)
	local player = Players[playerID];
	--local The300 = GameInfoTypes["UNIT_300"];
	local unitCreated = unitType;

	if unitCreated == GameInfoTypes["UNIT_300"] then
		pPlayer:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, "TXT_KEY_300_TRAINED", "TXT_KEY_300_TRAINED_HEADER");
		print("The 300 have been built!");
		LuaEvents.SerialEventUnitCreatedGood.Remove(The300Built);
	end
end
LuaEvents.SerialEventUnitCreatedGood.Add(The300Built);
 
I've never used anything except the unitID argument when 'pulling' the data for the unit:
Code:
function The300Built(playerID, unitID, hexVec, unitType, cultureType, civID, primaryColor, secondaryColor, unitFlagIndex, fogState, selected, military, notInvisible)
	local pPlayer = Players[playerID]
	local pUnit = pPlayer:GetUnitByID(unitID)
	local iUnitType = pUnit:GetUnitType()
	if(pPlayer == nil or
		pUnit == nil or
		pUnit:IsDead()) then
		return
	end
	if iUnitType == GameInfoTypes["UNIT_300"] then
		if pPlayer:IsHuman() then
			local sMessageShort = "300 Created"
			local sMessageFull = "You have created the 300 unit"
			Players[Game.GetActivePlayer()]:AddNotification(NotificationTypes["NOTIFICATION_GREAT_PERSON_ACTIVE_PLAYER"], sMessageFull, sMessageShort, pUnit:GetPlot():GetX(), pUnit:GetPlot():GetY(), GameInfoTypes["UNIT_300"], -1, false)
		else
			--I'm not sure yet how to give the human player the notification if they get beat to the unit
		end
		LuaEvents.SerialEventUnitCreatedGood.Remove(The300Built);
	end
end
LuaEvents.SerialEventUnitCreatedGood.Add(The300Built);
  1. You need to add the files SerialEventUnitCreatedGood.lua and Promotion_Created.xml to your mod
  2. Promotion_Created.xml needs an "OnModActivated" . "UpdateDatabase" activation in Modbuddy
  3. SerialEventUnitCreatedGood.lua needs an InGameUIAddin entrypoint under the "Content" tab of Modbuddy.
  4. See whoward69's what ModBuddy setting for what file types tutorial for info on these two file setting requirements if you are unsure what is meant.
  5. Otherwise, Machiavelli's system for SerialEventUnitCreatedGood will not be activated, and your code will never fire.
  6. As presented, the code I have shown will only give a notification if the human player constructs the unit.

Theoretically this part is probably overkill:
Code:
	if(pPlayer == nil or
		pUnit == nil or
		pUnit:IsDead()) then
		return
	end
but I've always included it because it was part of a sample I was gifted lo those many months ago by Nutty (I think), kinda like the girl in that one Star Trek: TOS episode just pushes the red lever when the yellow light flashes, and never questions why.
 
Slightly off-topic

Code:
local pPlayer = Players[playerID]
local pUnit = [COLOR="magenta"][B]pPlayer:[/B][/COLOR]GetUnitByID(unitID)
local iUnitType = [COLOR="blue"][B]pUnit:[/B][/COLOR]GetUnitType()

if ([B][COLOR="Magenta"]pPlayer == nil[/COLOR][/B] or
	[B][COLOR="Blue"]pUnit == nil[/COLOR][/B] or
	pUnit:IsDead()) then
	return

the tests for pPlayer == nil and pUnit == nil are redundant, as you've already used pPlayer without checking it, so if it ever could be nil, you'd have hit a "null pointer exception" before the test anyway. Same for pUnit

As this is the handler for an event, and the event (within the C++ code) passed playerID and unitID as parameters, just before the event call both the player object and the unit object MUST exist (otherwise the event wouldn't have fired). So, provided you have done nothing weird in other code (eg Players = {}), you have no typos in the parameters (pPlayer = Players[playerId], if punit == nil, etc), neither pPlayer nor pUnit will ever be nil.

(Edit: Not necessarily true for this event as it's a LuaEvent generated by some unknown code, but would be true if this was a GameEvent or Event.)
 
it was part of a sample I was gifted lo those many months ago by Nutty (I think), kinda like the girl in that one Star Trek: TOS episode just pushes the red lever when the yellow light flashes, and never questions why.
I know I wouldn't have structured it that way (I have a dislike for returns when a properly structured if-block would do). But I may have reposted it. There's a whole lot of us little girls pushing levers with little inkling what they do.
 
Back
Top Bottom