-- CityBuildingsToNearbyImprovementsHandler
-- Author: LeeS
-- DateCreated: 4/22/2016 3:49:21 PM
--------------------------------------------------------------
local tRealBuildingData = {} --don't change this line
--------------------------------------------------------------
--[[
USER CONFIGURABLE VARIABLES
Make changes to these variables as desired and needed
]]--
--------------------------------------------------------------
local bRequiresSpecificCiv = false
local iSpecificRequiredCiv = GameInfoTypes["CIVILIZATION_AMERICA"]
local bDoNotApplyToMinorCivs = true
----------------------------------------------------------------
--enter data into table tRealBuildingData here
--each subtable with table 'Counters' for a 'Real' building MUST have a designation of 'DummyBuilding=XXXXX'
----------------------------------------------------------------
tRealBuildingData[GameInfoTypes.BUILDING_GRANARY] = { Counters={
{DummyBuilding=GameInfoTypes["BUILDING_GRANARY_WHEAT_DUMMY"], ImprovementType=GameInfoTypes.IMPROVEMENT_FARM, ResourceType=GameInfoTypes.RESOURCE_WHEAT, LimitPerCity=4, PlotsPerEffect=1},
{DummyBuilding=GameInfoTypes["BUILDING_GRANARY_DUMMY"], ImprovementType=GameInfoTypes.IMPROVEMENT_CAMP, ResourceType=GameInfoTypes.RESOURCE_DEER, MustBeWorked=false, LimitPerCity=2, PlotsPerEffect=1},
{DummyBuilding=GameInfoTypes["BUILDING_GRANARY_DUMMY"], ImprovementType=GameInfoTypes.IMPROVEMENT_FARM, MustBeWorked=false, DoNotCountResourceTiles=true, LimitPerCity=2, PlotsPerEffect=1}
} }
tRealBuildingData[GameInfoTypes.BUILDING_WORKSHOP] = {ApplyToAllInClass=true, Counters={ {DummyBuilding=GameInfoTypes["BUILDING_WORKSHOP_DUMMY"], ImprovementType=GameInfoTypes.IMPROVEMENT_LUMBERMILL, LimitPerCity=-1 },
{DummyBuilding="LUMBERMILL_TOTAL", ImprovementType=GameInfoTypes.IMPROVEMENT_LUMBERMILL, MustBeOwned=false, MustBeWorked=false, LimitPerCity=-1 },
{DummyBuilding="LUMBERMILL_OWNED", ImprovementType=GameInfoTypes.IMPROVEMENT_LUMBERMILL, MustBeOwned=true, MustBeWorked=false, LimitPerCity=-1 }}}
tRealBuildingData[GameInfoTypes.BUILDING_WORKSHOP].SpecialHandling = (
function(BuildingID, tDummyQuantitiesTable, pCity, iPlayer)
local pPlayer = Players[iPlayer]
if not pPlayer:IsHuman() then return end
local iDummyBuilding = GameInfoTypes["BUILDING_WORKSHOP_DUMMY"]
local iOwnedLumbermills = tDummyQuantitiesTable["LUMBERMILL_OWNED"]
local iTotalLumbermills = tDummyQuantitiesTable["LUMBERMILL_TOTAL"]
local iNumberDummyToAdd = tDummyQuantitiesTable[iDummyBuilding]
local sDummyBuildingName = Locale.ConvertTextKey(GameInfo.Buildings[iDummyBuilding].Description)
print("The total number of Lumbermills within the working range of " .. pCity:GetName() .. " is " .. iTotalLumbermills)
print("The total number of Lumbermills within the working range of " .. pCity:GetName() .. " that are owned by player " .. pPlayer:GetName() .. " is " .. iOwnedLumbermills)
print("The total number of Dummy Buildings " .. sDummyBuildingName .. " that should be added if " .. pCity:GetName() .. " has a Workshop-Class Building is " .. iNumberDummyToAdd)
if pCity:IsHasBuilding(BuildingID) then
pCity:SetNumRealBuilding(iDummyBuilding, iNumberDummyToAdd)
else pCity:SetNumRealBuilding(iDummyBuilding, 0)
end
end
)
------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
--Debug Printing -- You can safely change bDebugprint to boolean true
------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
local bDebugprint = false
function DebugToLog(sMessage)
if (bDebugprint == true) then
print(sMessage)
end
end
------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
--Don't make changes in the following code
------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
local bDataIsIrreconcilable = false
local tCityImprovementEffectUnlockerBuildings = {}
local tCityLocalImprovements = { }
---------------------------------------------------------------------------------------------------------------------------
--Is Building Within Class Correct for Player
---------------------------------------------------------------------------------------------------------------------------
function IsBuildingCorrectForPlayer(iPlayer, iBuilding)
local pPlayer = Players[iPlayer]
local sCivilizationType = GameInfo.Civilizations[pPlayer:GetCivilizationType()].Type
local sBuildingName = GameInfo.Buildings[iBuilding].Type
local sBuildingClass = GameInfo.Buildings[iBuilding].BuildingClass
local sDefaultBuilding
for row in GameInfo.BuildingClasses("Type='" .. sBuildingClass .. "'") do
sDefaultBuilding = row.DefaultBuilding
end
for row in GameInfo.Civilization_BuildingClassOverrides("CivilizationType='" .. sCivilizationType .. "'") do
if sBuildingClass == row.BuildingClassType then
return (sBuildingName == row.BuildingType)
end
end
return (sBuildingName == sDefaultBuilding)
end
---------------------------------------------------------------------------------------------------------------------------
--function IrreconcilableData handles the busy-work of print error data to the lua log and making an error notification
---------------------------------------------------------------------------------------------------------------------------
function IrreconcilableData(sOriginator, sMessage)
local sLongMessage = sOriginator .. ": Bad Data Was Encountered"
if sMessage then
sLongMessage = sOriginator .. ": " .. sMessage
end
local sShortMessage = "[COLOR_NEGATIVE_TEXT]Invalid Data within table tRealBuildingData[ENDCOLOR]"
Players[0]:AddNotification(NotificationTypes["NOTIFICATION_GENERIC"], sShortMessage .. "[NEWLINE][NEWLINE]" .. sLongMessage, sShortMessage)
print(sLongMessage)
end
--XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
--XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function CityHasPrimaryBuildings(pCity)
for PrimaryBuildingID,Datatable in pairs(tCityImprovementEffectUnlockerBuildings) do
if pCity:IsHasBuilding(PrimaryBuildingID) then
return true
end
end
return false
end
--XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
--XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function CountCityImprovementsAndImplementEffectsForCity(pCity, iPlayer, tTableAlreadyCountedPlots)
local sCityName = pCity:GetName()
if (CityHasPrimaryBuildings(pCity) == false) then
DebugToLog("The City of " .. sCityName .. " has NO buildings we are interested in for Building-Improvement Linkages: nothing to do for this city")
return tTableAlreadyCountedPlots
end
local pPlayer = Players[iPlayer]
local tNumberCityLocalImprovements = {}
for ImprovementID,PrimaryBuildingDataTable in pairs(tCityLocalImprovements) do
if not tNumberCityLocalImprovements[ImprovementID] then
tNumberCityLocalImprovements[ImprovementID] = {}
end
for PrimaryBuildingID,ResourceDataTable in pairs(PrimaryBuildingDataTable) do
if not tNumberCityLocalImprovements[ImprovementID][PrimaryBuildingID] then
tNumberCityLocalImprovements[ImprovementID][PrimaryBuildingID] = {}
end
for ResourceID,DummyBuildingTable in pairs(ResourceDataTable) do
if not tNumberCityLocalImprovements[ImprovementID][PrimaryBuildingID][ResourceID] then
tNumberCityLocalImprovements[ImprovementID][PrimaryBuildingID][ResourceID] = {}
end
for DummyBuilding,SettingsTable in pairs(DummyBuildingTable) do
tNumberCityLocalImprovements[ImprovementID][PrimaryBuildingID][ResourceID][DummyBuilding] = 0
end
end
end
end
-- scanning through the city plots
DebugToLog("The City of " .. sCityName .. " has buildings we are interested in for Building-Improvement Linkages")
local iNumPlots = pCity:GetNumCityPlots()
for i = 0, iNumPlots - 1 do
local pPlot = pCity:GetCityIndexPlot(i)
if pPlot ~= nil then
local iPlotX, iPlotY = pPlot:GetX(), pPlot:GetY()
local iPlotID = pPlot:GetPlotIndex()
local iPlotOwner = pPlot:GetOwner()
local iImprovementType = pPlot:GetImprovementType()
local iResourceType = pPlot:GetResourceType()
local bPlotIsPillaged = pPlot:IsImprovementPillaged()
local bPlotIsBeingWorked = pPlot:IsBeingWorked()
local bCityIsWorkingPlot = (pPlot:GetWorkingCity() == pCity)
local bPlotOwnerIsCurrentPlayer = (iPlotOwner == iPlayer)
--================================================================================================================
-- this bit here is a bit brutal but I'm a bit rusty on the more-direct lua methods to achieve this for Civ5
--================================================================================================================
--================================================================================================================
-- this tells us whether or not the player has revealed the resource this plot contains
--================================================================================================================
local sResourceTypeTech = "NONE"
local iResourceTypeTech = "NONE"
local tResourceTable = GameInfo.Resources[iResourceType]
if (tResourceTable ~= nil) then
if (tResourceTable.TechReveal ~= nil) and (tResourceTable.TechReveal ~= "NULL") and (tResourceTable.TechReveal ~= "null") and (tResourceTable.TechReveal ~= -1) then
sResourceTypeTech = tResourceTable.TechReveal
local tTechTable = GameInfo.Technologies[sResourceTypeTech]
if (tTechTable ~= nil) then
iResourceTypeTech = tTechTable.ID
end
end
end
local bPlayerHasResourceRevealTech = true
if (iResourceTypeTech ~= "NONE") then
bPlayerHasResourceRevealTech = Teams[pPlayer:GetTeam()]:GetTeamTechs():HasTech(iResourceTypeTech)
end
--================================================================================================================
if tCityLocalImprovements[iImprovementType] then
local sImprovementName = Locale.ConvertTextKey(GameInfo.Improvements[iImprovementType].Description)
DebugToLog("A Valid Improvement for the Handler has been found! The Improvement is a " .. sImprovementName .. " : the plot grid location is X" .. iPlotX .. ",Y" .. iPlotY)
for PrimaryBuildingID,ResourceTable in pairs(tCityLocalImprovements[iImprovementType]) do
if pCity:IsHasBuilding(PrimaryBuildingID) then
local sBuildingName = Locale.ConvertTextKey(GameInfo.Buildings[PrimaryBuildingID].Description)
DebugToLog("The city has building " .. sBuildingName)
if tCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType] and (bPlayerHasResourceRevealTech == true) then
DebugToLog("The plot has a resource on it from the list for the Improvement/Building combo")
for DummyBuilding,SettingsData in pairs(tCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType]) do
local bAddToCount = true
if SettingsData.MustBeOwned then
DebugToLog("The plot with the " .. sImprovementName .. " must be owned to be counted")
bAddToCount = bPlotOwnerIsCurrentPlayer
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
if bAddToCount then
if (bPlayerHasResourceRevealTech == false) then
DebugToLog("The Resource on the plot has not yet been revealed so cannot be counted")
bAddToCount = false
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
end
if bAddToCount then
if SettingsData.CannotBePillaged then
DebugToLog("The plot with the " .. sImprovementName .. " cannot be pillaged to be counted")
bAddToCount = not bPlotIsPillaged
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
end
if bAddToCount then
if SettingsData.DoNotCountResourceTiles and (iResourceType ~= -1) then
DebugToLog("The plot with the " .. sImprovementName .. " cannot have a Resource to be counted")
bAddToCount = false
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
end
if bAddToCount then
if bPlotIsBeingWorked then
DebugToLog("The plot with the " .. sImprovementName .. " is being worked")
bAddToCount = bCityIsWorkingPlot
DebugToLog("The plot with the " .. sImprovementName .. " is being worked is by the correct city is " .. tostring(bCityIsWorkingPlot))
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
else
DebugToLog("The plot with the " .. sImprovementName .. " is not being worked")
if SettingsData.MustBeWorked then
DebugToLog("The plot with the " .. sImprovementName .. " must be worked to be counted")
DebugToLog("The plot with the " .. sImprovementName .. " is NOT being worked so cannot be counted")
bAddToCount = false
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
else
if (SettingsData.CountSameTileOnlyOnce == true) then
DebugToLog("The plot with the " .. sImprovementName .. " can only be counted once")
if tTableAlreadyCountedPlots[DummyBuilding][iPlotID] then
DebugToLog("The plot with the " .. sImprovementName .. " has already been counted for the current dummy building")
bAddToCount = false
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
if (bAddToCount == true) then
if not tTableAlreadyCountedPlots[DummyBuilding] then
tTableAlreadyCountedPlots[DummyBuilding] = {[iPlotID]="counted"}
else
tTableAlreadyCountedPlots[DummyBuilding][iPlotID]="counted"
end
end
end
end
end
end
if bAddToCount then
DebugToLog("The plot with the " .. sImprovementName .. " should be counted")
tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding] = tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding] + 1
DebugToLog("Before adjustment for LimitPerCity the " .. sImprovementName .. " total plots count for " .. sBuildingName .. " is " .. tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding])
if (SettingsData.LimitPerCity > 0) then
if tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding] > SettingsData.LimitPerCity then
tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding] = SettingsData.LimitPerCity
end
end
DebugToLog("After adjustment for LimitPerCity the " .. sImprovementName .. " total plots count for " .. sBuildingName .. " is " .. tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding])
end
end
else
if (iResourceType ~= -1) then
DebugToLog("The plot had a resource that was not listed as desired or the resource has not yet been revealed to the player")
else
DebugToLog("The plot had NO resource but the code is currently only looking for plots that have resources")
end
end
--==================================================================================================================================================================================================
--what to do when the ResourceType on the plot does not match to any resource listed in the sub-table "tCityLocalImprovements[iImprovementType][PrimaryBuildingID]{[iResourceType1], [iResourceType2]}"
--no ResourceType specified is now treated as "iResourceType == -1000" in the table(s) for "tCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType]"
--so no ResourceType specified should not be confusable in the code with "pPlot:GetResourceType() == -1" when the plot has no resource
--the code should always get here when no ResourceType was specified in the original "Counters" table.
--no longer really true-->: the code should also always get here when the plot's ResourceType was not in the list of required resources specified in the original "Counters" table.
--==================================================================================================================================================================================================
if tCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000] then
--still not sure that this part of the logic is really correct but it sure seems reasonable
--if tCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000] or (not tCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType]) then
DebugToLog("The plot was seen as not having a resource or as not having a resource from the required list")
for DummyBuilding,SettingsData in pairs(tCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000]) do
local bAddToCount = true
--if (bPlayerHasResourceRevealTech == false) and tCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType] then
-- DebugToLog("The plot has a resource that is in the list of resources needed but the resource is not revealed to the player")
-- bAddToCount = false
-- DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
--end
if bAddToCount then
if SettingsData.MustBeOwned then
DebugToLog("The plot with the " .. sImprovementName .. " must be owned to be counted")
bAddToCount = bPlotOwnerIsCurrentPlayer
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
end
if bAddToCount then
if SettingsData.CannotBePillaged then
DebugToLog("The plot with the " .. sImprovementName .. " cannot be pillaged to be counted")
bAddToCount = not bPlotIsPillaged
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
end
if bAddToCount then
if SettingsData.DoNotCountResourceTiles and (iResourceType ~= -1) then
DebugToLog("The plot with the " .. sImprovementName .. " cannot have a Resource to be counted")
bAddToCount = false
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
end
if bAddToCount then
if bPlotIsBeingWorked then
DebugToLog("The plot with the " .. sImprovementName .. " is being worked: it is being worked by the correct city is " .. tostring(bCityIsWorkingPlot))
bAddToCount = bCityIsWorkingPlot
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
else
DebugToLog("The plot with the " .. sImprovementName .. " is not being worked")
if SettingsData.MustBeWorked then
DebugToLog("The plot with the " .. sImprovementName .. " must be worked to be counted")
DebugToLog("The plot with the " .. sImprovementName .. " is NOT being worked so cannot be counted")
bAddToCount = false
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
else
if (SettingsData.CountSameTileOnlyOnce == true) then
DebugToLog("The plot with the " .. sImprovementName .. " can only be counted once")
if tTableAlreadyCountedPlots[DummyBuilding][iPlotID] then
DebugToLog("The plot with the " .. sImprovementName .. " has already been counted for the current dummy building")
bAddToCount = false
DebugToLog("The plot can be counted is evaluated as " .. tostring(bAddToCount))
end
if (bAddToCount == true) then
if not tTableAlreadyCountedPlots[DummyBuilding] then
tTableAlreadyCountedPlots[DummyBuilding] = {[iPlotID]="counted"}
else
tTableAlreadyCountedPlots[DummyBuilding][iPlotID]="counted"
end
end
end
end
end
end
if bAddToCount then
DebugToLog("The plot with the " .. sImprovementName .. " should be counted")
tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000][DummyBuilding] = tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000][DummyBuilding] + 1
DebugToLog("Before adjustment for LimitPerCity the " .. sImprovementName .. " total plots count for " .. sBuildingName .. " is " .. tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000][DummyBuilding])
if (SettingsData.LimitPerCity > 0) then
if tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000][DummyBuilding] > SettingsData.LimitPerCity then
tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000][DummyBuilding] = SettingsData.LimitPerCity
end
end
DebugToLog("After adjustment for LimitPerCity the " .. sImprovementName .. " total plots count for " .. sBuildingName .. " is " .. tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][-1000][DummyBuilding])
end
end
end
end
end
end
end
end
for PrimaryBuildingID,BuildingDataTable in pairs(tCityImprovementEffectUnlockerBuildings) do
local sBuildingIDName = Locale.ConvertTextKey(GameInfo.Buildings[PrimaryBuildingID].Description)
if IsBuildingCorrectForPlayer(iPlayer, PrimaryBuildingID) then
DebugToLog("Processing Dummy Buildings to be added for Primary Building " .. sBuildingIDName .. " for the city of " .. sCityName)
local tDummyQuantitiesToSet = {}
for Item,CounterData in pairs(BuildingDataTable.Counters) do
local DummyBuilding = (CounterData.DummyBuilding or -1)
local PlotsPerEffect = (CounterData.PlotsPerEffect or 1)
local iImprovementType = CounterData.ImprovementType
local iResourceType = (CounterData.ResourceType or -1000)
if not tDummyQuantitiesToSet[DummyBuilding] then
tDummyQuantitiesToSet[DummyBuilding] = 0
end
if PlotsPerEffect ~= 1 then
tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding] = math.floor(tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding]/PlotsPerEffect)
end
tDummyQuantitiesToSet[DummyBuilding] = tDummyQuantitiesToSet[DummyBuilding] + tNumberCityLocalImprovements[iImprovementType][PrimaryBuildingID][iResourceType][DummyBuilding]
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------
--the following is for Debug purposes only
if (bDebugprint == true) then
for DummyBuildingNeeded,QuantityToSet in pairs(tDummyQuantitiesToSet) do
if type(DummyBuildingNeeded) == "number" then
print(sCityName .. " ..... " .. Locale.ConvertTextKey(GameInfo.Buildings[DummyBuildingNeeded].Description) .. " has a quantity to set value of " .. QuantityToSet)
elseif type(DummyBuildingNeeded) == "string" then
print(sCityName .. " ..... " .. DummyBuildingNeeded .. " has a quantity to set value of " .. QuantityToSet)
else print(sCityName .. " ..... Invalid Data for DummyBuildingNeeded in table tDummyQuantitiesToSet:" .. tostring(DummyBuildingNeeded))
end
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------
if BuildingDataTable.SpecialHandling == "NONE" then
for DummyBuildingNeeded,QuantityToSet in pairs(tDummyQuantitiesToSet) do
if pCity:IsHasBuilding(PrimaryBuildingID) then
pCity:SetNumRealBuilding(DummyBuildingNeeded, QuantityToSet)
else
pCity:SetNumRealBuilding(DummyBuildingNeeded, 0)
end
end
else --this is where we do special handling
BuildingDataTable.SpecialHandling(PrimaryBuildingID, tDummyQuantitiesToSet, pCity, iPlayer)
end
else
DebugToLog("No processing of Dummy Buildings the city of " .. sCityName .. " for Primary Building " .. sBuildingIDName .. " is needed because Building " .. sBuildingIDName .. " is not correct for player # " .. iPlayer)
DebugToLog("Player # " .. iPlayer .. " has a unique version of Building " .. sBuildingIDName .. ", or Building " .. sBuildingIDName .. " is itself a unique replacement, or else the Database table BuildingClasses has been malformed by a mod for that Building-Class")
end
end
return tTableAlreadyCountedPlots
end
--XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
--XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
for BuildingID,DataTable in pairs(tRealBuildingData) do
local bApplyToAllInClass = (DataTable.ApplyToAllInClass or false)
local BuildingSpecialHandling = (DataTable.SpecialHandling or "NONE")
----------------------------------------------------------------------------------------------------------------------
--error checking on data entered by user into table tRealBuildingData
--looking only for errors that are going to cause spectacular failure of the code
----------------------------------------------------------------------------------------------------------------------
for Item,CounterData in pairs(DataTable.Counters) do
local sRealBuildingName = Locale.ConvertTextKey(GameInfo.Buildings[BuildingID].Description)
if not CounterData.DummyBuilding then
IrreconcilableData("Game Loading", "Dummy Building needed is missing for a Counter for 'Real' Building " .. sRealBuildingName .. "! A valid GameInfoTypes reference or a Unique Text-String must be supplied")
bDataIsIrreconcilable = true
end
local sDummyName = CounterData.DummyBuilding
local sDummyNameDataType = type(sDummyName)
local sDummyBuildingType = "NONE"
if sDummyNameDataType == "number" then
for row in GameInfo.Buildings("ID='" .. CounterData.DummyBuilding .. "'") do
sDummyBuildingType = row.Type
end
if sDummyBuildingType == "NONE" then
IrreconcilableData("Game Loading", "For Counter with DummyBuilding as " .. sDummyName .. " within the data for " .. sRealBuildingName .. "! The DummyBuilding has been designated as an integer value (ie, as if it were an ID # for a valid Building) but there is no matching Building ID # within table <Buildings>")
bDataIsIrreconcilable = true
else
sDummyName = Locale.ConvertTextKey(GameInfo.Buildings[CounterData.DummyBuilding].Description)
end
elseif sDummyNameDataType == "string" then
if ((BuildingSpecialHandling == nil) or (BuildingSpecialHandling == "NONE")) then
IrreconcilableData("Game Loading", "For Counter with DummyBuilding as " .. sDummyName .. " within the data for " .. sRealBuildingName .. "! The DummyBuilding is a Text-String, but SpecialHandling for " .. sRealBuildingName .. " is either unspecified or set to NONE")
bDataIsIrreconcilable = true
end
else
IrreconcilableData("Game Loading", "For Counter with DummyBuilding as " .. tostring(sDummyName) .. " within the data for " .. sRealBuildingName .. "! The DummyBuilding has not been designated as a proper Building ID# from table <Buildings>, or it is not a Text-String")
bDataIsIrreconcilable = true
end
if (CounterData.ResourceType ~= nil) and (CounterData.DoNotCountResourceTiles == true) then
IrreconcilableData("Game Loading", "For Counter with DummyBuilding as " .. sDummyName .. " within the data for " .. sRealBuildingName .. "! A ResourceType is specified while DoNotCountResourceTiles is set to true")
bDataIsIrreconcilable = true
end
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--using the data in table tRealBuildingData to construct a table called tCityImprovementEffectUnlockerBuildings
--data is essentially copied from tRealBuildingData into tCityImprovementEffectUnlockerBuildings
--where required, however, all buildings from within the same class as a building listed in tRealBuildingData is duplicated into table tCityImprovementEffectUnlockerBuildings
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if bApplyToAllInClass then
local sBuildingClass = GameInfo.Buildings[BuildingID].BuildingClass
for Building in GameInfo.Buildings("BuildingClass='" .. sBuildingClass .. "'") do
tCityImprovementEffectUnlockerBuildings[Building.ID] = { Counters=DataTable.Counters, SpecialHandling=BuildingSpecialHandling }
end
else
tCityImprovementEffectUnlockerBuildings[BuildingID] = { Counters=DataTable.Counters, SpecialHandling=BuildingSpecialHandling }
end
end
if not bDataIsIrreconcilable then
for BuildingID,DataTable in pairs(tCityImprovementEffectUnlockerBuildings) do
DebugToLog("In table tCityImprovementEffectUnlockerBuildings a primary building with ID # of " .. BuildingID .. " (" .. Locale.ConvertTextKey(GameInfo.Buildings[BuildingID].Description) .. ") is being processed")
for Item,CounterData in pairs(DataTable.Counters) do
local iResourceType = (CounterData.ResourceType or -1000)
local iResourceLinkedDummyBuilding = (CounterData.DummyBuilding or -1)
if not tCityLocalImprovements[CounterData.ImprovementType] then
tCityLocalImprovements[CounterData.ImprovementType] = {}
end
if not tCityLocalImprovements[CounterData.ImprovementType][BuildingID] then
tCityLocalImprovements[CounterData.ImprovementType][BuildingID] = {}
end
if not tCityLocalImprovements[CounterData.ImprovementType][BuildingID][iResourceType] then
tCityLocalImprovements[CounterData.ImprovementType][BuildingID][iResourceType] = {}
end
tCityLocalImprovements[CounterData.ImprovementType][BuildingID][iResourceType][iResourceLinkedDummyBuilding] = {DoNotCountResourceTiles=(CounterData.DoNotCountResourceTiles or false),
MustBeOwned=((CounterData.MustBeOwned == nil) and true or CounterData.MustBeOwned), MustBeWorked=((CounterData.MustBeWorked == nil) and true or CounterData.MustBeWorked),
CannotBePillaged=((CounterData.CannotBePillaged == nil) and true or CounterData.CannotBePillaged), LimitPerCity=(CounterData.LimitPerCity or -1),
CountSameTileOnlyOnce=((CounterData.CountSameTileOnlyOnce == nil) and true or CounterData.CountSameTileOnlyOnce)}
end
end
end
------------------------------------------------------------
---- CityContructedBuilding Game Event
------------------------------------------------------------
function CityConstructedBuilding(ownerId, cityId, buildingType, bGold, bFaithOrCulture)
if bGold or bFaithOrCulture then
if tCityImprovementEffectUnlockerBuildings[buildingType] then
local pPlayer = Players[ownerId]
if bDoNotApplyToMinorCivs and pPlayer:IsMinorCiv() then
return
end
if bRequiresSpecificCiv then
if pPlayer:GetCivilizationType() ~= iSpecificRequiredCiv then
return
end
end
local pCity = pPlayer:GetCityByID(cityId);
local tAlreadyCountedPlots = {}
tAlreadyCountedPlots = CountCityImprovementsAndImplementEffectsForCity(pCity, ownerId, tAlreadyCountedPlots)
end
end
end
------------------------------------------------------------
---- PlayerDoTurn Game Event
------------------------------------------------------------
function InspectPlayerCityImprovementsAndImplementBuildingEffects(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:IsBarbarian() then
return
end
if bDoNotApplyToMinorCivs and pPlayer:IsMinorCiv() then
return
end
if bRequiresSpecificCiv then
if pPlayer:GetCivilizationType() ~= iSpecificRequiredCiv then
return
end
end
local tAlreadyCountedPlots = {}
for pCity in pPlayer:Cities() do
tAlreadyCountedPlots = CountCityImprovementsAndImplementEffectsForCity(pCity, iPlayer, tAlreadyCountedPlots)
end
end
------------------------------------------------------------
---- WilliamHoward's IsCivInPlay
------------------------------------------------------------
function IsCivInPlay(iCivType)
for iSlot = 0, GameDefines.MAX_MAJOR_CIVS-1, 1 do
local iSlotStatus = PreGame.GetSlotStatus(iSlot)
if (iSlotStatus == SlotStatus.SS_TAKEN or iSlotStatus == SlotStatus.SS_COMPUTER) then
if (PreGame.GetCivilization(iSlot) == iCivType) then
return true
end
end
end
return false
end
------------------------------------------------------------
---- Game Event Hooks
------------------------------------------------------------
if not bDataIsIrreconcilable then
if bRequiresSpecificCiv then
if IsCivInPlay(iSpecificRequiredCiv) then
GameEvents.PlayerDoTurn.Add(InspectPlayerCityImprovementsAndImplementBuildingEffects)
GameEvents.CityConstructed.Add(CityConstructedBuilding)
end
else
GameEvents.PlayerDoTurn.Add(InspectPlayerCityImprovementsAndImplementBuildingEffects)
GameEvents.CityConstructed.Add(CityConstructedBuilding)
end
end
------------------------------------------------------------
---- Loading Confirmation Print Statements
------------------------------------------------------------
if not bDataIsIrreconcilable then
print("CityBuildingsToNearbyImprovementsHandler.lua loaded successfully")
else
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
print("CityBuildingsToNearbyImprovementsHandler.lua loaded without lua syntax-errors, but:")
print(" 1)......there were irreconcilable errors or conflicts in the construction of user configurable table tRealBuildingData")
print(" 2)......these errors must be resolved before the code will be allowed to run")
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
end