An Idiots Guide to Editing the DLL

I can already tell this will be a great guide to modding the sdk once i get it working, only one problem

i can't get the sdk set up

i've tried downloading the sdk but as soon as i go to install it it starts up, shows a splash screen, then it says:

Error: Setup was started in a non-native or WoW environment.
Please run the setup package that is appropriate for your operating system installation

i'm running vista x64 on an HP laptop

i can't find any other place to download the sdk

any ideas?
 
There are two guides linked in the first post for setting up the SDK. One for Codeblocks, the other for Visual Studio. Both do a fantastic job of walking you through step-by-step. If you are trying to use a compiler which you already have on your computer and normally use, the issue is most probably that you do not have the proper base libraries, as they are all quite heavily outdated now (from 2003)
 
There are two guides linked in the first post for setting up the SDK. One for Codeblocks, the other for Visual Studio. Both do a fantastic job of walking you through step-by-step. If you are trying to use a compiler which you already have on your computer and normally use, the issue is most probably that you do not have the proper base libraries, as they are all quite heavily outdated now (from 2003)

so is there no way to set it up for another compiler?

i'm using the netbeans ide which i've already gotten used to, do i have to switch to codeblocks for this to work?
 
You have to use the rules of the 2003 VS compiler. As for which program you use, that is just a pretty GUI for doing your edits to the pre-compiled code, as long as you know how to define the new/old ruleset for compiling (probably a Makefile is pretty standard) in your IDE, you can use any of them. The catch is being familiar enough with the program to know how to force it to use other libraries and rulesets for the compilation process. I am sure you can find guides that are general for the program itself, and adapt them as needed to fit Civ's specific needs. If you do go through the effort to discover all of that, please write up a guide so that others can benefit from your work and possibly use a compiler better suited to their own tastes :)
 
ok this probably isn't the best forum to ask this but i think this is the root of all my problems:

is the sdk i'm supposed to be setting up the windows sdk so i can use c++, or is it something just for civ4? I'm already set up to program in C++ and without downloading anything i found a folder called CvGameCoreDLL which has all the files listed in the first post. So can i just get the makefile and then edit those files (backing them up first of course)?
 
How do traits work? I want to make it so that if a civ has a certain trait, it won't get resistance in captured cities. I've changed code from RFC to the following:
Code:
//Star Trek - Alliance civ trait
			if(!hasTrait(GC.getInfoTypeForString("TRAIT_ALLIANCE")))
			{
				pNewCity->changeOccupationTimer(((GC.getDefineINT("BASE_OCCUPATION_TURNS") + ((pNewCity->getPopulation() * GC.getDefineINT("OCCUPATION_TURNS_POPULATION_PERCENT")) / 100)) * (100 - iTeamCulturePercent)) / 100);
			}
			else
			{
				pNewCity->changeOccupationTimer(0);
			}
I'd rather not hardcode this, though. I'd like to create a new XML value, but I'm not sure how to reference it here.
 
You would add a Boolean tag to TraitInfos <bNoResistance> or something. Then in CvPlayer during ::setHasTrait (FfH code and a few others) or ::init (base BtS code) you would mark a Boolean on the player to indicate the ability. Query that Boolean here.

Alternatively, you could just loop over all traits here and check of the player has the trait and of so, check of the trait has this Boolean.
 
For reference, this is what I'm trying to do:
Softcoding Inquisition civics
The reason I'm trying to do this is that RevDCM is the core of many mods, and it makes sense to softcode the inquisition civics so that modders can easily change things in the XML.

How do I expose an array to Python? I've added a PrereqOrCivic array to UnitInfos and it works. However I'd like to now reference this array in CyUnit, and can't figure out how to expose it there. Also this tag is never referenced in CvUnit (it's a canTrain function, so like the resource and tech arrays, it's only referenced in CvPlayer). I'm assuming I need to add it to CvUnit in order to expose it to CyUnit, so how do I do this?

This is the code in CvInfos:

CvInfos.h
Code:
	//RevolutionDCM canTrain
	bool getPrereqOrCivics(int iCivic) const;				// Exposed to Python
	//RevolutionDCM end
...
	//RevolutionDCM canTrain
	bool* m_pbPrereqOrCivics;
	//RevolutionDCM end
CvInfos.cpp
Code:
//RevolutionDCM canTrain
m_pbPrereqOrCivics(NULL),
//RevolutionDCM end
...
	//RevolutionDCM canTrain
	SAFE_DELETE_ARRAY(m_pbPrereqOrCivics);
	//RevolutionDCM end
...
	//RevolutionDCM canTrain
	SAFE_DELETE_ARRAY(m_pbPrereqOrCivics);
	m_pbPrereqOrCivics = new bool[GC.getNumCivicInfos()];
	stream->Read(GC.getNumCivicInfos(), m_pbPrereqOrCivics);
	//RevolutionDCM end
