Some help and question for Lua

The code seems to work now, but I noticed it doesn't seem to add the dummy buildings. I followed what you said, so did I messed up again?

I tried to build the building normally, by not adding it from IGE, so I'm not sure what went wrong.

Code:
local iSmeltingPit = GameInfoTypes.BUILDING_SMELTING_PIT
local iSmeltDummy = GameInfoTypes.BUILDING_SMELTING_DUMMY
local iCiv = GameInfoTypes.CIVILIZATION_DECEPTICON

function SmeltingPitExtraProduction(PlayerID)
	local pPlayer = Players[PlayerID]
	if pPlayer:GetCivilizationType() == iCiv then
		for pCity in pPlayer:Cities() do
			local iOriginalCityOwner = pCity:GetOriginalOwner()
			if iOriginalCityOwner ~= PlayerID then
				print("This city appears to captured by the Decepticons!")
				if (pCity:GetNumBuilding(iSmeltingPit) > 0) then
					print("It appears that there's Smelting Pit building in this city!")
					pCity:SetNumRealBuilding(iSmeltDummy, 1)
					print("A Smetling Pit Dummy Building has been added!")
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(SmeltingPitExtraProduction)
 
The lua looks ok. Nothing I see appears wrong, so you have to look at what you are doing in ModBuddy -- is the lua file set up as an InGameUIAddin ?

And you have to check and make sure the two buildings are even being added into the game's database (correct ModBuddy OnModActivated>UpdateDatabase setting for the xml-file(s) where the two buildings are defined), and then you need to check that the game is not dumping the xml-file(s) with the definitions of the buildings because of xml-sytnax errors.

If you add the BUILDING_SMELTING_PIT to a city with IGE or by the normal ways of buying with gold or hard-constructing the building, you still have to press NEXT TURN in order for the code to be processed and the dummy building to be added to the city.
 
I solved the problem! I accidentally put in GameInfoTypes.BUILDINGCLASS instead of GameInfoTypes.BUILDING. I'm not sure how that happened, but there you go.

Finally, all of the questions and help I have for this mod are done now.
Thank you for all of your help.

Anyways, If I have more questions, should use this thread for more coding help or should I just make another thread?
 
I was wondering if this code here is correct.
I borrowed this from another mod, it supposed to give a promotion to a unit when that unit's HP is under 33%.
Is this correct?

Code:
local iWreckerPromotion = GameInfoTypes["PROMOTION_WRECK_AND_RULE"]
local iWrecker = GameInfoTypes["UNIT_WRECKER"]
local pPlayer = Players[iPlayer]
local pUnit = pPlayer:GetUnitByID(iWrecker)


function WreckerLowHPAttackBonus(iPlayer)
	if pUnit:GetUnitType() == iWrecker then
		if iWrecker:GetCurrHitPoints() <= 33 then
			iWrecker:SetHasPromotion(iWreckerPromotion, true)
		else
			iWrecker:SetHasPromotion(iWreckerPromotion, false)
		end
	end
end
 
There is no lua hook (eg. PlayerDoTurn),so the code will never fire.
iPlayer (line 3) is never defined, which causes it to be 'nill', which will throw errors because you are using it to define pPlayer!
As far as I'm concerned, trying to applythe promotion to all Wreckers won't work with the way you are trying to do it (using GetUnitByID). (Though I could be completely wrong there) What you could do however is loop through all units of the player,and then apply the promotiom if the unit is a Wrecker (using pPlayer:Units() to loop through the units )
 
There is no lua hook (eg. PlayerDoTurn),so the code will never fire.
iPlayer (line 3) is never defined, which causes it to be 'nill', which will throw errors because you are using it to define pPlayer!
As far as I'm concerned, trying to applythe promotion to all Wreckers won't work with the way you are trying to do it (using GetUnitByID). (Though I could be completely wrong there) What you could do however is loop through all units of the player,and then apply the promotiom if the unit is a Wrecker (using pPlayer:Units() to loop through the units )

What Lua hook I could use for that? And do I still need to have the Lua code mention the player, ie. iPlayer, pPlayer, etc.?
 
The easiest way (and probably the best way in this case) would be the PlayerDoTurn(iPlayer) (which makes it so it updates every turn)

Add this below the current code
Code:
GameEvents.PlayerDoTurn.Add(WreckerLowHPAttackBonus)
(if the wrecker is a UU you could add Whoward's isCivinPlay to reduce lag, though that is'nt specificlly neccesary)

Now, remove line 3 and 4 from the original code, becauese they would only cause bugs if we leave them there.

