Modmodding Q&A Thread

Can you post the relevant code? Use [code][/code] tags please.
 
Code:
# Spawning cities (Leoreth)
# Year, coordinates, owner, name, population, unit type, unit number, religions, forced spawn
tMinorCities = (
(-3000, (73, 38), iIndependent, 'Yerushalayim', 2, con.iArcher, 2),	# Jerusalem
(-3000, (79, 40), iIndependent2, 'Shushan', 2, con.iArcher, 1), 	# Susa
(-2000, (85, 47), iIndependent, 'Afrosiyab', 1, con.iArcher, 1), 	# Samarkand
(-2000, (92, 39), iIndependent, 'Varanasi', 1, con.iWarrior, 1), 	# Varanasi
(-2000, (90, 40), iIndependent, 'Indraprastha', 1, con.iWarrior, 1),	# Delhi
(-1000, (102, 47), iIndependent, 'Zhongdu', 2, con.iSpearman, 1),	# Beijing
(-1000, (72, 44), iIndependent, 'Ankuwash', 2, con.iArcher, 2),		# Ankara
(-760, (59, 47), iCeltia, 'Melpum', 2, con.iArcher, 2),			# Milan
(-350, (56, 47), iCeltia, 'Lugodunon', 2, -1, -1),			# Lyon
(-325, (92, 33), iIndependent, 'Kanchipuram', 2, con.iArcher, 1),	# Madras
(-300, (105, 49), iBarbarian, 'Simiyan hoton', 2, con.iChariot, 2),	# Shenyang
(-300, (53, 48), iCeltia, 'Burdigala', 2, -1, -1),			# Bordeaux
(-300, (91, 31), iIndependent, 'Tanjapuri', 1, con.iWarElephant, 1),	# Thanjavur
(-2000, (77, 44), iIndependent2, 'Artashat', 2, con.iArcher, 1),	# Artaxata
(-100, (95, 47), iBarbarian, 'Dunhuang', 2, con.iArcher, 1),		# Dunhuang
(-100, (19, 35), iNative, 'Danni Báa', 2, con.iMayaHolkan, 2),	# Monte Albán
(-75, (89, 46), iBarbarian, 'Kashgar', 2, con.iArcher, 1),		# Kashgar
(-50, (55, 50), iCeltia, 'Lutetia', 2, -1, -1),				# Paris
(100, (76, 30), iIndependent, "Sana'a", 2, -1, -1),			# Sana'a
(107, (98, 36), iIndependent2, 'Pagan', 2, -1, -1),			# Pagan
(633, (96, 43), iBarbarian, 'Rasa', 2, con.iTibetanKhampa, 1),		# Lhasa
(680, (51, 37), iIndependent, 'Marrakus', 1, con.iCrossbowman, 1),	# Marrakesh
(700, (30, 20), iNative, 'Tiwanaku', 1, -1, -1),			# Tihuanaco
(800, con.tVienna, iIndependent, 'Vindobona', 1, con.iLongbowman, 1),	# Wien
(830, (59, 54), iIndependent, 'Hamburg', 2, con.iCrossbowman, 1),	# Hamburg
(830, (60, 54), iIndependent, 'Lübeck', 2, con.iCrossbowman, 1),	# Lübeck
(866, (101, 37), iBarbarian, 'Hanoi', 2, -1, -1),			# Hanoi
(880, (65, 48), iIndependent2, 'Buda', 3, con.iHorseArcher, 5),		# Budapest
(900, (24, 26), iNative, 'Tucume', 1, con.iArcher, 2),			# Tucume
(900, (25, 23), iNative, 'Chan Chan', 2, con.iArcher, 2),		# Chan Chan
(900, (69, 52), iIndependent, 'Kyiv', 2, con.iLongbowman, 2),		# Kiev
(990, (49, 56), iCeltia, 'Áth Cliath', 1, -1, -1),			# Dublin
(1000, (61, 63), iIndependent2, 'Nidaros', 1, con.iVikingBerserker, 1),	# Trondheim
(1000, (71, 17), iNative, 'Quelimane', 1, con.iZuluImpi, 1),		# Quelimane
(1100, (71, 20), iNative, 'Mombasa', 1, con.iZuluImpi, 1),		# Mombasa
(1200, (77, 55), iBarbarian, 'Qazan', 2, con.iHorseArcher, 1),		# Kazan
(1483, (62, 20), iNative, 'Mbanza Kongo', 1, con.iCongoPombos, 1),	# Mbanza Kongoх.
 
Did you change anything at all?
 
You also need to adjust iNumMinorCities in Consts.py.
 
CvRhyes.cpp and Consts.py.
 
I have a number of early buildings built by great prophets in my India mod and I want the AI civs to build them at the earliest opportunity. I have tried increasing "AI_buildingValue" in "CvUnitAI::AI_construct" and I have also tried changing the integer in the "if (AI_construct(1))" statement in "CvUnitAI::AI_prophetMove()", but nothing has really helped.

here are the 2 sections, changes in green:

CvUnitAI::AI_construct
Spoiler :
Code:
// Returns true if a mission was pushed... 
// iMaxCount = 1 would mean construct only if there are no existing buildings 
//   constructed by this GP type.
bool CvUnitAI::AI_construct(int iMaxCount, int iMaxSingleBuildingCount, int iThreshold)
{
	PROFILE_FUNC();

	CvCity* pLoopCity;
	CvPlot* pBestPlot;
	CvPlot* pBestConstructPlot;
	BuildingTypes eBestBuilding;
	int iValue;
	int iBestValue;
	int iLoop;
	int iI;
	int iCount;

	iBestValue = 0;
	pBestPlot = NULL;
	pBestConstructPlot = NULL;
	eBestBuilding = NO_BUILDING;
	iCount = 0;
	
	for (pLoopCity = GET_PLAYER(getOwnerINLINE()).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER(getOwnerINLINE()).nextCity(&iLoop))
	{
		if (AI_plotValid(pLoopCity->plot()) && pLoopCity->area() == area())
		{
			if (!(pLoopCity->plot()->isVisibleEnemyUnit(this)))
			{
				if (GET_PLAYER(getOwnerINLINE()).AI_plotTargetMissionAIs(pLoopCity->plot(), MISSIONAI_CONSTRUCT, getGroup()) == 0)
				{
					if (generatePath(pLoopCity->plot(), 0, true))
					{
						for (iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)
						{
							BuildingTypes eBuilding = (BuildingTypes)GC.getCivilizationInfo(getCivilizationType()).getCivilizationBuildings(iI);

							if (NO_BUILDING != eBuilding)
							{
								bool bDoesBuild = false;
								if ((m_pUnitInfo->getForceBuildings(eBuilding))|| (m_pUnitInfo->getBuildings(eBuilding)))
								{
									bDoesBuild = true;
								}
							
								if (bDoesBuild && (pLoopCity->getNumBuilding(eBuilding) > 0))
								{
									iCount++;
									if (iCount >= iMaxCount)
									{
										return false;
									}
								}
							
								if (bDoesBuild && GET_PLAYER(getOwnerINLINE()).getBuildingClassCount((BuildingClassTypes)GC.getBuildingInfo(eBuilding).getBuildingClassType()) < iMaxSingleBuildingCount)
								{
									if (canConstruct(pLoopCity->plot(), eBuilding))
									{
										//iValue = pLoopCity->AI_buildingValue(eBuilding);
										[COLOR="Green"]iValue = pLoopCity->AI_buildingValue(eBuilding)*5; // srpt encourage epics[/COLOR]

										if ((iValue > iThreshold) && (iValue > iBestValue))
										{
											iBestValue = iValue;
											pBestPlot = getPathEndTurnPlot();
											pBestConstructPlot = pLoopCity->plot();
												eBestBuilding = eBuilding;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}

	if ((pBestPlot != NULL) && (pBestConstructPlot != NULL) && (eBestBuilding != NO_BUILDING))
	{
		if (atPlot(pBestConstructPlot))
		{
			getGroup()->pushMission(MISSION_CONSTRUCT, eBestBuilding);
			return true;
		}
		else
		{
			FAssert(!atPlot(pBestPlot));
			getGroup()->pushMission(MISSION_MOVE_TO, pBestPlot->getX_INLINE(), pBestPlot->getY_INLINE(), 0, false, false, MISSIONAI_CONSTRUCT, pBestConstructPlot);
			return true;
		}
	}

	return false;
}

CvUnitAI::AI_prophetMove
Spoiler :
Code:
void CvUnitAI::AI_prophetMove()
{
	PROFILE_FUNC();

	//if (AI_construct(1))
	[COLOR="Green"]if (AI_construct(8)) // srpt encourage epics[/COLOR]
	{
		return;
	}

	if (AI_discover(true, true))
	{
		return;
	}

	if (AI_construct(3))
	{
		return;
	}
	
	int iGoldenAgeValue = (GET_PLAYER(getOwnerINLINE()).AI_calculateGoldenAgeValue() / (GET_PLAYER(getOwnerINLINE()).unitsRequiredForGoldenAge()));
	int iDiscoverValue = std::max(1, getDiscoverResearch(NO_TECH));

	if (((iGoldenAgeValue * 100) / iDiscoverValue) > 60)
	{
        if (AI_goldenAge())
        {
            return;
        }

        if (iDiscoverValue > iGoldenAgeValue)
        {
            if (AI_discover())
            {
                return;
            }
            if (GET_PLAYER(getOwnerINLINE()).getUnitClassCount(getUnitClassType()) > 1)
            {
                if (AI_join())
                {
                    return;
                }
            }
        }
	}
	else
	{
		if (AI_discover())
		{
			return;
		}

		if (AI_join())
		{
			return;
		}
	}

/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      08/20/09                                jdog5000      */
/*                                                                                              */
/* Unit AI, Efficiency                                                                          */
/************************************************************************************************/
	//if ((GET_PLAYER(getOwnerINLINE()).AI_getPlotDanger(plot(), 2) > 0) ||
	if ((GET_PLAYER(getOwnerINLINE()).AI_getAnyPlotDanger(plot(), 2)) ||
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/
		  (getGameTurnCreated() < (GC.getGameINLINE().getGameTurn() - 25)))
	{
		if (AI_discover())
		{
			return;
		}
	}

	if (AI_retreatToCity())
	{
		return;
	}

	if (AI_safety())
	{
		return;
	}

	getGroup()->pushMission(MISSION_SKIP);
	return;
}
 
Okay, so I'm also bad at these AI routines, but here's what I think.

It looks like there are two reasons why AI_construct() wouldn't result in a building being built:
- there are more than iCount buildings
- for no city any building exceeds the value of iThreshold

Since you tried to adjust iCount with no success, maybe you should take a look at iThreshold. Do your buildings have any effects that the AI can recognize? If not, it's not surprising that they have a value of 0 and get rejected. So, either set iThreshold to a lower value in the method parameter or use the iAIWeight entry to make the AI value the building more.

If that doesn't work, I also suspect a bug in this code if there are multiple buildings associated with one GP unit. Since the iCount variable is global over all buildings without being reset, it's apparently enough if the total sum of building instanced exceeds iCount, instead of their individual count. You might want to investigate and change that. But if there are no buildings associated with that GP type in its civ, it's unlikely the reason for your immediate problem.
 
thanks. I will keep trying.

edit: I replaced the first statement in "CvUnitAI::AI_prophetMove" with "if (AI_construct(MAX_INT, 1))" and now all the buildings are being built

edit2: or maybe not. after building all 4 buildings on the first 4 test runs they built none on the 5th...

and then all 4 on the next. weird.
 
How do I make the getbutton code to use self.lBarbarianList?
Code:
		self.lBarbarianList = [con.iAztecJaguar, con.iCongoPombos, con.iIncanQuechua, con.iSumerianVulture, con.iNativeAmericaDogSoldier, con.iZuluImpi, con.iIroquoisMohawk, con.iNubianMedjay, con.iMayaHolkan, con.iHittiteHuluganni, con.iCarthageNumidianCavalry, con.iKushanAsvaka, con.iTibetanKhampa, con.iMongolKeshik, con.iCamelArcher, con.iMandeFarari, con.iSiouxMountedBrave]
		if self.iCivilization == con.iCivBarbarian:
			screen.attachImageButton(panelName, "", gc.getUnitInfo([B]self.lBarbarianList[/B]).getButton(), GenericButtonSizes.BUTTON_SIZE_CUSTOM, WidgetTypes.WIDGET_PEDIA_JUMP_TO_UNIT, [B]self.lBarbarianList[/B], 1, False)
 
I suppose you want a list with buttons of all units in the list.

Code:
		self.lBarbarianList = [con.iAztecJaguar, con.iCongoPombos, con.iIncanQuechua, con.iSumerianVulture, con.iNativeAmericaDogSoldier, con.iZuluImpi, con.iIroquoisMohawk, con.iNubianMedjay, con.iMayaHolkan, con.iHittiteHuluganni, con.iCarthageNumidianCavalry, con.iKushanAsvaka, con.iTibetanKhampa, con.iMongolKeshik, con.iCamelArcher, con.iMandeFarari, con.iSiouxMountedBrave]
		if self.iCivilization == con.iCivBarbarian:
			[COLOR="Blue"]for iUnit in self.lBarbarianList:[/COLOR]
				screen.attachImageButton(panelName, "", gc.getUnitInfo([COLOR="blue"]iUnit[/COLOR]).getButton(), GenericButtonSizes.BUTTON_SIZE_CUSTOM, WidgetTypes.WIDGET_PEDIA_JUMP_TO_UNIT, [COLOR="Blue"]iUnit[/COLOR], 1, False)
 
You basically have to add them as an entirely new civilization, there's not much of what's there that you can actually use.
 
This is more of a general question, but I can't save anything I move into a new folder (for a mod that I'm working on). It always goes to "save as" and then when I override it, it says that the "path is denied". Has anybody seen this before?
 
Maybe your current user account does not have the privileges to perform that action in this folder?
 
Thanks in advance.

Where can I find the code about obsolesce of monasteries? I scanned XML but it seems not in there.
Additionally, can I use monastery as an UB with ordinary way that applied to other usual buildings? (Yeah I need monastery UB which does not obsolete.)
 
Generic monasteries are in Buildings\SpecialBuildingInfos.xml. This file is unchanged in DoC and therefore not in the mod folder, you have to copy it there if you want to edit it.

All specific monasteries are instances of this generic monastery "special building". A UB can only replace one monastery for a specific religion (unless you create 9 instances of the UB, one for every religion). Not sure how tech obsoletion in building and special building XML interact with each other, but probably the building XML does not override the special building XML.
 
Back
Top Bottom