...
	//RevolutionDCM canTrain
	stream->Write(GC.getNumCivicInfos(), m_pbPrereqOrCivics);
	//RevolutionDCM end
...
	pXML->SetVariableListTagPair(&m_pbPrereqOrCivics, "PrereqOrCivics", sizeof(GC.getCivicInfo((CivicTypes)0)), GC.getNumCivicInfos());
	//RevolutionDCM end
...
	//RevolutionDCM canTrain
	for ( int iCivic = 0; i < GC.getNumCivicInfos(); iCivic++)
	{
		if ( getPrereqOrCivics(iCivic) == bDefault )
		{
			m_pbPrereqOrCivics[iCivic] = pClassInfo->getPrereqOrCivics(iCivic);
		}
	}
	//RevolutionDCM end
...

And here is what the array looks like in UnitInfos
Code:
			<PrereqOrCivics>
				<PrereqCivic>
					<CivicOption>CIVIC_THEOCRACY</CivicOption>
					<bPrereqCivic>1</bPrereqCivic>
				</PrereqCivic>
				<PrereqCivic>
					<CivicOption>CIVIC_ORGANIZED_RELIGION</CivicOption>
					<bPrereqCivic>1</bPrereqCivic>
				</PrereqCivic>
			</PrereqOrCivics>


Also will exposing this array to CyUnit break save game compatibility?
 
You would want to leave it in CvPlayer, and thus CyPlayer, just for clarity I believe. Then in python you just reference the player identified with pUnit.getOwner() and check the canTrain against the player as normal. Reason being that most cases where you want to use canTrain you are checking about building a unit, it just HAPPENS to also be used for upgrading units. I guess that is the primary use for it in your case?

Anyway, there are plenty of examples for exposing arrays to python, if you just want the array itself (a UnitInfos object) then you can do it with a single line in the appropriate CyInfoInterface(1/2/3).cpp file (you just define a getPrereqOrCivics(int i) which points to the CvInfos function you wrote with this tag). The canTrain portion in CvPlayer is likely already exposed to python, so as long as you have included the check in there you'll be set in that regard.

Exposing things never harms savegame compat status to my knowledge, as you aren't saving/loading any new data.
 
The problem with using the existing python exposure is that it checks if the unit can be trained. But I specifically only want to check if the player is running one of the civics defined in the units array and nothing else.
 
Sounds like what you want is to just use the UnitInfo exposure then. I assume this is for checking when they move OUT of a civic to see if the unit should be lost? You could do that check in the DLL as well quite easily.

Anyway, to a getUnitInfo(pUnit.getUnitType()).getPrereqOrCivics(i) check, you just need the single line entry in CyInfoInterface(1/2/3), whichever holds all the other unitinfo exposure.
 
Don't I need to also put the variable in CvUnit and CyUnit if I want it to be able to call the civics from python? At least the call isNukeImmune in CvUnit isn't referenced in the SDK, and seems to have it's functional aspects work in python, yet if you follow it, it is set in CvUnit and CyUnit respectively, as well as CyInfoInterface.

Looks like I'm going to need to google loops again. I can't figure out how to really code this without using a loop, and I can't remember how to code a loop that would work for this :crazyeye:
 
No, this will be something which doesn't need to be loaded onto the unit (pUnit), just the UnitInfo (eUnit). It exists only in CvInfos, specifically in the CvUnitInfo section of it (where XML is loaded from).

The only time you would need to move to having this as a property of the CvUnit object would be if you allowed promotions or something else to modify it. But since any unit which is UNIT_WARRIOR in the XML (for example) will ALWAYS have a certain PrereqCivic requirement, you can leave the data in CvInfos (same place that the name "Warrior" exists).


You are loading your data into an array of getNumCivicTypes() size, right? So any civic which is required just has a TRUE stored in that spot of the array. So you would do a loop over getNumCivicTypes(), check if the Unit gives you a TRUE for requiring that civic, then check if the player who owns the unit is following that civic. If not, unit needs killing.
 
Hey Xienwolf, using one of your current example new tags you've created in the tutorial, could you add a tut on how to do that and make the new tag save game compatible with a previous version that didn't have the new tag?
 
I could look at doing that. Probably best not to have it too early in the series so I don't confuse new codemonkies, but also best not to have it on the arrays so it isn't terribly complicated. Then again, most cases don't get complicated when adding new material, it is when you alter things that it goes a bit crazy.
 
I added a whole new class to the dll and I was wondering whether or not I need to create pStream->Read and ->Write parts? For now, I only have the read function that read the xml, not the saves functions, not sure I need them.
 
Top Bottom