Add this in between line 7 and 8 of the original code:
Code:
local pPlayer=Players[iPlayer]
for pUnit in pPlayer:Units() do
and add its respective closing 'end' in between the last 2 'ends' of the original code
(If the wrecker is a UU you could add an additional check for the player's CivilizationType to reduce lag a bit more)

And I think that's it :D

NOTE: I wasn't able to test this since I'm typing on a tablet right now (which took a damn long time :p)
 
OK, I did the corrections you made, Troller. Is it correct?

Code:
local iWreckerPromotion			= GameInfoTypes["PROMOTION_WRECK_AND_RULE"]
local iWrecker					= GameInfoTypes["UNIT_WRECKER"]

GameEvents.PlayerDoTurn.Add(WreckerLowHPAttackBonus)
	if pUnit:GetUnitType() == iWrecker then
		if iWrecker:GetCurrHitPoints() <= 33 then
		local pPlayer=Players[iPlayer]
			for pUnit in pPlayer:Units() do
		end
			iWrecker:SetHasPromotion(iWreckerPromotion, true)
		else
			iWrecker:SetHasPromotion(iWreckerPromotion, false)
		end
	end
end

Also, this is a Unique Unit, so how where and would I put to check the user's CivilizationType?
 
Code:
local iWreckerPromotion = GameInfoTypes["PROMOTION_WRECK_AND_RULE"]
local iWrecker = GameInfoTypes["UNIT_WRECKER"]


function WreckerLowHPAttackBonus(iPlayer)
	pPlayer = Players[iPlayer]
	for pUnit in pPlayer:Units() do

		if pUnit:GetUnitType() == iWrecker then
			if iWrecker:GetCurrHitPoints() <= 33 then
				iWrecker:SetHasPromotion(iWreckerPromotion, true)
			else
				iWrecker:SetHasPromotion(iWreckerPromotion, false)
			end
		end
	end
end

GameEvents.PlayerDoTurn.Add(WreckerLowHPAttackBonus)
EDIT: Full code is in post #52
This is what I meant; sorry for the confusing line numbers :$

Technically you wouldnt need a civ-check because other civs can't train this unit anyways. Also, without a civ-check, the units will function properly if a CS would gift them to another player

This does however cause a little bit of lag, which could add up quickly with multiple mods.

In short, you'd need to make a tradeoff. (I generally tend to go the laggy way with PlayerDoTurn and the un-laggy way with things like UnitSetXY)
 
There's an error on the code that I found with Firetuner:

Code:
[10041.750] Runtime Error: C:\Users\Admin\Documents\My Games\Sid Meier's Civilization 5\MODS\Test Mod (v 1)\Test Unit.lua:10: attempt to index upvalue 'iWrecker' (a number value)
stack traceback:
	C:\Users\Admin\Documents\My Games\Sid Meier's Civilization 5\MODS\Test Mod (v 1)\Test Unit.lua:10: in function <C:\Users\Admin\Documents\My Games\Sid Meier's Civilization 5\MODS\Test Mod (v 1)\Test Unit.lua:5>
 
It should be this:
Code:
local iWreckerPromotion = GameInfoTypes["PROMOTION_WRECK_AND_RULE"]
local iWrecker = GameInfoTypes["UNIT_WRECKER"]


function WreckerLowHPAttackBonus(iPlayer)
	pPlayer = Players[iPlayer]
	for pUnit in pPlayer:Units() do

		if pUnit:GetUnitType() == iWrecker then
			if [S]iWrecker[/S][COLOR="RoyalBlue"]pUnit[/COLOR]:GetCurrHitPoints() <= 33 then
				[S]iWrecker[/S][COLOR="royalblue"]pUnit[/COLOR]:SetHasPromotion(iWreckerPromotion, true)
			else
				[S]iWrecker[/S][COLOR="RoyalBlue"]pUnit[/COLOR]:SetHasPromotion(iWreckerPromotion, false)
			end
		end
	end
end

GameEvents.PlayerDoTurn.Add(WreckerLowHPAttackBonus)

We were trying to check the hitpoints of the Wrecker unit type/definition/notsurehowIshouldcallit, rather than of the actual wrecker unit in-game, which is why we replaced iWrecker with (the pointer) pUnit
Those are some mistakes that you can easily overlook sometimes :crazyeye: (I'm back to my sweet ol' laptop so typing just became so much easier :D)

Spoiler Full Code :

Code:
local iWreckerPromotion = GameInfoTypes["PROMOTION_WRECK_AND_RULE"]
local iWrecker = GameInfoTypes["UNIT_WRECKER"]


function WreckerLowHPAttackBonus(iPlayer)
	pPlayer = Players[iPlayer]
	for pUnit in pPlayer:Units() do

		if pUnit:GetUnitType() == iWrecker then
			if pUnit:GetCurrHitPoints() <= 33 then
				pUnit:SetHasPromotion(iWreckerPromotion, true)
			else
				pUnit:SetHasPromotion(iWreckerPromotion, false)
			end
		end
	end
end

GameEvents.PlayerDoTurn.Add(WreckerLowHPAttackBonus)
 
I have another question: How can you make a code that has a unit with a special promotion that gives a promotion to certain nearby units (In this case, Melee and Gun Units)?
 
Define 'nearby' (if it's more than one tile away, I'd recommend you use Whoward's plot-Iterators, if it's only one tile away, you can get away with a small loop).

Also, would promotion #2 only be given to units that end their turn to a specific unit, or also to units that pass by the specific unit? (If the latter, I'd recommend you use the UnitSetXY-hook. If the first, use PlayerDoTurn)

An example of how to loop through adjacent tiles/hexes/plots:
Code:
for i = 0, 5 do
	local pPlotAdj = Map.PlotDirection(pPlot:GetX(),pPlot:GetY(),i);

	if pPlotAdj == nil then --this could happen when the center-plot is the one on the poles.
		print("Plot was off the map")
	else
		print("Checking plot: X="..pPlotAdj:GetX().." Y="..pPlotAdj:GetY())
                --add more stuff here (such as getting the unit on the plot and applying the promotion)
	end
end

To get the unitCombatType (such as melee and gun) of a unit you use: pUnit:GetUnitCombatType(), which returns any of these unitcombattypes. (UNITCOMBAT_GUN and UNITCOMBAT_MELEE are the ones that are important in your case)
 
When I meant by nearby Troller, I meant something like 2 tiles away. I was looking something like JFD's Armenia Civ, where the Mamikonian unit gives nearby Mounted units a promotion. I was wondering If I can get something like that.
 
That means you have a great point of reference! See what JFD does, try to understand what he does/how it's achieved, and then copy-paste and make changes from there! (and don't forget to give credit of course)
(I'll report back tomorrow since it's running late here :))
 
