Adding Events

Don't forget lua is also used for setting up maps so it has to have that functionality, too.
 
Not really true. Also any effects of social policies, or leader traits, or anything else that the game currently does, which covers a lot of stuff really. If you go digging far enough you can find ways to implement a lot of stuff.

For e.g. our religion mod, or a revolutions mod. They are all, perhaps a few concessions aside, possible with lua. Not saying it's ideal, it's certainly more limited than the SDK in a multitude of ways, but if you go digging it's surprising what's possible. The limitations are mainly things that don't ever happen in the game in any form currently (for e.g. changing the cost of a tech mid-game)

I cant change some basic things with lua like changing food yield from granary for example when you discover a tech, I cant manipulate city output (food, commerce) while the game is running I can only do that in database before the game starts which is very static and limited.
I dont know if someone was able to do that.
 
I cant change some basic things with lua like changing food yield from granary for example when you discover a tech, I cant manipulate city output (food, commerce) while the game is running I can only do that in database before the game starts which is very static and limited.
I dont know if someone was able to do that.

You can change anything to do with yields conditionally. In our religion mod we have doctrine that give you additional food in cities that are devout, and stuff like that.

To give a variable amount of extra food conditionally if you have a tech, you can do something like:

Code:
if pCity:CountNumBuilding(granaryID) > 0 and lastTimeDidnt and pTeam:HasTech(tech) then
    pCity:ChangeBaseYieldRateFromMisc(YieldTypes.FOOD, iAmountToGive)
end

if pCity:CountNumBuilding(granaryID) == 0 and lastTimeDid and pTeam:HasTech(tech) then
    pCity:ChangeBaseYieldRateFromMisc(YieldTypes.FOOD, -iAmountToGive)
end

(This is not working code btw, just an example typed off the top of my head.)

Also you can then edit the help tooltip when you mouse over the tech so it says it gives granaries X extra food, you could even add a new table called 'Technology_BuildingYieldChanges':

Code:
<Technology_BuildingYieldChangeOnTech>
     <Row>
       <TechType>TECH_FERTILIZER</TechType>
       <YieldType>YIELD_FOOD</YieldType>
       <Yield>1</Yield>
     </Row>
</Technology_BuildingYieldChangeOnTech>

and query this table for the effect....

Code:
for yieldChanges in GameInfo.Technology_BuildingYieldChangeOnTech("TechType = '"..TestTech.."'") do
  
end

so you could add a yield change to any building on any tech, and generate the tooltip and effect from that, even had a little round button on the tech panel if you liked. It would be indistinguishable from the actual game effects.

so yeah as I say, you've got the mechanism to change yields, culture, combat bonuses, promotions, experience, create units and all manner of other things and can add lua logic to unlock these on any conceivable conditions, so it really isn't as bad as everyone makes out.
 
do you know why the following code does not work?

Code:
iYieldType = YieldTypes.YIELD_GOLD;
for pBuilding in GameInfo.Buildings() do
	if pBuilding.BuildingClass == "BUILDINGCLASS_MARKET" then
                  thisBuildingClass = GameInfo.BuildingClasses[pBuilding.BuildingClass];
	end
        pCity:SetBuildingYieldChange(thisBuildingClass, iYieldType, 1)
end

I am trying to give Market +1 gold. this code returns no error but nothing is changed in city output.
 
Never mind it I sloved the problem by using ChangeBaseYieldRateFromBuildings then I can update the yield on the building tootip.

I have another question: when I use my own mod I have a weird problem with the game where yield icons on the terrain inside my borders are not all shown, do you know why? my mod is very simple, the code in my above post is the important part of the code actually.
 
Extremely useful files. One question: can something similar be done with the spaceship launch, making an event that triggers when your civ launches? My mod prevents the spaceship from ending the game, but I want things to happen when it launches. The problem is, it's not like a building where it completes when the last bit is built; you still need to assemble the pieces and launch it.
 
Man, too complicated for the average player.

I would like to learn how to do an event which triggers on a certain turn#. Like making a carthaginian army appear out of the Alps on turn 30 :)

something like this

Code:
local barcaplayerid = 63;
local barcacheck = 0;
local MECH = 23;

local ALPSCOORDS = {
	somespot = { x = 1, y = 1 },
	thisspot = { x = 2, y = 2 },
	thatspot = { x = 3, y = 3 },
};

