• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

Modmodding Q&A Thread

yes the button correctly says that the archer cannot hurry the barracks, while the tooltip is incorrect.

the normal (vanilla) tooltip simply says "only buildings can be hurried" when hurrying is not possible. the original code only considers the great engineer, whose only restriction is that he can only rush buildings.
 
Okay, so how did you change the canHurry() method? I also can't see any difference in your parseActionHelp() method.
 
here is the canHurry, my changes towards the bottom in red

Spoiler :
Code:
bool CvUnit::canHurry(const CvPlot* pPlot, bool bTestVisible) const
{
	if (isDelayedDeath())
	{
		return false;
	}

	CvCity* pCity;

	if (getHurryProduction(pPlot) == 0)
	{
		return false;
	}

	pCity = pPlot->getPlotCity();

	if (pCity == NULL)
	{
		return false;
	}

	if (pCity->getProductionTurnsLeft() == 1)
	{
		return false;
	}

	if (!bTestVisible)
	{
		if (getUnitType() == GC.getInfoTypeForString("UNIT_ENGINEER"))
		{
			if (!(pCity->isProductionBuilding()))
			{
				return false;
			}
		}
		[COLOR="Red"]// srpt unit retrain[/COLOR]
		else
		{
			if (!(pCity->isProductionUnit()))
			{
				return false;
			}
			UnitTypes eProductionUnit = pCity->getProductionUnit();
			if (eProductionUnit != NULL)
			{
				bool bUpgrade = canUpgrade(eProductionUnit, true);
				if (!(bUpgrade))
				{
					return false;
				}
			}
		}
		[COLOR="Red"]//srpt end[/COLOR]
	}

	return true;
}
and I actually added the "if (getUnitType() == GC.getInfoTypeForString("UNIT_ENGINEER"))" condition as well

and here is parseActionHelp, again changes in red:

Spoiler :
Code:
			else if (GC.getActionInfo(widgetDataStruct.m_iData1).getMissionType() == MISSION_HURRY)
			{
				if (pMissionCity != NULL)
				{
					pSelectedUnitNode = gDLL->getInterfaceIFace()->headSelectionListNode();

					while (pSelectedUnitNode != NULL)
					{
						pSelectedUnit = ::getUnit(pSelectedUnitNode->m_data);

						[COLOR="Red"]if (pSelectedUnit->canHurry(pMissionPlot, true))[/COLOR]
						{
							const wchar* pcKey = NULL;
							if (NO_PROJECT != pMissionCity->getProductionProject())
							{
								pcKey = GC.getProjectInfo(pMissionCity->getProductionProject()).getTextKeyWide();
							}
							else if (NO_BUILDING != pMissionCity->getProductionBuilding())
							{
								pcKey = GC.getBuildingInfo(pMissionCity->getProductionBuilding()).getTextKeyWide();
							}
							else if (NO_UNIT != pMissionCity->getProductionUnit())
							{
								pcKey = GC.getUnitInfo(pMissionCity->getProductionUnit()).getTextKeyWide();
							}
							if (NULL != pcKey && pSelectedUnit->getHurryProduction(pMissionPlot) >= pMissionCity->productionLeft())
							{
								szBuffer.append(NEWLINE);
								szBuffer.append(gDLL->getText("TXT_KEY_ACTION_FINISH_CONSTRUCTION", pcKey));
							}
							[COLOR="Red"]else[/COLOR]
							{
								szBuffer.append(NEWLINE);
								szBuffer.append(gDLL->getText("TXT_KEY_ACTION_EXTRA_CONSTRUCTION", pSelectedUnit->getHurryProduction(pMissionPlot), pcKey));
							}
						}
						else
						{
							szBuffer.append(NEWLINE);
							szBuffer.append(gDLL->getText("TXT_KEY_ACTION_BUILDING_HURRY"));
						}
						break;

						pSelectedUnitNode = gDLL->getInterfaceIFace()->nextSelectionListNode(pSelectedUnitNode);
					}
				}
			}
 
canHurry() looks okay, but your changes in parseActionHelp() are all already in my version of the method.
 
here is the section of parseActionHelp from regular BtS:

