[Lua] Troller0001's stupid questions that may actually not be that stupid

@whoward69, Standard, my test mod was the only active mod.
 
my test mod was the only active mod.

EUI isn't a mod, it's a pseudo-DLC so doesn't show up in the list of active mods

Are you 100% positive you don't have EUI installed
 
I am 1000% sure I haven't installed that. I haven't installed any stuff within the Firaxis folders. I've only been using steam workshop. In fact, I've never even used EUI (or checked its install page), since I'm a noob in Civ anyways :p
 
I'm missing something obvious. :crazyeye:

That's what I'm thinking the whole time...

Here's the code I used to check (set WLTKD-turns within the FireTuner Lua console so the event would fire)
Spoiler :
MonGrandPrix.lua (VFS=true;executed every turn from another lua file (PlayerDoTurn) in combination with include("MonGrandPrix"))
Code:
--function that checks if WLTKD is active, and then activates the grand prix if it is
local iGrandPrix = GameInfoTypes.BUILDING_MON_GRAND_PRIX
local iMon_ID = GameInfoTypes.CIVILIZATION_MOROCCO --will be monaco once the civ is added in the game


function MonGrandPrix(iPlayer)
	local pPlayer = Players[iPlayer]
	
	if(pPlayer:GetCivilizationType() == iMon_ID)then
		for pCity in pPlayer:Cities() do
			if(pCity:GetWeLoveTheKingDayCounter() > 0) then
				if(not pCity:IsHasBuilding(iGrandPrix))then--if the grand prix isn't already active, add a notification
					if pPlayer:IsHuman() then
						local description = ("Since 'We Love the King Day' is active, the citizens of "..pCity:GetName().." have organized a Grand Prix in their city, increasing Great People Generation by 15%")
						local descriptionShort = ("A Grand Prix has been organized")
						Players[Game.GetActivePlayer()]:AddNotification(NotificationTypes["NOTIFICATION_WONDER_BEATEN"], description, descriptionShort, pCity:GetX(), pCity:GetY(),iMonGrandPrix,Game.GetActivePlayer())
					end
				end
				pCity:SetNumRealBuilding(iGrandPrix, 1)
			else
				pCity:SetNumRealBuilding(iGrandPrix, 0)
			end
		end
	end
end
Mon_Buildings.xml (OnModActivate->UpdateDatabase)
Code:
<GameData>
<BuildingClasses>
<Row>
			<Type>BUILDINGCLASS_MON_GRAND_PRIX</Type>
			<DefaultBuilding>BUILDING_MON_GRAND_PRIX</DefaultBuilding>
			<Description>TXT_KEY_BUILDING_MON_GRAND_PRIX</Description>
		</Row>
	</BuildingClasses>

<Buildings>
<Row>
			<Type>BUILDING_MON_GRAND_PRIX</Type>
			<BuildingClass>BUILDINGCLASS_MON_GRAND_PRIX</BuildingClass>
			<Cost>-1</Cost>
			<PrereqTech>NULL</PrereqTech>
			<MinAreaSize>-1</MinAreaSize>
			<Description>TXT_KEY_BUILDING_MON_GRAND_PRIX</Description>
			<Civilopedia>TXT_KEY_BUILDING_MON_GRAND_PRIX_PEDIA</Civilopedia>
			<Strategy>TXT_KEY_BUILDING_MON_GRAND_PRIX_STRATEGY</Strategy>
			<Help>TXT_KEY_BUILDING_MON_GRAND_PRIX_HELP</Help>
			<GreatPeopleRateModifier>15</GreatPeopleRateModifier>
			<AllowsRangeStrike>true</AllowsRangeStrike>
			<HurryCostModifier>-1</HurryCostModifier>
			<IconAtlas>BW_ATLAS_1</IconAtlas>
			<NeverCapture>true</NeverCapture>
			<PortraitIndex>26</PortraitIndex>
			<Nukeimmune>true</Nukeimmune>
		</Row>
</Buildings>

</GameData>
NOTE: Checked the Database and XML logs; no errors. Rest of the code (everything but the AddNotification-building-icon) seems to work fine.
 
Move your lua to its own InGameUIAddin state and remove the VFS=true. Then test again. Doing this will verfify whether the problem is an lua "context" issue with the variables.

I've had problems with files that are "included" into another and where variables use 'local' in the file that is to be included into another lua.
 
@Lees, Nope, no difference. Thanks for the tip though!
 
It's all working as it should be!