function HANNIBAL ()

	if ( barcacheck == 1 ) then return; end

	if ( Game.GetGameTurn() == 30 ) then
		for k,v in pairs( ALPSCOORDS ) do
			Players[ barcaplayerid ] :InitUnit( MECH, ALPSCOORDS[k].x, ALPSCOORDS[k].y );
		end
		barcacheck = 1;
	else
		return;
	end
end
Events.SpecificCityInfoDirty.Add ( HANNIBAL );

it's not that complicated if you look that over. if this then do that ;)

like xml editing except you can do stuff depending on what the xml value is equal to
 
for every city, every player turn. it can be replaced with activeplayerturnstart but if using autoplay it won't be triggered
 
Hmm this is interesting to know. I started adding the events page to the Civ5 wiki, maybe if you have time you can add some stuff to it? Would be useful to have a collection of information about this kind of thing.

http://wiki.2kgames.com/civ5/index.php/Lua_Game_Objects/Events

Does SerialEventEndTurnDirty work as I'd expect it to?

Edit: What does "dirty" mean, anyways? Nvm about the SerialEvent, they are UI, yes?
 
Dirty is a concept used mainly in UI systems for optimizations. Basically if something is 'dirty' it means 'it's changed', so you can update and draw the City Banners, and then not bother updating them again, just drawing the pre-calculated information until the Dirty event has been raised, where it will recalculate the banner information. Means it's not querying database or game data 60 times a second while you're scrolling around the map.

In our tech editor for example, we have a dirty flag on every table in the database that's set when anything in that table is changed, and one for each row that's set when any property in that row has changed. So when it comes to diff them to generate the XML, it just skips any that haven't had the 'dirty' flag set. Takes it down from minutes to seconds in save time.

A word of warning: The fact that they occur once per turn or once per city per turn for each player is more a happy coincidence than intentional, and can be broken if any mods call these events themselves. For example some of our religion stuff calls several of the Dirty events after doctrine are picked and various other things, to update the relevant info without needing to next turn to see it. If any other mods active at the same time assumed these only occurred once per turn or whatever, then it would cause problems.

So it's best to check the turn number etc and keep track of if the function's been called this turn for this city or not, otherwise you could end up with mods calling that event and ending up with twice as many unit spawns or more.
 
Thanks. So using dirty things is not a good idea... just like IRL ;)

Any theory why the SerialEvents are called SerialEvents?
 
Hmm this is interesting to know. I started adding the events page to the Civ5 wiki, maybe if you have time you can add some stuff to it? Would be useful to have a collection of information about this kind of thing.

http://wiki.2kgames.com/civ5/index.php/Lua_Game_Objects/Events

Does SerialEventEndTurnDirty work as I'd expect it to?

Edit: What does "dirty" mean, anyways? Nvm about the SerialEvent, they are UI, yes?

documenting the events on the official wiki? :p

i've got several of the events kind of figured out with some guesswork documentation in the tuner util in my sig. i felt like i was on a roll a few weeks ago figuring them out but then i got sidetracked, so its one of those things to do/finish

never tried serialeventendturndirty but now that you mention it and some quick testing, it looks like its triggered on the AIs turn at least twice. almost looks like its triggered before and after they do stuff (or that was probably just the location of the print in the script)

for human player it's triggered at start of turn, when you get next turn button to show up, on unit creation, after a unit is moved... very often :crazyeye:

and i would really like to know what is meant by all that dirty stuff. it's used all over the place and triggered a lot. it's not UI only. gamedatadirty for example, that's triggered at the start of a player's turn, or when a human switches around the windows (cityview, techtree view), but then gamedatadirty doesn't fire for the first alive player following the human in the Players table when the game is on autoplay.
 
So it's best to check the turn number etc and keep track of if the function's been called this turn for this city or not, otherwise you could end up with mods calling that event and ending up with twice as many unit spawns or more.

that's what the barcacheck = 1 is for
 
Thanks. So using dirty things is not a good idea... just like IRL ;)

just like IRL you're usually going to use something to handle dirty things (gloves). like lemmy points out you have to add checks, tracking, etc. stuff to make sure your functions are going to happen when you want them to

using SpecificCityInfoDirty for example, it's also passing 3 values: playerid, cityid, and an integer:

function HANNIBAL ( playerid, cityid, int )

so it's really simple to just add a function thats triggered by that event and have it print out the playername and cityname and you can see for yourself how it's called and in what order
 
Top Bottom