Techs: how to make one exclusive to another

Okay, so I've gone into CvGlobals.cpp.

Under "CvGlobals gGlobals;", I changed:

Spoiler :
Code:
m_iNUM_UNIT_AND_TECH_PREREQS(0),
m_iNUM_AND_TECH_PREREQS(0),
m_iNUM_OR_TECH_PREREQS(0),
m_iLAKE_MAX_AREA_SIZE(0),

into

Spoiler :
Code:
m_iNUM_UNIT_AND_TECH_PREREQS(0),
m_iNUM_AND_TECH_PREREQS(0),
m_iNUM_OR_TECH_PREREQS(0),
[B]m_iNUM_OR_TECH_PREREQS(0)[/B],
m_iLAKE_MAX_AREA_SIZE(0),

Under "void CvGlobals::cacheGlobals()", I changed

Spoiler :
Code:
	m_iNUM_UNIT_AND_TECH_PREREQS = getDefineINT("NUM_UNIT_AND_TECH_PREREQS");
	m_iNUM_AND_TECH_PREREQS = getDefineINT("NUM_AND_TECH_PREREQS");
	m_iNUM_OR_TECH_PREREQS = getDefineINT("NUM_OR_TECH_PREREQS");
	m_iLAKE_MAX_AREA_SIZE = getDefineINT("LAKE_MAX_AREA_SIZE");

to

Spoiler :
Code:
	m_iNUM_UNIT_AND_TECH_PREREQS = getDefineINT("NUM_UNIT_AND_TECH_PREREQS");
	m_iNUM_AND_TECH_PREREQS = getDefineINT("NUM_AND_TECH_PREREQS");
	m_iNUM_OR_TECH_PREREQS = getDefineINT("NUM_OR_TECH_PREREQS");
	[B]m_iNUM_NOT_TECH_PREREQS = getDefineINT("NUM_NOT_TECH_PREREQS");[/B]
	m_iLAKE_MAX_AREA_SIZE = getDefineINT("LAKE_MAX_AREA_SIZE");

Then, again under that section, I changed

Spoiler :
Code:
int CvGlobals::getNUM_UNIT_AND_TECH_PREREQS()
{
	return m_iNUM_UNIT_AND_TECH_PREREQS;
}

int CvGlobals::getNUM_AND_TECH_PREREQS()
{
	return m_iNUM_AND_TECH_PREREQS;
}

int CvGlobals::getNUM_OR_TECH_PREREQS()
{
	return m_iNUM_OR_TECH_PREREQS;
}

int CvGlobals::getLAKE_MAX_AREA_SIZE()
{
	return m_iLAKE_MAX_AREA_SIZE;
}

to

Spoiler :
Code:
int CvGlobals::getNUM_UNIT_AND_TECH_PREREQS()
{
	return m_iNUM_UNIT_AND_TECH_PREREQS;
}

int CvGlobals::getNUM_AND_TECH_PREREQS()
{
	return m_iNUM_AND_TECH_PREREQS;
}

int CvGlobals::getNUM_OR_TECH_PREREQS()
{
	return m_iNUM_OR_TECH_PREREQS;
}

[B]int CvGlobals::getNUM_NOT_TECH_PREREQS()
{
	return m_iNUM_NOT_TECH_PREREQS;
}[/B]

int CvGlobals::getLAKE_MAX_AREA_SIZE()
{
	return m_iLAKE_MAX_AREA_SIZE;
}

I then went into CvGlobals.h and did the same thing: everytime I saw an entry that I thought related to OR_TECH, I copied the code and pasted in a new entry, changing it to NOT_TECH (or NotTech, as the case may be).

In fact, I only made 2 changes to the .h file. First off, under "///////////////// BEGIN global defines", I changed

Spoiler :
Code:
	DllExport int getNUM_UNIT_AND_TECH_PREREQS();
	DllExport int getNUM_AND_TECH_PREREQS();
	DllExport int getNUM_OR_TECH_PREREQS();
	DllExport int getLAKE_MAX_AREA_SIZE();

to