Here are the clues as to why it's not working as expected (and why the Hagia Sophia is being displayed instead)

Clue 1: From NotificationPanel.xml
Code:
<AlphaAnim ID="WonderConstructedAlphaAnim" Anchor="C,C" Offset="0,-1" 
           Size="80,80"
           TextureOffset="0,80" 
           Texture="assets\UI\Art\Notification\WonderAtlas640.dds"/>

Clues 2 to 4 are the attached images
 

Attachments

  • WonderAtlas640.jpg
    WonderAtlas640.jpg
    30.7 KB · Views: 55
  • PyramidIcons.jpg
    PyramidIcons.jpg
    32.1 KB · Views: 48
  • MonumentIcons.jpg
    MonumentIcons.jpg
    25.2 KB · Views: 51
Aah, it chooses from a specific wonder 80*80 icon-sized atlas, since there are no 80*80 icons for non-wonder buildings. Though my next (expected) question would be, can I simply set the icon atlas to another one? Can I update the file name in the same way I would use an <update> tag if I want to increase building cost for example?
E.g. Something like this:
Spoiler :
Code:
<Context>
    <Update>
         <Where Name="WonderConstructedItem">
         <Set Texture="NewAtlas640.dds">
    </Update>
</Context>
Where NewAtlas640.dds would contain all the normal wonder icons as well as the new notification icons


Anyway, thanks for clearing this up W! Turns out it isn't actually that confusing ;)

EDIT: I still don't get why Hagia Sophia is the default though? Are the icon IDs set up from left to right in the 1st row, then set from right to left on the 2nd, and if there would've been a 3rd row, from the left to right again?
 
I still don't get why Hagia Sophia is the default

The "filler" in the XML is the WonderAtlas640 file with an offset of 0,80 applied (0,0 is the top left hand corner, +ve X moves right, +ve Y moves down)
 