Spoiler :
Code:
			else if (GC.getActionInfo(widgetDataStruct.m_iData1).getMissionType() == MISSION_HURRY)
			{
				if (pMissionCity != NULL)
				{
					if (!(pMissionCity->isProductionBuilding()))
					{
						szBuffer.append(NEWLINE);
						szBuffer.append(gDLL->getText("TXT_KEY_ACTION_BUILDING_HURRY"));
					}
					else
					{
						pSelectedUnitNode = gDLL->getInterfaceIFace()->headSelectionListNode();

						while (pSelectedUnitNode != NULL)
						{
							pSelectedUnit = ::getUnit(pSelectedUnitNode->m_data);

							if (pSelectedUnit->canHurry(pMissionPlot, true))
							{
								const wchar* pcKey = NULL;
								if (NO_PROJECT != pMissionCity->getProductionProject())
								{
									pcKey = GC.getProjectInfo(pMissionCity->getProductionProject()).getTextKeyWide();
								}
								else if (NO_BUILDING != pMissionCity->getProductionBuilding())
								{
									pcKey = GC.getBuildingInfo(pMissionCity->getProductionBuilding()).getTextKeyWide();
								}
								else if (NO_UNIT != pMissionCity->getProductionUnit())
								{
									pcKey = GC.getUnitInfo(pMissionCity->getProductionUnit()).getTextKeyWide();
								}
								if (NULL != pcKey && pSelectedUnit->getHurryProduction(pMissionPlot) >= pMissionCity->productionLeft())
								{
									szBuffer.append(NEWLINE);
									szBuffer.append(gDLL->getText("TXT_KEY_ACTION_FINISH_CONSTRUCTION", pcKey));
								}
								else
								{
									szBuffer.append(NEWLINE);
									szBuffer.append(gDLL->getText("TXT_KEY_ACTION_EXTRA_CONSTRUCTION", pSelectedUnit->getHurryProduction(pMissionPlot), pcKey));
								}
								break;
							}

							pSelectedUnitNode = gDLL->getInterfaceIFace()->nextSelectionListNode(pSelectedUnitNode);
						}
					}
				}
			}

it first asks "isBuilding" and says no if its not, the rest asks "canHurry" and decides whether or not the construction will be finished.

my version:

Spoiler :
Code:
			else if (GC.getActionInfo(widgetDataStruct.m_iData1).getMissionType() == MISSION_HURRY)
			{
				if (pMissionCity != NULL)
				{
					pSelectedUnitNode = gDLL->getInterfaceIFace()->headSelectionListNode();

					while (pSelectedUnitNode != NULL)
					{
						pSelectedUnit = ::getUnit(pSelectedUnitNode->m_data);

						if (pSelectedUnit->canHurry(pMissionPlot, true))
						{
							const wchar* pcKey = NULL;
							if (NO_PROJECT != pMissionCity->getProductionProject())
							{
								pcKey = GC.getProjectInfo(pMissionCity->getProductionProject()).getTextKeyWide();
							}
							else if (NO_BUILDING != pMissionCity->getProductionBuilding())
							{
								pcKey = GC.getBuildingInfo(pMissionCity->getProductionBuilding()).getTextKeyWide();
							}
							else if (NO_UNIT != pMissionCity->getProductionUnit())
							{
								pcKey = GC.getUnitInfo(pMissionCity->getProductionUnit()).getTextKeyWide();
							}
							if (NULL != pcKey && pSelectedUnit->getHurryProduction(pMissionPlot) >= pMissionCity->productionLeft())
							{
								szBuffer.append(NEWLINE);
								szBuffer.append(gDLL->getText("TXT_KEY_ACTION_FINISH_CONSTRUCTION", pcKey));
							}
							else
							{
								szBuffer.append(NEWLINE);
								szBuffer.append(gDLL->getText("TXT_KEY_ACTION_EXTRA_CONSTRUCTION", pSelectedUnit->getHurryProduction(pMissionPlot), pcKey));
							}
						}
						[COLOR="Red"]else[/COLOR]
						{
							szBuffer.append(NEWLINE);
							szBuffer.append(gDLL->getText("TXT_KEY_ACTION_BUILDING_HURRY"));
						}
						break;

						pSelectedUnitNode = gDLL->getInterfaceIFace()->nextSelectionListNode(pSelectedUnitNode);
					}
				}
			}
