Modmodding Q&A Thread

Something similar happened to me.

Check the handicap level of your new civ in the scenario files. I forgot to update that and that caused a crash.

(I used "Handicap=HANDICAP_PRINCE" for Sweden, which doesn't exist anymoredue to the new difficulty levels and caused the crash. I updated it to "Handicap=HANDICAP_REGENT" and the problem was solved.)

I checked, and no problem there. Actually I can play some turns properly without any errors then it crashes in sudden. :crazyeye:
 
You mean log folder in Beyond the Sword folder? I cannot remember whether I changed options about them.

There's a file in my log folder and following is its content.

[695422.593] ERR: InitWinApp() failed, exiting
[695422.593] ERR: CIV Init FAILED, exiting
 
You can enable logging in the config file.
Code:
; Enable the logging system
LoggingEnabled = 1

Pythondbg.log and PythonErr2.log contain the logging info you need.
 
If the game crashes without any ingame error message and shows Windows™ error window™, is it the problem of cpp files?
Likely, but not necessarily. Invalid scenario files or missing graphics are also popular reasons.
 
That makes hard to figure out what the problem is, just like congress.py bug. :P

Seems like this will take long time to solve.
 
Nothing inside of PythonErr.log and PythonDbg.log doesn't have any suspicious texts. Huh...

PythonErr2.log is the one you need.
Can you post both PythonErr2 and PythonDbg? Maybe we can find something.
 
There's no PythonErr2.log file in my logs folder. Let me check my configuration.

++ Logging is enabled. Maybe I'm looking wrong folder?
 
That makes hard to figure out what the problem is, just like congress.py bug. :P

Seems like this will take long time to solve.
Welcome to my world.
 
Just for inform, is there any special events on 1852AD? or maybe 1850AD?

And is it possible to play invalid scenario files? I thought that I will not available to run with invalid one, and I could actually play until end of 1850AD.
 
I found that the game crashes with Australia in 1850AD - 600AD scenario and 1852AD - 1700AD scenario. So it seems like not a problem of scenario files.
I tried Brazil play in 1700AD scenario and it goes more than 1850's, 1872AD now and there was no crash here. So I think it is related with Australia it self :crazyeye:
 
From the most recent test, I found that Brazilian game crashed finally in 1888AD. It seems like there's a problem in cpp and dll itself. I cannot see why it crashes without any error message however. I want to ask about is there any possible error log file I can refer? I couldn't find PythonErr2.log file in my "My Games\Beyond the Sword\Logs" folder.
 
Not that I remember.
 
I asked this in the main modding forum but no one answered. do you have any idea what's wrong here?

I'm adding a feature to allow obsolete units to rush construction of their upgrades, using the same xml tags as the Great Engineer. the new code is in CvUnit::canHurry and it works:

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;
}

the mission button displays properly and is greyed-out in the proper cases but I cannot get the text tooltip to follow. here is the code from CvDLLWidgetData::parseActionHelp:

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);
						}
					}
				}
			}

my first problem was using GC.getInfoTypeForString("UNIT_ENGINEER"). it compiled but caused an unidentified C++ exception when the unit was selected.

I tried another version using the "if (pSelectedUnit->canHurry(pMissionPlot, true))" statement as the deciding factor:

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);
					}
				}
			}

but it seemed to answer that "canHurry" call incorrectly:

Spoiler :

the button says no but the text says yes

can anyone help?
 
That's a pretty cool idea.

Before I dive into the code, allow me to completely understand your situation. The button is behaving correctly in this case, right? What is the normal behavior for the tooltip in case something cannot be hurried?
 
Back
Top Bottom