@whoward69, Got it! Thanks! (Though, what's the point of having such a 'weird' offset?)
 
You would update the database not the UI context. For your Grand Prix building you'll be creating an icon atlas - just make sure you create an 80x80 icon
 
(Though, what's the point of having such a 'weird' offset?)
"Weird" is Firaxis' middle name (along with "pointless", "inconsistent", ...)
 
Thanks W! You'll surely get a special thanks once the mod is done!

"Weird" is Firaxis' middle name (along with "pointless", "inconsistent", ...)
:lol: Surely they must love spaghetti with that kind of inconsistency!
 
Wow, it's been such a long time since I last visited this place. Anyhow, I've got a new (stupid) question by me for you guys!

Code:
local iDemakCiv = GameInfoTypes.CIVILIZATION_MOROCCO --ignore this one; I was still testing
local tValidUnits = { [GameInfoTypes.UNIT_PROPHET] = true, [GameInfoTypes.UNIT_MISSIONARY] = true}
local tValidUnitPromotions = { [GameInfoTypes.PROMOTION_SIGHT_PENALTY] = GameInfoTypes.PROMOTION_SIGHT_PENALTY_DUMMY }




function CountDemakBonusUnits(iPlayer,iUnit)
	local pPlayer = Players[iPlayer]

	if pPlayer:GetCivilizationType() == iDemakCiv then
		local pUnit = pPlayer:GetUnitByID(iUnit)

		if tValidUnits[pUnit:GetUnitType()] then
			print("A unit applicable for a Swap-promotion was moved/created/destroyed")

			for iPromotion, iSwapPromotion in pairs(tValidUnitPromotions) do
				if pUnit:IsHasPromotion(iPromotion) then
					local iPromotionName = GameInfo.UnitPromotions[iPromotion].Type
					local iSwapPromotionName = GameInfo.UnitPromotions[iSwapPromotion].Type

					print("The unit has a valid Swap-Promotion: "..iPromotionName)
					if pUnit then
						pUnit:SetHasPromotion(iPromotion,false)
						pUnit:SetHasPromotion(iSwapPromotion,true)
						print("The Swap-Promotion ("..iSwapPromotionName..") has been given instead of the normal Promotion ("..iPromotionName..")")
					else
						print("The Unit was destroyed. R.I.P.")
					end
				else
					print("Unit didnt'have the promotion")
				end
			end

		end


	end
end


GameEvents.UnitSetXY.Add(CountDemakBonusUnits)
So the idea behind this was a sort of "dynamic" (read: over-complicated/obscure) way to add an invisible marker promotion to a unit, by replacing a specific promotion with a dummy version of it (which has the same stats but allows me to separate the two promotions from each other). It is going to be part of a Demak mod. "But Troller, why would you use tables for this", you may ask. Well, it's mostly since I want to learn how to use tables. And the best way to learn that is by practicing right? :)


Anyhow, most of it works like a charm. However, I'm having two problems with the UnitSetXY.

1) It also fires when a unit is created (not placed by IGE!), but the unit promotions have not yet been initialized when it fires! E.g. When a Great Prophet spawns (for example by finishing the Piety Policy Tree), the code fires but doesn't replace the promotion! While this isn't actually that bad, it causes a serious major bug:

2) It also fires when a unit is destroyed (well, now that I think of it I haven't actually tested this for 'disbanded' or 'killed', though the unit is also killed when it creates a religion right?). However, it also only causes a problem if the unit does not have its promotion(s) replaced! Also, nothing appears in the logs since it simply causes a CTD... :(

How to reproduce both bugs/problems:
- Enable IGE
- Finish the Piety Policy Tree
- Check the logs, it states that the unit was applicable for a promotion-swap did not have any promotions to swap
- Click on the free Great Prophet that you gained (do NOT move it)
- Click on 'Found Religion'
- A CTD takes place (the last things the logs say is: "The unit has a valid Swap-Promotion: PROMOTION_SIGHT_PENALTY"



EDIT: I might be able to solve the second (and the most important) bug actually, but it would depend on if UnitPreKill fires before UnitSetXY
 
I would use the SerialEventUnitCreated event. But rather than that, I would use Machiavelli's SerialEventUnitCreatedGood system because it keeps the game from re-firing your code for the same unit for all those different types of 'unit-creation', like saved game reloading and unit upgrading and unit embarking, and unit dis-embarking.

And both UnitPreKill and UnitSetXY fire a whole bunch of times for causes that aren't 'intuitive'. UnitSetXY fires for a unit-creation (actual creation, embarking, and the like) as well as unit desctruction, as does UnitPreKill because the game treats for example an embarkation as both a destruction and a creation event.
 
Ah, thanks a lot for the suggestion!
 
Let's go and create a 3rd page for this thread with another question! :D

This time it regards this piece of code:
Code:
for iPlayer = 0, GameDefines.MAX_MAJOR_CIVS-1, 1 do
	 local pPlayer = Players[iPlayer];
	 if pPlayer:IsAlive() then
		 if pPlayer:GetCivilizationType()== iDemakCiv then
			print("The Game loaded/started and the Demak-civilization was found")
			local pCapital = pPlayer:GetCapitalCity()
			[COLOR="DarkRed"]if not pCapital == nil then[/COLOR]
				print("Demak has settled its Capital: "..pCapital:GetName())
				
			[COLOR="darkred"]else
                               print("Demak has not settled its capital yet")
                        end[/COLOR]
		 end
	end
end
This code is not tied to any GameEvent/LuaEvent and therefore only fires when the game starts or is loaded from a save (which is intended).

Scenario 1: The full code (as in, all of the code above) is used
Whenever I start a new game, the lua.log shows "Demak has not settled its capital yet"
Whenever I load from a saved game (where I settled the capital), the lua.log shows the same! That must mean that when a game is reloaded, the cities have not been "placed" yet, right?

Well, here's the catch:
Scenario 2: The parts in red from the code above are removed (thus no check for pCapital==nil is done)
Whenever I start a new game, the logs show an error: a nil value for pCapital (which is logical since there is no capital yet)
Whenever I load from a saved game (where I settled the capital), we would expect the lua.log to show an error too right (because of Scenario 1)? WRONG, it shows "Demak has settled its capital: MARRAKECH".

NOTE: After rebuilding changes from modbuddy I made sure to make a separate save (so: BUILD CODE1 -> GAME1 ->SAVE1 -> EXIT1 -> RELOAD1; BUILD CODE2 -> GAME2 -> SAVE2 -> EXIT2 -> RELOAD2 if that's clear enough?)

I'm confused :confused::(:wallbash::aargh:
 
You need to understand Lua operator precedence (see here)

not has a higher precedence than ==

so
if not pCapital == nil then
means
if ((not pCapital) == nil) then

when pCapital is nil, this is treated as false, not false is true and true is not equal to nil, so the log shows "Demak has not settled its capital yet"

when pCapital has a value, this is treated as true, not true is false and false is not equal to nil, so the log shows "Demak has not settled its capital yet"

You want
if not (pCapital == nil) then
or
if pCapital ~= nil then
or just
if pCapital then
 
Top Bottom