Modmodding Q&A Thread

I also don't see anything wrong with your code. Does the tooltip work outside of the WB?
 
What about my glitch? Did you look in it?
 
Not yet.
 
I also don't see anything wrong with your code. Does the tooltip work outside of the WB?

yes its working perfectly as far as I can tell. I only opened WB to give myself the resources to test the tooltip. I'm still getting the same C++ exception.
 
Maybe you have to make sure that pCity isn't null? Usually you are in a city screen when showing the unit tooltip, but that's not the case when you're in the world builder interface, so it could be a null pointer exception.
 
Is there a scripted event that destroys Indian cities in 600AD scenario. Moreover, which function controls birth of civs?
 
Is there a scripted event that destroys Indian cities in 600AD scenario. Moreover, which function controls birth of civs?
I don't think there is such a scripted event.

And the birth of civs starts with initBirth().
 
I don't think there is such a scripted event.

In that case, there is a very strange bug to report in my 500AD modmodmod. What can cause the complete destruction of three cities just one turn before the Arab spawn?
 
:dunno:
 
If you select a civ that requires autoplay, it spawns immediately at 500 ad with a warrior, no tech and no flip. The ai spawns work fine though.
I have a feeling that the problem relating to the player not spawning as well as the loading dates error is somewhere in CvRhye or whatever it is called. Leoreth, did you encounter the same problem in the 1700 AD? Do you think that is where the autoplay and opening screen problems are?
^This.

However, by some miracle, I was able to persuade my brother to let me install Civ4 from his Steam onto the laptop that he uses, so I can work on the mod now. What do you think causes the problem that makes the player unable to autoplay in the 500 AD scenario?
 
You probably will have to change the scenario starting date in RFCUtils.py and CvGameCoreUtils.cpp.
 
Maybe you have to make sure that pCity isn't null? Usually you are in a city screen when showing the unit tooltip, but that's not the case when you're in the world builder interface, so it could be a null pointer exception.

thank you Leoreth. I have no idea what a null pointer is but I got it to work. here is the whole implementation in case anyone is interested or wants to use it in a mod. one caveat is that it doesn't deal with "Or" bonus prereqs.

in CvPlot::canTrain:

Spoiler :
Code:
		if (GC.getUnitInfo(eUnit).getPrereqAndBonus() != NO_BONUS)
		{
			if (NULL == pCity)
			{
				if (!isPlotGroupConnectedBonus(getOwnerINLINE(), (BonusTypes)GC.getUnitInfo(eUnit).getPrereqAndBonus()))
				{
					return false;
				}
			}
			else
			{
				if (!pCity->hasBonus((BonusTypes)GC.getUnitInfo(eUnit).getPrereqAndBonus()))
				{
					return false;
				}
			}
			// srpt resource unit restriction mk II
			int iJ = 0;
			for (int iI = 0; iI < GC.getNumUnitInfos(); iI++)
			{
				if ( GC.getUnitInfo((UnitTypes)iI).getPrereqAndBonus() == GC.getUnitInfo(eUnit).getPrereqAndBonus() )
				{
					UnitClassTypes eUnitClass = ((UnitClassTypes)(GC.getUnitInfo((UnitTypes)iI).getUnitClassType()));
					iJ += (GET_PLAYER(getOwnerINLINE()).getUnitClassCountPlusMaking(eUnitClass));
				}
			}
			if (iJ >= ((pCity->getNumBonuses((BonusTypes)GC.getUnitInfo(eUnit).getPrereqAndBonus())) * 6) )
			{
				return false;
			}
		}
		// srpt end

and the tooltip, in CvGameTextMgr::setUnitHelp:

Spoiler :
Code:
	// srpt resource unit restriction
	if (pCity != NULL)
	{
		if( GC.getUnitInfo(eUnit).getPrereqAndBonus() != NO_BONUS )
		{
			iJ = 0;
			int iK = 0;
			int iL = 0;
			for (int iI = 0; iI < GC.getNumUnitInfos(); iI++)
			{
				if ( GC.getUnitInfo((UnitTypes)iI).getPrereqAndBonus() == GC.getUnitInfo(eUnit).getPrereqAndBonus() )
				{
					UnitClassTypes eUnitClass = (UnitClassTypes)GC.getUnitInfo((UnitTypes)iI).getUnitClassType();
					iJ += (GET_PLAYER(ePlayer).getUnitClassCountPlusMaking(eUnitClass));
				}
			}
			iK = pCity->getNumBonuses((BonusTypes)GC.getUnitInfo(eUnit).getPrereqAndBonus())*6;
			iL = (iK - iJ);
			if (iL < 0)
			{
				iL = 0;
			}
			szBuffer.append(NEWLINE);
			szBuffer.append(gDLL->getText("TXT_KEY_UNIT_RESOURCE_BASED_UNIT_LEFT", (iL)));
		}
	}

 
To whenever the scenario starts. 500 AD in this case apparently.
 
thank you Leoreth. I have no idea what a null pointer is but I got it to work. here is the whole implementation in case anyone is interested or wants to use it in a mod. one caveat is that it doesn't deal with "Or" bonus prereqs.

in CvPlot::canTrain:

