Request: Assistance with religion changes

OK, here is what I've come up with so far. It compiles correctly, but doesn't seem to work:

Code:
ReligionTypes eReligion = (ReligionTypes)GC.getBuildingInfo(eBuilding).getFoundsReligion();
	if (eReligion != NO_RELIGION)
	{
		if (GC.getGameINLINE().isReligionFounded(eReligion))
		{
			return false;
		}

		iFounded = 0;

		for (int iReligion = 0; iReligion < GC.getNumReligionInfos(); ++iReligion)
		{
			if (isHolyCity((ReligionTypes)iReligion))
			{
				return false;
			}

			if (GC.getGameINLINE().isReligionFounded(eReligion))
			{
				iFounded = iFounded + 1;

				if (iFounded >= GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getDefaultPlayers() )
				{
					return false;
				}
			}
		}
	}

What I aimed to do:

I created an int to track the number of religions founded, iFounded. I defined it as 0, and then in the loop had it add 1 for each founded religion. When iFounded is greater or equal to the DefaultPlayers value from WorldInfos.xml, don't allow any more religions to be founded.

I think my logic is solid, but I suspect I have something in the wrong place.

I want to thank you again for your help; you are giving me just the right amount of help without doing it for me and I appreciate that. Give a man a fish, and all that stuff. :)
The key to your problem is that eReligion and iReligion are two different variables.

Btw, since it compiled I assume that you declared the iFounded variable somewhere outside the posted part? In C++ you can do it right where you intialise it (which is usually a good idea as that way there is no chance that you accidently use an uninitialised variable).
 
The key to your problem is that eReligion and iReligion are two different variables.

Btw, since it compiled I assume that you declared the iFounded variable somewhere outside the posted part? In C++ you can do it right where you intialise it (which is usually a good idea as that way there is no chance that you accidently use an uninitialised variable).


Hmmmm. Been thinking on this and doing some reading for a couple of hours and am still a little stumped here. I'm going to try and talk this out.

eReligion is assigned in the first line of code, and if i am correct it is an integer that each religion is assigned based on the order in the XML. (0 = RELIGION_BUDDHISM, 1 RELIGION_HINDUISM, etc.) (An enum?).

