[BNW] Triggering some effect when unit is near missionary

Toppasticus

Chieftain
Joined
Jul 20, 2020
Messages
12
I would like to create some kind of crusader unit, that gets faith on kill or some other effect, but only if a missionary is near. My lua skills are lacking, but I manage to copy together and edit what I need from similar mechanics.
Could anyone point me to some mod that implements something like granting a unit an effect if a specified other unit is near?
 
I found something, here is what I have now (using PlotIterators.lua of Whoward):
Code:
        if player:GetUnitClassCount(GameInfoTypes["UNITCLASS_KNIGHT"]) > 0 then
            local Religious = {}
--first remove all instances of the crusader promotion
            for unit in player:Units() do
            if unit:IsHasPromotion(GameInfoTypes["PROMOTION_CRUSADER"]) then
                unit:SetHasPromotion(GameInfoTypes["PROMOTION_CRUSADER"], false)

            end
--now check the plots around all your religious units for crusaders, and when there is one, give him the crusader promotion, that has the desired special effect
            if unit:GetUnitClassType() == GameInfoTypes["UNITCLASS_MISSIONARY"] or unit:GetUnitClassType() == GameInfoTypes["UNITCLASS_INQUISITOR"] or unit:GetUnitClassType() == GameInfoTypes["UNITCLASS_PROPHET"] then
                table.insert(Religious, unit)
            end
            for key,Reli in pairs(Religious) do
                local plot = Reli:GetPlot()
                for loopPlot in PlotAreaSweepIterator(plot, 3, SECTOR_NORTH, DIRECTION_CLOCKWISE, DIRECTION_OUTWARDS, CENTRE_INCLUDE) do
                    for i = 0, loopPlot:GetNumUnits() - 1, 1 do 
                        local otherUnit = loopPlot:GetUnit(i)
                        if otherUnit and otherUnit:GetOwner() == playerID and otherUnit:GetUnitType() == GameInfoTypes["UNIT_CRUSADER"] then
                            otherUnit:SetHasPromotion(GameInfoTypes["PROMOTION_CRUSADER"], true)
                        end
                    end
                end
            end
        end

Not tested so far.
 
I highly recommend keeping to tab indentations when writing lua scripts. It makes it far easier to visualize which bits of code will execute within other bits of code.
Code:
if player:GetUnitClassCount(GameInfoTypes["UNITCLASS_KNIGHT"]) > 0 then
	local Religious = {}
	--first remove all instances of the crusader promotion
	for unit in player:Units() do
		if unit:IsHasPromotion(GameInfoTypes["PROMOTION_CRUSADER"]) then
			unit:SetHasPromotion(GameInfoTypes["PROMOTION_CRUSADER"], false)
		end
		--now check the plots around all your religious units for crusaders, and when there is one, give him the crusader promotion, that has the desired special effect
		if unit:GetUnitClassType() == GameInfoTypes["UNITCLASS_MISSIONARY"] or unit:GetUnitClassType() == GameInfoTypes["UNITCLASS_INQUISITOR"] or unit:GetUnitClassType() == GameInfoTypes["UNITCLASS_PROPHET"] then
			table.insert(Religious, unit)
		end
		for key,Reli in pairs(Religious) do
			local plot = Reli:GetPlot()
			for loopPlot in PlotAreaSweepIterator(plot, 3, SECTOR_NORTH, DIRECTION_CLOCKWISE, DIRECTION_OUTWARDS, CENTRE_INCLUDE) do
				for i = 0, loopPlot:GetNumUnits() - 1, 1 do 
					local otherUnit = loopPlot:GetUnit(i)
					if otherUnit and otherUnit:GetOwner() == playerID and otherUnit:GetUnitType() == GameInfoTypes["UNIT_CRUSADER"] then
						otherUnit:SetHasPromotion(GameInfoTypes["PROMOTION_CRUSADER"], true)
					end
				end
			end
		end
        end
end -- missing from your posted code chunk
lua does not need nor care about the indentations but you the code-maker can profit from them.
You code is executing through all of the player's units if that player has any Knight-Class units, which is well and good so far. But:
  1. As it encounters each unit with Promotion "PROMOTION_CRUSADER" it removes it, even if the code has already given it back earlier in the iteration. This is because everything is under the primary loop through the player's units here:
    Code:
    for unit in player:Units() do
  2. You are not running through all units and removing the promotion from them all before the code does anything else. You are removing the promotion from each discovered unit with the promotion as encountered in sequence through the list of the player's units, and then doing a lot of processing that will find both that and other "UNIT_CRUSADER" units and give each one found that are close to a previously-discovered religious unit the promotion. The promotion might very well be removed again in number 1 above if the main loop through the player's units has not yet processed a unit that was found to be near a religious unit.
  3. For each and every player unit regardless of its type you are executing through an lua table of all found religious units and then searching all nearby plots to any and all of these previously-found religios units to see if there are units near each and every one of these previously-found religious units that ought to have the promotion.
 
Top Bottom