Spoiler :
Code:
		if (GC.getUnitInfo(eUnit).getPrereqAndBonus() != NO_BONUS)
		{
			if (NULL == pCity)
			{
				if (!isPlotGroupConnectedBonus(getOwnerINLINE(), (BonusTypes)GC.getUnitInfo(eUnit).getPrereqAndBonus()))
				{
					return false;
				}
			}
			else
			{
				if (!pCity->hasBonus((BonusTypes)GC.getUnitInfo(eUnit).getPrereqAndBonus()))
				{
					return false;
				}
			}
			// srpt resource unit restriction mk II
			int iJ = 0;
			for (int iI = 0; iI < GC.getNumUnitInfos(); iI++)
			{
				if ( GC.getUnitInfo((UnitTypes)iI).getPrereqAndBonus() == GC.getUnitInfo(eUnit).getPrereqAndBonus() )
				{
					UnitClassTypes eUnitClass = ((UnitClassTypes)(GC.getUnitInfo((UnitTypes)iI).getUnitClassType()));
					iJ += (GET_PLAYER(getOwnerINLINE()).getUnitClassCountPlusMaking(eUnitClass));
				}
			}
			if (iJ >= ((pCity->getNumBonuses((BonusTypes)GC.getUnitInfo(eUnit).getPrereqAndBonus())) * 6) )
			{
				return false;
			}
		}
		// srpt end

and the tooltip, in CvGameTextMgr::setUnitHelp:

Spoiler :
Code:
	// srpt resource unit restriction
	if (pCity != NULL)
	{
		if( GC.getUnitInfo(eUnit).getPrereqAndBonus() != NO_BONUS )
		{
			iJ = 0;
			int iK = 0;
			int iL = 0;
			for (int iI = 0; iI < GC.getNumUnitInfos(); iI++)
			{
				if ( GC.getUnitInfo((UnitTypes)iI).getPrereqAndBonus() == GC.getUnitInfo(eUnit).getPrereqAndBonus() )
				{
					UnitClassTypes eUnitClass = (UnitClassTypes)GC.getUnitInfo((UnitTypes)iI).getUnitClassType();
					iJ += (GET_PLAYER(ePlayer).getUnitClassCountPlusMaking(eUnitClass));
				}
			}
			iK = pCity->getNumBonuses((BonusTypes)GC.getUnitInfo(eUnit).getPrereqAndBonus())*6;
			iL = (iK - iJ);
			if (iL < 0)
			{
				iL = 0;
			}
			szBuffer.append(NEWLINE);
			szBuffer.append(gDLL->getText("TXT_KEY_UNIT_RESOURCE_BASED_UNIT_LEFT", (iL)));
		}
	}


Oooh, is that RFC India? If it is, how far along are you with it?
 
To whenever the scenario starts. 500 AD in this case apparently.

I checked, and all of them have 500 AD:
To clarify:
Code:
// Leoreth: identify the active scenario

ScenarioTypes getScenario()
{
	if (GET_PLAYER((PlayerTypes)EGYPT).isPlayable()) return SCENARIO_3000BC;

	if (GET_PLAYER((PlayerTypes)GREECE).isPlayable()) return SCENARIO_500AD;

	if (GET_PLAYER((PlayerTypes)BYZANTIUM).isPlayable()) return SCENARIO_600AD;

	return SCENARIO_1700AD;
}

int getScenarioStartYear()
{
	ScenarioTypes eScenario = getScenario();

	if (eScenario == SCENARIO_3000BC) return -3000;
	else if (eScenario == SCENARIO_500AD) return 500:
	else if (eScenario == SCENARIO_600AD) return 600;
	else return 1700;
}

int getScenarioStartTurn()
{
	return getTurnForYear(getScenarioStartYear());
}

Code:
	def getScenario(self):
		if gc.getPlayer(con.iEgypt).isPlayable():
			return con.i3000BC

		if gc.getPlayer(con.iGreece).isPlayable():
			return con.i500AD
		
		if gc.getPlayer(con.iByzantium).isPlayable():
			return con.i600AD
		
		return con.i1700AD
		
	def getScenarioStartYear(self):
		lStartYears = [-3000, 500, 600, 1700]
		return lStartYears[self.getScenario()]
		
	def getScenarioStartTurn(self):
		return getTurnForYear(self.getScenarioStartYear())

Where is the code for autoplay? The problem might be there.
 
Have you compiled the C++ code?
 
Have you compiled the C++ code?

How do I do that? That is probably where the problem is.

EDIT: I've downloaded and installed a DLL compiler program and I've also tried looking around the Internet for a tutorial on how to compile a DLL. I've even tried to open your DLL (but the computer won't let me). Do I just copy-paste all of the code in, or do I merely call/import all of the modules?
 
Looking how to compile a DLL in general is probably too much for your purposes because you still have to figure out how to compile the BtS source code. I recommend this tutorial instead.

In general, the Civ4 Modiki is worth checking out for more general information about Civ4 modding - maybe you want an overview of how the game as a whole is structured instead of my very narrow answers for specific features.
 
Looking how to compile a DLL in general is probably too much for your purposes because you still have to figure out how to compile the BtS source code. I recommend this tutorial instead.

In general, the Civ4 Modiki is worth checking out for more general information about Civ4 modding - maybe you want an overview of how the game as a whole is structured instead of my very narrow answers for specific features.

I think that tutorial was all I needed. I know enough Python and C++ to be able to write and mod the actual code, I just didn't know how to compile a DLL. The way you answer problems is fine. Thanks!
 
Top Bottom