doesn't use the "isBuilding" call but asks the "canHurry" question first

in the case of the archer and the barracks should it not go to the red else statement, canHurry being false?
 
Okay, now I see what you did. Seems my brain cannot function without WinMerge anymore.

Couldn't it be part of the problem that your else clause is within the while loop? Never sure how this works, but your code looks at the first unit on the tile to see whether it can hurry the unit, and in the else block write the text for hurrying buildings. So something happens for the first unit in any case, what if it cannot hurry anything?
 
yeah good point. I will mess around with it when I get home.

edit: I have decent solution. if the parseActionHelp is left simply as this:

Spoiler :
Code:
			else if (GC.getActionInfo(widgetDataStruct.m_iData1).getMissionType() == MISSION_HURRY)
			{
				if (pMissionCity != NULL)
				{
					pSelectedUnitNode = gDLL->getInterfaceIFace()->headSelectionListNode();

					while (pSelectedUnitNode != NULL)
					{
						pSelectedUnit = ::getUnit(pSelectedUnitNode->m_data);

						if (!pSelectedUnit->canHurry(pMissionPlot, true))
						{
							szBuffer.append(NEWLINE);
							szBuffer.append(gDLL->getText("TXT_KEY_ACTION_BUILDING_HURRY"));
						}
						break;

						pSelectedUnitNode = gDLL->getInterfaceIFace()->nextSelectionListNode(pSelectedUnitNode);
					}
				}
			}
it just returns the same text whether the action is good or not, which is how unit upgrades behave, so I think I can live with that.
 
yeah good point. I will mess around with it when I get home.

edit: I have decent solution. if the parseActionHelp is left simply as this:

Spoiler :
Code:
			else if (GC.getActionInfo(widgetDataStruct.m_iData1).getMissionType() == MISSION_HURRY)
			{
				if (pMissionCity != NULL)
				{
					pSelectedUnitNode = gDLL->getInterfaceIFace()->headSelectionListNode();

					while (pSelectedUnitNode != NULL)
					{
						pSelectedUnit = ::getUnit(pSelectedUnitNode->m_data);

						if (!pSelectedUnit->canHurry(pMissionPlot, true))
						{
							szBuffer.append(NEWLINE);
							szBuffer.append(gDLL->getText("TXT_KEY_ACTION_BUILDING_HURRY"));
						}
						break;

						pSelectedUnitNode = gDLL->getInterfaceIFace()->nextSelectionListNode(pSelectedUnitNode);
					}
				}
			}
it just returns the same text whether the action is good or not, which is how unit upgrades behave, so I think I can live with that.
Didn't see this edit, good to know that you found a solution.

Using both art afk file and folder at same time can be a possible reason of crashing?
Not that I know of. The usual behavior is that the FPK overwrites the normal files if it has a more recent timestamp, which is how the Blue Marble module works.
 
How would I remove the tag (Establishes permanent contact with this civilization) that appears when you mouse over the embassy but not when you actually go to the civilopedia page for the embassy?
 
I'm pretty sure that tag is hardcoded into the DLL, search for the text key in CvGameTextManager.cpp and add a condition for the civilopedia, there should be a variable for this.
 
mind explaining what this code do? Latest CNM on York -> Toronto
Code:
city.getRegionID() == con.rCanada
 
There is an underlying region map (look up CvRhyes.cpp). The main use is to define city styles for independents in Varietas Delectat. The code checks whether the city is in the region equivalent to Canada, to differentiate it from the York on Great Britain.
 
I think they are set right at the top of the scenario files in PublicMaps.
 
Hi

I'm trying to add spawns for more independent cities. I just added these under the cities already in barbs.py using the format given there but apparently this doesn't seem to have any effect? :confused:
 
There's a constant in Consts.py like iNumMinorCities or something which you have to increase by one for every city you add.
 
Then no idea what's going wrong without further information.
 
Back
Top Bottom