Technology Prereq for Great Work Bonuses

itsFHB

Chieftain
Joined
May 13, 2014
Messages
5
Okay so what I'm doing is trying to add an extra bonus to special Great Works that my Civilization's unique Great Writer makes that would be added once Computers is researched. Frankly I'm not too sure where to begin since I'm very basic when it comes to Lua but I'm learning I assure you.

I tried using XML to add the bonuses but that didn't end up working exactly as I hoped it would (the game wouldn't refresh the bonuses properly for every Great Work you had for some reason) so I figured I'll have to tweak out the Lua code a bit more.

Here's what the main chunk of the code looks like at the moment, the one that counts up all the special Great Works in the city and adds the dummy buildings accordingly. Just an FYI, I'm using ViceVirtuoso's script from their Vocaloid mod to add bonuses to Great Works. I just adjusted it a little bit and renamed a few of the labels to be consistent with my mod. :lol:

Code:
[SPOILER]--set to true to enable print statements
local bDebug = true

function dprint(...)
  if (bDebug) then
    print(string.format(...))
  end
end

--Variable to detect if CultureOverview popup is up; this is the only time that the UpdateGWBuildingsUI() function should run
local bPopup;


--Precache every Great Work in the database to speed things up.
local tSbemailWorks = {}

for work in GameInfo.GreatWorks() do
	if work.SbemailBonus == 1 then
		tSbemailWorks[work.ID] = work.Type
	end
end

for k, v in pairs(tSbemailWorks) do
	dprint("Great Work type " ..k.. "; Name: " ..v)
end

--Precache all buildings that have Great Works of Literature to speed things up more.
local tGreatLiteratureBuildings = {};
for pBuilding in GameInfo.Buildings() do
	if pBuilding.GreatWorkSlotType == "GREAT_WORK_SLOT_LITERATURE" and pBuilding.GreatWorkCount > 0 then
		local pBuildingClass = GameInfo.BuildingClasses("Type = '" ..pBuilding.BuildingClass.. "'")()
		--Save BuildingClasses instead of BuildingTypes since GetBuildingGreatWork() calls for Classes
		tGreatLiteratureBuildings[pBuildingClass.ID] = pBuildingClass.Type
		dprint("Added buildingclass " ..Locale.ConvertTextKey(pBuildingClass.Description).. " to Great Work building table")
	end
end

--Check all of a player's buildings at start of turn, and update the bonus buildings accordingly
--Time-consuming function, should look into possibilities of reducing processor impact
function UpdateGWBuildings(iPlayer)
if iPlayer >= GameDefines.MAX_MAJOR_CIVS then return end
dprint("Called UpdateGWBuildings")
local pPlayer = Players[iPlayer]
	if pPlayer:IsEverAlive() then
		for pCity in pPlayer:Cities() do
			local iNumWorksThisCity = 0;
			for iSbemailWork, pSbemailWork in pairs(tSbemailWorks) do
				dprint("Testing to see if " ..pSbemailWork.. " (ID " ..iSbemailWork.. ") is in " ..pCity:GetName())
				for iBuildingClass, pBuildingClass in pairs(tGreatLiteratureBuildings) do
					dprint("Checking building class " ..pBuildingClass)
					local iCurrentWorks = pCity:GetNumGreatWorksInBuilding(iBuildingClass)
					if iCurrentWorks > 0 then
						for i = 0, iCurrentWorks - 1, 1 do
							dprint("Testing work slot")
							local iWorkType = pCity:GetBuildingGreatWork(iBuildingClass, i)
							dprint("iWorkType:" ..iWorkType)
							dprint("GreatWorkType: " ..Game.GetGreatWorkType(iWorkType, iPlayer))
							if Game.GetGreatWorkType(iWorkType, iPlayer) == iSbemailWork then
								dprint("Found it!")
								iNumWorksThisCity = iNumWorksThisCity + 1
								break
							end
						end
					else
						dprint("No works in this building!")
					end
				end
			end
			if iNumWorksThisCity > 0 then
				pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_SBEMAIL_BONUS_BUILDING, iNumWorksThisCity)
			end
		end
	end
