Quick Modding Questions Thread

I have another question (maybe I should post this in my own thread, but nobody seems to reply to my posts there).
Would it be possible to let an event appear if a specific building is completed?
For example: You have completed a Kemetic Temple, an event appears with some info and some choices about who should be the patron deity of your city.
-Set (+2 experience in the city for all units)
-Isis (+2 food)
-Osiris (+2 happiness)
-Anubis (+2 health)
-Thoth (+2 science)
The same would apply for other temples of other religions but with other gods (Zeus, Athena... for Olympianism; Shiva, Vishnu... for Hinduism etcetera...)

Also, how can I make events appear with images without DLL-modding?
And how can I make a building require a civic and city size?
And finally: How can I make a building give a free (non-researchable tech)?
 
With these larger requests, it might be a good idea to attacha link to a dedicated thread (like the one you mentioned) Then you can have better convos about it.

As for the final three requests, go to the platy pleasant posh power poop python thread (or what ever the list of naems he calls it is! :D)

He has a requirement script that will do no. 2 He also has (if he hasn't removed them) an events with images section.

Not sure about the other things off the top of my head, but I am guessing the main request is quite complex.
 
With these larger requests, it might be a good idea to attacha link to a dedicated thread (like the one you mentioned) Then you can have better convos about it.
Here's the link (but it's also in my signature).
He also has (if he hasn't removed them) an events with images section.
I don't think so, I can't find it anywhere. If it still exists, could you point me to it. I still need it though.
He has a requirement script that will do no. 2
Thanks, that will work I guess.
I also need some way to make a wonder give a free tech or make a wonder give +1 production for farms.
 
I'm trying to mod the latest version of K-mod to increase the max number of players. I changed MAX_CIV_PLAYERS in CvDefines.h and recompiled but the change does not take effect, it still says MAX_CIV_PLAYERS = 18. I've made a few mods and never had trouble with this before. what else do I need to do?
 
I have some problems with the civicscreen in my mod.
Spoiler :
attachment.php
attachment.php

I have eight civic categories in my mod and I can't get them displayed on the normal screen. How can I find a solution for this? I use the scrolling civic screen by the way.
 

Attachments

  • Civ4ScreenShot0974.JPG
    Civ4ScreenShot0974.JPG
    120.8 KB · Views: 177
  • Civ4ScreenShot0975.JPG
    Civ4ScreenShot0975.JPG
    120.8 KB · Views: 203
I'm sure you have checked this but ... have you got /D_USRDLL in the list of compiler flags in your makefile?

this?
Code:
#### CFLAGS ####
GLOBAL_CFLAGS=/GR /Gy /W3 /EHsc /Gd /Gm- /DWIN32 /D_WINDOWS /D_USRDLL /DCVGAMECOREDLL_EXPORTS /Yu"CvGameCoreDLL.h"
Debug_CFLAGS=/MD /Zi /Od /D_DEBUG /DLOG_AI /RTC1 /Fp"$(Debug_PCH)" $(GLOBAL_CFLAGS)
Release_CFLAGS=/MD /O2 /Oy /Oi /Og /G7 /DNDEBUG /DFINAL_RELEASE /Fp"$(Release_PCH)" $(GLOBAL_CFLAGS)
Profile_CFLAGS=/MD /O2 /Oy /Oi /Og /G7 /DNDEBUG /DFP_PROFILE_ENABLE /DUSE_INTERNAL_PROFILER /Fp"$(Profile_PCH)" $(GLOBAL_CFLAGS)
 
Yep, that's what I was talking about. I would have been surprised if it was the problem, but sometimes its making basic assumptions that trip you up.

When you say:
it still says MAX_CIV_PLAYERS = 18
What is 'it' and where/how did you check it? Was this via a breakpoint at runtime or some other mechanism?
 
it gave a python exception when loading a map with more than 18 players. then I inserted a python print statement to print gc.getMaxCivTeams() and it printed 18.
 
I also need some way to make a wonder give a free tech or make a wonder give +1 production for farms.

You mean like the Oracle?
Code:
<iFreeTechs>1</iFreeTechs>

Not what you request but there is a tag:
Code:
			<ImprovementFreeSpecialists>
				<ImprovementFreeSpecialist>
					<ImprovementType>IMPROVEMENT_FOREST_PRESERVE</ImprovementType>
					<iFreeSpecialistCount>1</iFreeSpecialistCount>
				</ImprovementFreeSpecialist>
			</ImprovementFreeSpecialists>
 
You mean like the Oracle?
No, I should have been more specific. Example: The Eanna Temple should give +1 production for each farm. I thought it could be done by giving it a free specific "hidden tech" (TECH_EANNA?) which could give +1 production for a farm.
The specialists thing is a bit too much, you would get 10-15 free specialists.
Anybody know a solution to my civicscreen problem.
(I know I ask a lot the last few days...;)
 
No, I should have been more specific. Example: The Eanna Temple should give +1 production for each farm. I thought it could be done by giving it a free specific "hidden tech" (TECH_EANNA?) which could give +1 production for a farm.

A Tech coulb be easily granted by python but apart the two tags on irrigation?... :confused:
 
I have some problems with the civicscreen in my mod.
Spoiler :
attachment.php
attachment.php

I have eight civic categories in my mod and I can't get them displayed on the normal screen. How can I find a solution for this? I use the scrolling civic screen by the way.

It looks like you are double spacing the lines for the civics in the first column, presumably the value for the step size used to position them is too big or it is using the wrong one. The font for the effects of a civic is too big in the second column (it looks like it is using the font size for the headings in the left column for all the details in the right column) and it is needlessly skipping a line after the upkeep line.

Other mods have had issues with this, and I expect the mod component has these bugs in it. You might be able to find a mod that uses this but has already fixed it.
 
How can I save variables into the save file when the game saves?

I need to create an array with 2 global variables associated with each of the civs, and then I need this array to get saved into the save file so that it's loaded each time and available again. I am working in C++.

Does the game automatically save all global values with their names? or ... how does it work?


(Thank you).
 
I assume you mean in Python. You have to save any data manually since the game only saves its own data and is pretty much unaware of any Python data. There is a variable which is provided specifically for this on many of the game objects called "ScriptData".

If you are using BUG it has built-in functions to help you do this known as "BugData" as it is implemented in the BugData.py file.
There are also stand-alone mod components to help do this, like the SdToolKit.

To do it by hand without BUG or SdToolKit, what you do is have an event handler for the OnPreSave event in your CvEventManager.py file, in the BtS CvEventManager.py file there is already a function for this called onPreSave. In that function you can save the data to one or more scriptdata locations. You also need a function for the OnLoad event, which also already exists in the default BtS CvEventManager.py where it is called onLoadGame.

There are two relatively straightforward designs. The first is to store everything for a player in that player's CvPlayer object's scriptdata. The second is to store everything in a dictionary and store that dictionary in some object like the CvGame object.

To save an array on each player you'd have something like this (not tested, largely stolen from commented tu code int he original Final Frontier mod):
Code:
	def onPreSave(self, argsList):
		"called before a game is actually saved"
		CvUtil.pyPrint('OnPreSave')

		# save player data
		for iPlayerLoop in range(gc.getMAX_PLAYERS()):
			pPlayer = gc.getPlayer(iPlayerLoop)
			aPlayerData = self.aaiPlayerDatas[iPlayerLoop]
			pPlayer.setScriptData(pickle.dumps(aPlayerData))


	def onLoadGame(self, argsList):
		CvAdvisorUtils.resetNoLiberateCities()

		# Load player data
		for iPlayerLoop in range(gc.getMAX_PLAYERS()):
			pPlayer = gc.getPlayer(iPlayerLoop)
			aData = pickle.loads(pPlayer.getScriptData())
			self.aaiPlayerDatas[iPlayerLoop] = aData
		return 0
This assumes that the data for the players is stored in an array attached to the CvEventManager called aaiPlayerDatas with index being the player number (the "aai" prefix would indicate that it is intended to be an array of arrays of integers). If they are stored in some global arrays you just need to read/write them instead.

The CyPlayer.scritpdata variable holds a text string. The pickle object exists to convert things to a text string representation (via pickle.dumps(X)) and from a string back to a copy of the original object (via pickle.loads(X)). This "pickling" operation is also called "serialization" and some other things.

You would use these in the CvEventManager in the usual ways of manipulating arrays, perhaps something like these sorts of things:
Code:
		# initialize array of arrays, 1 per player with 2 values in each starting with 0 for both
		self.aaiPlayerDatas = [[0,0] for i in range(gc.getMAX_PLAYERS())]
		# change the data for player iPlayer
		self.aaiPlayerDatas[iPlayer][0] = 42
		self.aaiPlayerDatas[iPlayer][1] = 3.14

If you need to use the data in some other file, like CvGameUtils.py for example, you need to import CvEventInterface.py into that file and then get the event manager with the CvEventInterface.getEventManager() function and use that to access the variables, something like this:
Code:
		EM = CvEventInterface.getEventManager()
		EM.aaiPlayerDatas[iPlayer][0] = -1
There are probably other good ways of doing it, but because of that CvEventInterface.getEventManager() function making it easy to access the event manager object from any file, it is pretty easy to use that as the place to keep your data if you need to access it in more than one file.

The original Final Frontier mod is an example of doing "manually" this since all of the star system data, AI data, and tutorial data is stored in the scriptdata of various objects in this way. The Final Frontier Plus mod uses BugData to store some data, but mostly does it the same as plain Final Frontier (I had to switch the tutorial over since it was using the CyGame's scriptdata which BUG uses for BugData and there was therefore a conflict where one overwrote the other).
 
Thanks a lot for the thorough and helpful response. Very appreciated and will come handy...

...But ....I really did means C++,


Doh-face-copy.jpg








Yah... I'm working in the SDK. I need the C++. :cringe:
 
In C++ when you add variables to a class like CvPlayer or CvGame you must add them to the read and write functions of the class to get it saved. The order variables are read must match the order they are saved. There are about a millionty examples in the various .cpp files.

There is nothing that saves the state of global variables automatically (or anything else, for that matter). The data for the various classes is saved by the executable calling the write function for each object when it wants to write that object to the stream it has open to the save file, and similarly to read it in from the stream of data from the save file (the object is created and then the read function is called, passing it a pointer to the stream to read from). Any changes to these functions will destroy save game compatibility across versions (unless you are using C2C's code for this, which uses some labeled wrapper data on saved values, and default values for missing data, to enable cross version compatibility in many cases).

If you have variables not associated with a class and want to save them then you should maybe add them to either the class they are involved with (presumably CvPlayer in this case) or the CvGame object, instead of having them unassociated to anything that way. This is mainly for avoiding confusion later since it otherwise doesn't really matter if the values you are saving and loading are stored in an object or some global array, as long as the arrays have memory allocated for them before you try loading anything into them. Since you control the read and write functions, you can control where it gets and puts the data, so it is not required that the data be part of the class being saved or loaded at the time.
 
I don't understand this part? Irrigation? What did I say about irrigation?

Nothing, but these are the only tags in TechInfos related to farms...

You asked for a Wonder to give you a Tech to give you + 1 food on farms. It's easier to grant that with Python than through a Tech that has no tags for farms or even improvements.
 
Perfect. Thank you. That clarifies. I have seen the read and writes, didn't know about the order and class issue. Question that comes to mind now is if I initialize my variables to 0 after I create them in CvPlayer:: class, When those variables are reloaded from save files do they get reinitialized back to 0 again or are they safe? Is the "loading" coming after my initialization?

Also in the stream I noticed for read it says:
Code:
pStream->Read([B]&[/B]m_iGold);
But for white it says:
Code:
pStream->Write(m_iGold);

The difference is the "&" sign. I know the "&" is a reference maker, but I am not finding &iGold = iGold declared anywhere. Does that not cause a problem? Is it just understood by the system that it's referring to the same iGold? I wanna make sure I do this correctly.
 
Back
Top Bottom