Here's what I have so far, borrowed from JFD. Would I need PlotIterators for this?

Code:
local unitPromotionMuniID = GameInfoTypes["PROMOTION_MUNITIONS"]
local unitPromotionMuniGaverID = GameInfoTypes["PROMOTION_GUN_MELEE_NEARBY_BOOST"]
local unitCombatLandID = GameInfoTypes["DOMAIN_LAND"]

function MunitionsGunBoost(playerID)
	local player = Players[playerID]
	local MunitionsNearby = false
	for unit in player:Units() do
		if (unit:GetUnitCombatType() == unitCombatLandID and not (unit:IsEmbarked())) then
			for munitionsPromotion in player:Units() do
				if munitionsPromotion:GetUnitType() == unitPromotionMuniID then
					if Map.PlotDistance(unit:GetX(), unit:GetY(), munitionsPromotion:GetX(), munitionsPromotion:GetY()) < 3 then
						MunitionsNearby = true
					end
				end
			end
			
			if MunitionsNearby then
				if not unit:IsHasPromotion(unitPromotionMuniGaverID) then
					unit:SetHasPromotion(unitPromotionMuniGaverID, true)
				end
			else
				if unit:IsHasPromotion(unitPromotionMuniGaverID) then
					unit:SetHasPromotion(unitPromotionMuniGaverID, false)
				end
			end
			
		else
			if unit:IsHasPromotion(unitPromotionMuniGaverID) then
				unit:SetHasPromotion(unitPromotionMuniGaverID, false)
			end
		end
	end
end
GameEvents.UnitSetXY.Add(MunitionsGunBoost) 
GameEvents.PlayerDoTurn.Add(MunitionsGunBoost)
 
Nope, PlotIterators in not necessary in this case!
Though there's an error here:
Code:
if munitionsPromotion:GetUnitType() == unitPromotionMuniID then
You are checking if UNIT_SOMETHING is equal to PROMOTION_MUNITIONS, which will always result in false (because units ~= promotions)
Change the line to
Code:
if munitionsPromotion:IsHasPromotion(unitPromotionMuniID) then
to fix it
 
I found an error in the code:

Code:
[1717.671] Syntax Error: C:\Users\Admin\Documents\My Games\Sid Meier's Civilization 5\MODS\Test Mod (v 1)\Test Promotion.lua:16: ')' expected near 'iID'
 
Back
Top Bottom