end


--Check all of a player's buildings when CultureOverview is updated (swapping Great Works around), and update the Logia bonus buildings accordingly
function UpdateGWBuildingsUI()
	--If bPopup is false then that will (should) mean that CultureOverview is not active, and that's the only screen this mod needs tracking for,
	--so quit this function if false
	if not bPopup then
		return
	end
	local iPlayer = Game:GetActivePlayer()
	local pPlayer = Players[iPlayer]
	if pPlayer:IsEverAlive() then
		for pCity in pPlayer:Cities() do
			local iNumWorksThisCity = 0;
			for iSbemailWork, pSbemailWork in pairs(tSbemailWorks) do
				dprint("Testing to see if " ..pSbemailWork.. " (ID " ..iSbemailWork.. ") is in " ..pCity:GetName())
				for iBuildingClass, pBuildingClass in pairs(tGreatLiteratureBuildings) do
					dprint("Checking building class " ..pBuildingClass)
					local iCurrentWorks = pCity:GetNumGreatWorksInBuilding(iBuildingClass)
					if iCurrentWorks > 0 then
						for i = 0, iCurrentWorks - 1, 1 do
							dprint("Testing work slot")
							local iWorkType = pCity:GetBuildingGreatWork(iBuildingClass, i)
							dprint("iWorkType:" ..iWorkType)
							dprint("GreatWorkType: " ..Game.GetGreatWorkType(iWorkType, iPlayer))
							if Game.GetGreatWorkType(iWorkType, iPlayer) == iSbemailWork then
								dprint("Found it!")
								iNumWorksThisCity = iNumWorksThisCity + 1
								break
							end
						end
					else
						dprint("No works in this building!")
					end
				end
			end
			if iNumWorksThisCity > 0 then
				pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_SBEMAIL_BONUS_BUILDING, iNumWorksThisCity)
			end
		end
	end
end

GameEvents.PlayerDoTurn.Add(UpdateGWBuildings)
Events.SerialEventCityInfoDirty.Add(UpdateGWBuildingsUI)


--When a popup screen appears, check if it is CultureOverview. If so, set bPopup to true, which lets UpdateLostLogiaBuildingsUI() fire
function SetCurrentPopupSbemail(popupInfo)
	local popupType = popupInfo.Type
	if popupType == ButtonPopupTypes.BUTTONPOPUP_CULTURE_OVERVIEW then
		bPopup = true
	end
end
Events.SerialEventGameMessagePopup.Add(SetCurrentPopupSbemail)


--When a popup is closed, delete bPopup so it doesn't keep refreshing Logia buildings when CultureOverview isn't open
function ClearCurrentPopupSbemail()
	bPopup = nil;
end
Events.SerialEventGameMessagePopupProcessed.Add(ClearCurrentPopupSbemail)[/SPOILER]

I have the works already granting +1 Happiness each with the code, but I also want it to gain extra culture and science yields once Computers is researched via dummy buildings. Figured I'd tackle this by creating an event before this part activates that adds a Dummy trigger to all cities once Computers is researched. Once it's actually counting the Great Works, I insert in a code that checks whether or not the dummy trigger is in the city already and if so, adds the bonus dummy building that generates culture and science accordingly.

I tried doing this myself but as the gross newbie that I am when it comes to Lua, things have been pretty fruitless for me so far. :( Any ideas on how I can do this? Or is my idea actually unnecessary and is there an easier way to do this?
 
What effect are you trying to implement? Something like +1 Happiness, Culture and Science per great work after Computers is researched? You said you already had happiness working. If you already have a building providing the happiness you can also add Culture and Science to the same building.

It is easy to detect when a player finishes a tech (there is an event that fires for human and ai). It is a bit trickier to detect when Great Works are created or move (city capture, digs finish, etc). Depending exactly on what you want to do it may be relatively easy (adding a hidden social policy that gives yields per great work when computers is finished) or very hard.
 
Back
Top Bottom