The code is looking at the FoundsReligion tag in the XML in BuildingInfos. There is then a check for a value in that field before going on to the next part of code. It then checks and sees if the religion is founded, and if it is founded to terminate the function, thereby rendering the building as unable to be built. I then declare the integer I need to keep track of the number of religions founded. (I had put it up at the beginning of the function with the other declarations. Didn't realize if that was mandatory or not.

The next step is a loop. The variable used to store the number of times to process the loop is designated as iReligion. iReligion is assigned the value determined by the number of religions listed in the XML. Inside the loop, I use the same "Is the religion founded" bit checking eReligion as before. If the religion is founded, it adds 1 to iFounded. It then looks at iFounded and doesn't allow the building to be built is the max number of religions is reached.

It then looks at isHolyCity, and I don't understand why it is passing iPlayer. Passing the number of religions to a bool like that doesnt make sense.

I apologize if any of this seems stream-of-consciousness, it just helped to write it down as I was thinking it through. I feel like I'm starting to get the hang of some of the basics of C++ and I think my logic up there is mostly correct. Again, I appreciate the help. :)
 
Hmmmm. Been thinking on this and doing some reading for a couple of hours and am still a little stumped here. I'm going to try and talk this out.

eReligion is assigned in the first line of code, and if i am correct it is an integer that each religion is assigned based on the order in the XML. (0 = RELIGION_BUDDHISM, 1 RELIGION_HINDUISM, etc.) (An enum?).

The code is looking at the FoundsReligion tag in the XML in BuildingInfos. There is then a check for a value in that field before going on to the next part of code. It then checks and sees if the religion is founded, and if it is founded to terminate the function, thereby rendering the building as unable to be built. I then declare the integer I need to keep track of the number of religions founded. (I had put it up at the beginning of the function with the other declarations. Didn't realize if that was mandatory or not.
In C++ you can declare a local variable nearly anywhere in a function and it is good style to keep it as local as possible.

The next step is a loop. The variable used to store the number of times to process the loop is designated as iReligion. iReligion is assigned the value determined by the number of religions listed in the XML. Inside the loop, I use the same "Is the religion founded" bit checking eReligion as before. If the religion is founded, it adds 1 to iFounded. It then looks at iFounded and doesn't allow the building to be built is the max number of religions is reached.

It then looks at isHolyCity, and I don't understand why it is passing iPlayer. Passing the number of religions to a bool like that doesnt make sense.

I apologize if any of this seems stream-of-consciousness, it just helped to write it down as I was thinking it through. I feel like I'm starting to get the hang of some of the basics of C++ and I think my logic up there is mostly correct. Again, I appreciate the help. :)
eReligion is the religion that would be founded. iReligion is looped over all the religions. To count them you need to check iReligion in the inner loop but currently you use eReligion there.
 
OK. Got it working with that info.

Code:
//<True Prophet Mod Start>
	ReligionTypes eReligion = (ReligionTypes)GC.getBuildingInfo(eBuilding).getFoundsReligion();
	if (eReligion != NO_RELIGION)
	{
		if (GC.getGameINLINE().isReligionFounded(eReligion))
		{
			return false;
		}

		int iFounded;
		iFounded = 0;

		for (int iReligion = 0; iReligion < GC.getNumReligionInfos(); ++iReligion)
		{
			//if (GC.getGameINLINE().isReligionFounded(iReligion))
			if (GC.getGameINLINE().isReligionFounded((ReligionTypes)iReligion))
			{
				iFounded = iFounded + 1;

				if (iFounded >= GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getDefaultPlayers() )
				{
					return false;
				}
			}

			if (isHolyCity((ReligionTypes)iReligion))
			{
				return false;
			}
		}
	}
	//<True Prophet Mod End>

What I don't quite understand is why I would use iplayer there instead of eplayer.

So this line:
Code:
if (GC.getGameINLINE().isReligionFounded(eReligion))

I understand how this works, I believe.

I must be confused somewhere in my understanding of the loop.

The first line of the loop: the int part in parentheses says "create an integer variable and call it iPlayer. Assign the value of 0 to iPlayer. if iPlayer is less than the number of religions listed in the xml, add 1 to iPlayer. Let's say I have 10 religions in the XML. So iPlayer will equal 10, determining the number of times the loop is performed.

So it starts the loop: at this line
Code:
if (GC.getGameINLINE().isReligionFounded((ReligionTypes)iReligion))
iReligion is just the number of times the loop is running? Wouldn't this need the eplayer variable just like in the section above as we already know the loop is running iReligion # of times?

I think I am missing something re how the loop is constructed.

I'm jazzed that it is actually working and that I can finally get this thing tidied up and out the door. :):):)
 
What I don't quite understand is why I would use iplayer there instead of eplayer.

So this line:
Code:
if (GC.getGameINLINE().isReligionFounded(eReligion))

I understand how this works, I believe.

I must be confused somewhere in my understanding of the loop.

The first line of the loop: the int part in parentheses says "create an integer variable and call it iPlayer. Assign the value of 0 to iPlayer. if iPlayer is less than the number of religions listed in the xml, add 1 to iPlayer. Let's say I have 10 religions in the XML. So iPlayer will equal 10, determining the number of times the loop is performed.
I assume you mean iReligion and eReligion and not iPlayer and ePlayer.

How the C++ for loop works. Lets assume this:

for (A; B; C)
{
Do something;
}

This equals:
A;
while (B)
{
Do something;
C;
}

So you do A before the loop starts, execute the loop as long as B is true and execute C at the end of each run of the loop body.
Usually you use A to define and initialize a loop variable (e.g. int i = 0), B is the condition (e.g. i < num) and C increments the loop variable (e.g. i++).

So this:
for (int i = 0; i < 3; i++)
{
DoSomething(i);
}

Equals:
DoSomething(0);
DoSomething(1);
DoSomething(2);
 
OK, this makes sense.

Unless I am mistaken, ePlayer and iPlayer are the same value? ePlayer is 0-6, with the numbers 0 - 6 representing the 7 religions in order of the XML.

iPlayer is also 0-6, again representing the same thing? So we use iPlayer in the loop as it is generated in a different manner? (I don't know if this makes sense)
 
OK, this makes sense.

Unless I am mistaken, ePlayer and iPlayer are the same value? ePlayer is 0-6, with the numbers 0 - 6 representing the 7 religions in order of the XML.

iPlayer is also 0-6, again representing the same thing? So we use iPlayer in the loop as it is generated in a different manner? (I don't know if this makes sense)
Starting the variable name with e or i is a convention that is supposed to tell the reader what type that variable has.
i means it is an int (a signed number without decimals).
e means it is an enum (an enumeration). While internally C++ stores that as an int, the compiler will not accept a direct assignment of an int to an enum. Instead you have to type cast the value (e.g. ReligionTypes eReligion = (ReligionTypes) iReligion; ).
 
OK, this makes sense.

Unless I am mistaken, ePlayer and iPlayer are the same value? ePlayer is 0-6, with the numbers 0 - 6 representing the 7 religions in order of the XML.

iPlayer is also 0-6, again representing the same thing? So we use iPlayer in the loop as it is generated in a different manner? (I don't know if this makes sense)

eReligion is one specific value, that being the number for the religion that the building causes to be founded as per your "ReligionTypes eReligion = (ReligionTypes)GC.getBuildingInfo(eBuilding).getFoundsReligion();" line of code.

iReligion is also one specific value. It is just a different specific value each time it goes through the loop. If there are 7 religions, the first time all of the code in the {} after the for statement is run it will be 0, the second time through all that code it is 1, and so on through 6. When it is bumped up to 7 by the "++iReligion" the loop exits before the code is run again due to the condition "iReligion < GC.getNumReligionInfos()" evaluating to "false".

This is pretty much the entire point of a loop: It is a chunk of code that is run multiple times using a different value assigned to the loop variable each time the chunk of code is run. The code keeps running as long as the specified condition evaluates to "true" when it is checked before the start of the next pass through the loop.

Any simple variable is always just one specific value (well, in C++ or Python, anyway - there are some languages that may do more complicated things). To specify a range of values you'd need some sort of data structure, or at least an array. There is no way for a single enum or integer variable to be a range like "0-6", it has to be just one number.

I recommend that you check out one or more of then innumerable tutorials on the fundamentals of programming that are all over the place on the web if you plan on continuing with C++ (or Python) modding.
 
Back
Top Bottom