Spoiler :
Code:
	DllExport int getNUM_UNIT_AND_TECH_PREREQS();
	DllExport int getNUM_AND_TECH_PREREQS();
	DllExport int getNUM_OR_TECH_PREREQS();
	[B]DllExport int getNUM_NOT_TECH_PREREQS();[/B]
	DllExport int getLAKE_MAX_AREA_SIZE();

Secondly, under "FVariableSystem* m_VarSystem;", I changed
Spoiler :

Code:
	int m_iNUM_UNIT_AND_TECH_PREREQS;
	int m_iNUM_AND_TECH_PREREQS;
	int m_iNUM_OR_TECH_PREREQS;
	int m_iLAKE_MAX_AREA_SIZE;

to

Spoiler :
Code:
	int m_iNUM_UNIT_AND_TECH_PREREQS;
	int m_iNUM_AND_TECH_PREREQS;
	int m_iNUM_OR_TECH_PREREQS;
	[B]int m_iNUM_NOT_TECH_PREREQS;[/B]
	int m_iLAKE_MAX_AREA_SIZE;

Went I went to compile, CodeBlocks gave me this error:

Code:
CvGlobals.cpp
[COLOR="Red"]CvGlobals.cpp(222) : error C2437: 'm_iNUM_OR_TECH_PREREQS' : already initialized
Process terminated with status 1 (2 minutes, 1 seconds)[/COLOR]
[COLOR="Blue"]1 errors, 0 warnings[/COLOR]

Does this mean that I've done something that I didn't need to do?
 
In your second spoiler up there, it says "OR" instead of "NOT". Simply typo
 
Okay, the DLL has compiled successfully. But now, XML problems :lol:

OK, thanks for all your help. I'm just trying to organise the process in my head.

XML preparation

The first thing I need to do is add to CIV4TechnologiesSchema.xml. Going by what's been said, this is what I think I need:

Spoiler :
Code:
<ElementType name="PrereqTech" content="textOnly"/>
    <ElementType name="OrPreReqs" content="eltOnly">
        <element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
    </ElementType>
    <ElementType name="AndPreReqs" content="eltOnly">
        <element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
    </ElementType>

becomes

Spoiler :
Code:
<ElementType name="PrereqTech" content="textOnly"/>
[B]    <ElementType name="NotPreReqs" content="eltOnly">
        <element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
    </ElementType>[/B]
    <ElementType name="OrPreReqs" content="eltOnly">
        <element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
    </ElementType>
    <ElementType name="AndPreReqs" content="eltOnly">
        <element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
    </ElementType>

When I try and load the mod, it tells that it's expecting "OrPreReqs" where it should be expecting "NotPreReqs" :(
 
I've only ever done XML modding, but that always happened to me when I messed up the order in the XML file, like putting defensecombatmod in front of attackcombatmod, or when I left a \ in front of a tag that I gave values for.
 
Right, make sure the tags are in the same order that the schema specifies. And if you haven't changed the schema to include your new tags, do so.
 
You didn't update the Schema properly.
Code:
    <element type="Flavors"/>
    <element type="OrPreReqs"/>

should be
Code:
    <element type="Flavors"/>
    <element type="NotPreReqs"/>
    <element type="OrPreReqs"/>
 
That's weird. The base BTS tech schema runs like so:

Code:
	<ElementType name="FlavorType" content="textOnly"/>
	<ElementType name="iFlavor" content="textOnly" dt:type="int"/>
	<ElementType name="Flavor" content="eltOnly">
		<element type="FlavorType"/>
		<element type="iFlavor"/>
	</ElementType>
	<ElementType name="Flavors" content="eltOnly">
		<element type="Flavor" minOccurs="0" maxOccurs="*"/>
	</ElementType>
	<ElementType name="PrereqTech" content="textOnly"/>
	<ElementType name="OrPreReqs" content="eltOnly">
		<element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
	</ElementType>
	<ElementType name="AndPreReqs" content="eltOnly">
		<element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
	</ElementType>
	<ElementType name="Quote" content="textOnly"/>

Thus I had assumed that "<ElementType name="PrereqTech" content="textOnly"/>" introduced tech prereqs, that I had to keep that, and add what I have added. Namely, it becomes like so (or so i thought):

