LeeS
Imperator
When a unit is added to the game directly via lua such units are "born" without the XPs or the promotions that are given via buildings present in the "creating city". The limitation also applies to units created via the <Building_FreeUnits> table or the <Buildings> column <InstantMilitaryIncrease>, so using a dummy building is not actually a solution.
This can of course be "fixed" as part of an lua program, and I have a working chunk of code to do so, but there are a couple of thoughts I have for which I would like some feedback based on others' experience.
Later, when the unit is spawned, I access the two tables and check for buildings that are present in the city which constructed the wonder, and give correct XPs and promotions accordingly:
So:
This can of course be "fixed" as part of an lua program, and I have a working chunk of code to do so, but there are a couple of thoughts I have for which I would like some feedback based on others' experience.
- As part of my Knights Templar World Wonder mod, a special "Crusader" unit is given every X turns after the wonder is completed. In order to track how many XP ought to be given to the unit(s) when they are spawned, I am creating an lua table that stores the ID's and the XP amounts of all buildings that give experience to the unit's domain and/or unitcombat type, as well as any buildings that give XP via the <Buildings> column <Experience>:
Spoiler XP Buildings Table :Code:sRequiredCombatClass = tostring(GameInfo.Units{ID=iFreeUnit}().CombatClass) sRequiredUnitDomain = tostring(GameInfo.Units{ID=iFreeUnit}().Domain) print("In looking through buildings to create the XP table") for row in GameInfo.Buildings() do iTotalFreeExperience = 0 iBuildingID = row.ID sBuildingType = tostring(row.Type) iExperience = row.Experience if iExperience > 0 then iTotalFreeExperience = iTotalFreeExperience + iExperience end for row in GameInfo.Building_DomainFreeExperiences() do if tostring(row.BuildingType) == sBuildingType then if tostring(row.DomainType) == sRequiredUnitDomain then iTotalFreeExperience = iTotalFreeExperience + (row.Experience) end end end for row in GameInfo.Building_UnitCombatFreeExperiences() do if tostring(row.BuildingType) == sBuildingType then if tostring(row.UnitCombatType) == sRequiredCombatClass then iTotalFreeExperience = iTotalFreeExperience + (row.Experience) end end end --------------------------------------------------------------------------------------------------- --store the building ID and the total XP given by it --do not make additions to the table gValidBuildingExperience anywhere but in the following lines --------------------------------------------------------------------------------------------------- if iTotalFreeExperience > 0 then gValidBuildingExperience[iBuildingID] = iTotalFreeExperience end end
- In order to "trap" a list of all buildings that could give <TrainedFreePromotion> to the unit, I construct a second table to store the building ID's and promotion ID's of TrainedFreePromotions that would apply to my unit:
Spoiler Promo Buildings Table :Code:for row in GameInfo.Buildings() do iBuildingID = row.ID sPromoString = tostring(row.TrainedFreePromotion) --print("sPromoString is set to " .. sPromoString .. " with a building ID number of " .. tostring(iBuildingID)) if sPromoString ~= "nil" then bWasAPromoMatch = false bWasACombatClassMatch = false for row in GameInfo.UnitPromotions_UnitCombats() do if tostring(row.PromotionType) == sPromoString then bWasAPromoMatch = true if tostring(row.UnitCombatType) == sRequiredCombatClass then bWasACombatClassMatch = true end end end if bWasAPromoMatch then if bWasACombatClassMatch then gValidBuildingPromos[iBuildingID] = GameInfoTypes[sPromoString] end else gValidBuildingPromos[iBuildingID] = GameInfoTypes[sPromoString] end end end
- These tables are created when the mod loads.
Later, when the unit is spawned, I access the two tables and check for buildings that are present in the city which constructed the wonder, and give correct XPs and promotions accordingly:
Spoiler Generate XP and Promos :
Code:
local iXPS = 0
for k,v in pairs(gValidBuildingExperience) do
if pCity:IsHasBuilding(k) then
iXPS = iXPS + v
end
end
iUnitPlot = pCity:Plot()
pUnitToSpawn = pPlayer:InitUnit(iFreeUnit, iUnitPlot:GetX(), iUnitPlot:GetY())
pUnitToSpawn:JumpToNearestValidPlot()
pUnitToSpawn:SetExperience(iXPS)
for k,v in pairs(gValidBuildingPromos) do
if pCity:IsHasBuilding(k) then
pUnitToSpawn:SetHasPromotion(v, true)
end
end
- If a promotion is given using pUnitToSpawn:SetHasPromotion(v, true) will this cause a crash or other problem if the unit in question has already been given the promotion? IE, if more than one building in the database gives, say, the Amphibious promotion, and both buildings are present in the city?
- Is there a more direct way of pulling as a string the unit's domain and combat class than what I am using?
Code:sRequiredCombatClass = tostring(GameInfo.Units{ID=[COLOR="Blue"]iFreeUnit[/COLOR]}().CombatClass) sRequiredUnitDomain = tostring(GameInfo.Units{ID=[COLOR="blue"]iFreeUnit[/COLOR]}().Domain)