Irkalla
ENTP POWWWEEEEEER
Basically, I want to spawn a unit that gets experience from Barracks and stuff. Any ideas?
What's wrong with InitUnit() and then Set/ChangeExperience()?
local pPlayer = Players[0];
local iUnitID = GameInfoTypes["UNIT_BOOTY_WARRIOR"];
local pCapital = pPlayer:GetCapitalCity();
local pCapitalPlot = pCapital:Plot();
pSoldier = pPlayer:InitUnit( iUnitID, pCapitalPlot.X, pCapitalPlot.Y );
pSoldier:JumpToNearestValidPlot();
pSoldier:SetExperience( fnGetMilitaryTrainingXP( pCapital )
local sUnitType = "UNIT_WARRIOR"
pUnit = pPlayer:InitUnit(GameInfoTypes[sUnitType], pCity:GetX(), pCity:GetY())
pUnit:SetExperience(pCity:GetDomainFreeExperience(pUnit:GetDomainType()))
-- Could also use pCity:GetFreePromotionCount() to text for any free promotions from Wonders
pUnit:JumpToNearestValidPlot()
-- TAKE CARE!!! The unit may have just been deleted if there is no valid plot
Pretty much. Although if you want to use a city as the generation point, something like
Code:local sUnitType = "UNIT_WARRIOR" pUnit = pPlayer:InitUnit(GameInfoTypes[sUnitType], pCity:GetX(), pCity:GetY()) pUnit:SetExperience(pCity:GetDomainFreeExperience(pUnit:GetDomainType())) -- Could also use pCity:GetFreePromotionCount() to text for any free promotions from Wonders pUnit:JumpToNearestValidPlot() -- TAKE CARE!!! The unit may have just been deleted if there is no valid plot
Also, any idea as to in what situations JumpToNearestValidPlot() may fail?
It will only jump within the current area, so if you have a city on an island, and there are already units on every tile of that island it will fail.
Just create the unit and don't use the Jump...() method - you'll end up with stacked units you'll have to move before you can end the turn - the problem is if the AI ends up with stacked units it can't move.So it won't put two units on the same tile then force you to move stacked unit? :T Sounds dumb.
Any alternatives for placing it that allows stacking?
If you mean pUnit = Add... then yesOh, also. Can I do that handle thing with AddFreeUnit instead of InitUnit?
Yes. To change the icon you'll need to use one of the notification replacing mods, to do the click to jump to a plot you'll either have to use a standard notification that does that (eg a unit or wonder one) or use one of the notification replacing modsLast thing, do you know anything about Notifications? Like, how can I change the icon of it and make it do that thing where you click it and it goes to a certain plot?
Just create the unit and don't use the Jump...() method - you'll end up with stacked units you'll have to move before you can end the turn - the problem is if the AI ends up with stacked units it can't move.
If you mean pUnit = Add... then yes
Yes. To change the icon you'll need to use one of the notification replacing mods, to do the click to jump to a plot you'll either have to use a standard notification that does that (eg a unit or wonder one) or use one of the notification replacing mods
Also, I'm thinking of doing this. A nice for loop that cycles through all cities. For each city, it counts all the player's units, initializes the unit meant to be created, jumps him to a valid plot, then counts all the player's units again. If second count == first count + 1, break.
In other words, check to see if it fails, then go to the next city and try it again until we get it.
Last thing... say I make a var pointing to a function (what are these actually called?)... How can I execute the function contained within? You know, so I can execute it then pass stuff on it.
local pFunc = Players[iPlayer]:GetCapital -- Note the lack of brackets
local pCapital = pFunc() -- Note the brackets
Function pointers usually
Code:local pFunc = Players[iPlayer]:GetCapital -- Note the lack of brackets local pCapital = pFunc() -- Note the brackets
JumpToNearestValidPlot() now returns a boolean, true if the unit was jumped, false if it was killed
Or will comparing it also run the function?
Correct, so it's just
if pUnit:JumpToNearestValidPlot() then break; end
Does GetFreePromotionCount() with no args test for any (*) free promotion? Whereas I can specify an arg to test for a specific promotion?
Nope.
GetFreePromotionCount() will tell you how many there are from the city (it returns an int), you then have to loop all possible promotions and then test IsFreePromotion(iPromotion) IIRC
[LIST=1]
[*]GameEvents.SetPopulation.Add(
[*]
[*]function( xOffset, yOffset, fOldPop, fNewPop )
[*]
[*] -- BEGIN DEFINES
[*] local pPlot = Map.GetPlot( xOffset, yOffset )
[*] local pCity = pPlot:GetPlotCity()
[*] local iPlyID = pCity:GetOwner()
[*] local pPly = Players[ iPlyID ] -- Dat Datatype Mismatch, son
[*] local iUnitMostCurrent = nil
[*] local pLeader = GameInfo.Leaders[ pPly:GetLeaderType() ]
[*] local iLeaderTrait = GameInfo.Leader_Traits("LeaderType ='" .. pLeader.Type .. "'")()
[*] local pTrait = GameInfo.Traits[ iLeaderTrait.TraitType ]
[*] local nTrait = pTrait.UnitPerCapitalGrowths
[*] local nZenith = math.floor( pCity:GetHighestPopulation() )
[*] local nGeneralCount = pPly:GetGreatGeneralsCreated()
[*] local pFreeUnit = nil
[*] -- END DEFINES
[*]
[*] --[[ On every growth of every city, run through the following list of conditions:
[*] 1: Does the city's owner have the trait, and is its population evenly divisible
[*] by the trait? Have they yet to create a Great General?
[*] 2: Is the city a capital?
[*] 3: Has the city grown instead of shrinking, and is this the city's highest
[*] population?
[*]
[*] If all of the above are true, get the best land infantry unit we can, and
[*] spawn it at the city. --]]
[*]
[*] if ( ( nTrait > 0 ) and ( ( math.floor( fNewPop ) % nTrait ) == 0 ) and ( nGreatGeneralCount > 0 ) ) then
[*]
[*] if pCity:IsCapital() then
[*]
[*] if ( ( fNewPop > fOldPop ) and ( fNewPop >= nZenith ) ) then
[*]
[*] iUnitMostCurrent = fnReturnBestInfantryUnit( pPly, pCity )
[*]
[*] for City in pPly:Cities() do
[*]
[*] pFreeUnit = pPly:InitUnit( iUnitMostCurrent, City:GetX(), City:GetY() )
[*]
[*] if pFreeUnit:JumpToNearestPlot() then
[*]
[*] local strNotificationText = "The Agoge has produced a free " .. pFreeUnit:GetName() .. " in " .. City:GetName() .. "!"
[*] local strNotificationTitle = "New Unit from the Agoge!"
[*]
[*] pFreeUnit:SetExperience( pCity:GetDomainFreeExperience( pFreeUnit:GetDomainType() ) )
[*]
[*] if ( pCity:GetFreePromotionsCount() > 0 ) then
[*]
[*] [COLOR="Red"]for iPromotion in GameInfo["UnitPromotions"] do[/COLOR]
[*]
[*] if pCity:IsFreePromotion( iPromotion ) then
[*]
[*] pFreeUnit:SetHasPromotion( iPromotion, true )
[*]
[*] end
[*]
[*] end
[*]
[*] end
[*]
[*] pPly:AddNotification( NotificationTypes["NOTIFICATION_GENERIC"], strNotificationText,
strNotificationTitle, pFreeUnit:GetX(), pFreeUnit:GetY() )
[*]
[*] break
[*]
[*] end
[*]
[*] end
[*]
[*] end
[*]
[*] end
[*]
[*] end
[*]
[*]end )
[/LIST]
IIRC you'll need
for promotion in GameInfo.Promotions() do
local iPromotion = promotion.ID
-- other stuff
end
if ( pCity:GetFreePromotionCount() > 0 ) then
for promotion in GameInfo.UnitPromotions() do
iPromotion = promotion.ID
if pCity:IsFreePromotion( iPromotion ) then
pFreeUnit:SetHasPromotion( iPromotion, true )
end
end
end