Code:
<ElementType name="FlavorType" content="textOnly"/>
	<ElementType name="iFlavor" content="textOnly" dt:type="int"/>
	<ElementType name="Flavor" content="eltOnly">
		<element type="FlavorType"/>
		<element type="iFlavor"/>
	</ElementType>
	<ElementType name="Flavors" content="eltOnly">
		<element type="Flavor" minOccurs="0" maxOccurs="*"/>
	</ElementType>
	<ElementType name="PrereqTech" content="textOnly"/>
	[B]<ElementType name="NotPreReqs" content="eltOnly">
		<element type="PrereqTech" minOccurs="0" maxOccurs="*"/>[/B]
	</ElementType>
	<ElementType name="OrPreReqs" content="eltOnly">
		<element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
	</ElementType>
	<ElementType name="AndPreReqs" content="eltOnly">
		<element type="PrereqTech" minOccurs="0" maxOccurs="*"/>
	</ElementType>
	<ElementType name="Quote" content="textOnly"/>

You seem to be suggesting that I ditch certain lines that are present in the base BTS file, so my modded file looks like this:

Code:
<ElementType name="FlavorType" content="textOnly"/>
	<ElementType name="iFlavor" content="textOnly" dt:type="int"/>
	<ElementType name="Flavor" content="eltOnly">
		<element type="FlavorType"/>
		<element type="iFlavor"/>
	</ElementType>
	<ElementType name="Flavors" content="eltOnly">
		<element type="Flavor" minOccurs="0" maxOccurs="*"/>
	</ElementType>
[B]	<ElementType name="NotPreReqs" content="eltOnly">
	</ElementType>
	<ElementType name="OrPreReqs" content="eltOnly">
	</ElementType>
	<ElementType name="AndPreReqs" content="eltOnly">
	</ElementType>[/B]
	<ElementType name="Quote" content="textOnly"/>

Am I right?
 
Not at all. There are lines later in the file that I'm referring to. Do a find for "OrPreReqs" in your files. Everywhere it is, so should be your new tag.
 
Okay, so the mod loads fine - at this stage the mod is only the DLL and the 2 tech XML files (TechInfos and TechnologiesSchema). So far, however, I hadn't actually made any rule changes (i.e. the NOT prereq for techs had not yet been implemented).

I changed the tech entries for Bronze Working and Horseback Riding like so:

Bronze Working
Code:
			<NotPreReqs>
				<PrereqTech>TECH_HORSEBACK_RIDING</PrereqTech>
			</NotPreReqs>
			<OrPreReqs>
				<PrereqTech>TECH_MINING</PrereqTech>
			</OrPreReqs>
			<AndPreReqs/>

Horseback Riding
Code:
			<NotPreReqs>
				<PrereqTech>TECH_BRONZE_WORKING</PrereqTech>
			</NotPreReqs>	
			<OrPreReqs>
				<PrereqTech>TECH_ANIMAL_HUSBANDRY</PrereqTech>
			</OrPreReqs>
			<AndPreReqs/>

What I was hoping for was that once I had researched Bronze Working, I would not be able to research Horseback Riding, and vice-versa. However, when I got in-game (no loading errors) I was able to research both. So I think the C++ code hasn't actually done anything :(
 
Please, can anyone help? Here again is the 'meat' of the code that I was advised on:

You simply need to add your own loop like this:
Code:
    for (iI = 0; iI < GC.getNUM_NOT_TECH_PREREQS(); iI++)
    { // You'll need this new method for GC's NUM_NOT_TECH_PREREQS
        TechTypes ePrereq = (TechTypes)GC.getTechInfo(eTech).getPrereqNotTechs(iI); // And you need this new method
        if (ePrereq != NO_TECH)
        {
            if (GET_TEAM(getTeam()).isHasTech(ePrereq))
            { // Read the above line carefully, removed '!'
                return false;
            }
            
            if (bTrade && !GC.getGameINLINE().isOption(GAMEOPTION_NO_TECH_BROKERING) && GET_TEAM(getTeam()).isNoTradeTech(ePrereq))
            { // You should probably make any tech used as a 'not' prereq untradable, you'll still have issues with teams
                return false;
            }
        }
    }
 
Back
Top Bottom