'initializing' : cannot convert from 'CivicTypes' to 'CivilizationTypes'

Monaldinio

Prince
Joined
Jan 6, 2010
Messages
415
Location
Rostock
Code:
1>CvPlayer.cpp(8943) : error C2440: 'initializing' : cannot convert from 'CivicTypes' to 'CivilizationTypes'
1> Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)
1>NMAKE : warning U4010: 'Release\CvPlayer.obj' : build failed; /K specified, continuing ...

Old

Code:
        CivilizationTypes ePrereq = (CivicTypes)GC.getCivicInfo(eCivic).getPrereqOrCivs(iI);  //Überprüf das mit dem PrereqCivs      #####Fehlerzeile

Better Do in this way???

Code:
CivilizationTypes ePrereq = (CivilizationTypes)GC.getCivicInfo(eCivic).getPrereqOrCivs(iI)
 
The compiler causes an error when the types don't match. This is not because the code can't be compiled, but done by design because 99% of the time mismatching types is a bug. Typecasting is generally viewed as evil as it skips this compiler check and opens for more errors. Vanilla uses typecasting a lot though, and I can easily understand when modders mimic the style from vanilla. After all, what could be wrong in copying working code? :)

The correct solution to this is to edit CvCivic::getPrereqOrCiv to return the correct type. In this case I think it would be (think because you didn't provide the full code)
PHP:
CivilizationTypes getPrereqOrCiv(int iI) const;
You may or may not have to typecast in the get function, but that would be a better place to do it as the code is presumably just returning an int, possibly from an array index. Not only is it only done once instead of once for each caller, it also keeps the typecast away from the long complex lines of code and spotting mistakes will be easier.

Fixing the issue from the get function should allow this line
PHP:
CivilizationTypes ePrereq = GC.getCivicInfo(eCivic).getPrereqOrCivs(iI);
This way, the compiler will cause an error if the function returns something other than CivilizationTypes, which is likely the help you want to get in finding potential bugs.

However if you want to do it simple (and risky), typecasting with (CivilizationTypes) should work, but the compiler will not help you if you typecast to the wrong type. You could in theory end up reading a Unit ID and typecasting it to a CivilizationTypes ID. If there are more units than civs, then you could get an index, which is too high when looking up the civ info, in which case the game crash with a non descriptive error. This is the main reason why I don't like typecasting and avoid it myself if I can get away with it.
 
Okay, the full code...maybe you can see somthing wich could be wrong

CvXMLLoadUtilitySet.cpp

Code:
[COLOR="SeaGreen"]//Versuch
	LoadGlobalClassInfo(GC.getCivicInfo(), "CIV4CivicInfos", "GameInfo", "Civ4CivicInfos/CivicInfos/CivicInfo", true, &CvDLLUtilityIFaceBase::createCivicInfoCacheObject); // Edited for CoC - 2nd pass should also readed in CvInfo.cpp and .h
	//Versuch[/COLOR]
	for (int i=0; i < GC.getNumVoteSourceInfos(); ++i)
	{
		GC.getVoteSourceInfo((VoteSourceTypes)i).readPass3();
	}


CvPlayer.cpp

Code:
bool CvPlayer::canDoCivics(CivicTypes eCivic) const
{
	[COLOR="SeaGreen"]//Versuch
	// bool bFoundPossible;
	bool bFoundValid = false;
	//int iI;
	//Versuch[/COLOR]
	
	PROFILE_FUNC();

/************************************************************************************************/
/* UNOFFICIAL_PATCH                       02/16/10                                jdog5000      */
/*                                                                                              */
/* Bugfix                                                                                       */
/************************************************************************************************/
	// Circumvents second crash bug in simultaneous turns MP games
	if( eCivic == NO_CIVIC )
	{
		return true;
	}
/************************************************************************************************/
/* UNOFFICIAL_PATCH                        END                                                  */
/************************************************************************************************/	

	if (GC.getGameINLINE().isForceCivicOption((CivicOptionTypes)(GC.getCivicInfo(eCivic).getCivicOptionType())))
	{
		return GC.getGameINLINE().isForceCivic(eCivic);
	}

	if(GC.getUSE_CAN_DO_CIVIC_CALLBACK())
	{
		CyArgsList argsList;
		argsList.add(getID());
		argsList.add(eCivic);
		long lResult=0;
		gDLL->getPythonIFace()->callFunction(PYGameModule, "canDoCivic", argsList.makeFunctionArgs(), &lResult);
		if (lResult == 1)
		{
			return true;
		}
	}
	
	// ************************
	// Added for Planetfall
	// ************************
	
	if (GC.getCivicInfo(eCivic).isTranscendence())
	{
		if (isTranscendence())
		{
			return true;
		}
		else if (getPlanetAttitude() < 1 || GC.getGameINLINE().getFloweringCounter() < GC.getTRANSCENDENCE_CIVIC_FC_REQUIREMENT())
		{
			return false;
		}
		if (GET_TEAM(getTeam()).isAVassal())
		{
			return false;
		}
	}
	else if (isTranscendence() && (CivicOptionTypes)(GC.getCivicInfo(eCivic).getCivicOptionType()) == (CivicOptionTypes)GC.getInfoTypeForString(GC.getDefineSTRING("CIVICOPTION_COUNCIL")))
	{
		return false;
	}
	if (GC.getCivilizationInfo(getCivilizationType()).getCivilizationInitialCivics(GC.getCivicInfo(eCivic).getCivicOptionType()) == eCivic)
	{
		return true;
	}
	if (GC.getLeaderHeadInfo(getPersonalityType()).getHatedCivic() == eCivic)
	{
		return false;
	}	
	if (GC.getCivicInfo(eCivic).isTerraformer() && getStateReligion() == (ReligionTypes)3) // Voice of Planet
	{
		return false;
	}
	if (GC.getCivicInfo(eCivic).isHybrid())
	{
		if (getStateReligion() == (ReligionTypes)1) // Edenism
		{
			return false;
		}
	}
	if (GC.getCivicInfo(eCivic).isCouncilMember())
	{
		if (!GC.getGameINLINE().isBuildingClassMaxedOut((BuildingClassTypes)GC.getInfoTypeForString(GC.getDefineSTRING("BUILDINGCLASS_PLANETARY_COUNCIL"))))
		{
			return false;
		}
		if (!isCharter())
		{
			return false;
		}
		for (int iI = 0; iI < GC.getNumVoteSourceInfos(); ++iI)
	    {
	        if (GC.getGameINLINE().isExpelHybrids((VoteSourceTypes)iI))
	        {
				if (isHybrid())
				{
					return false;
				}
	        }
	    }
	}
	
	// ************************
	// End Added For Planetfall
	// ************************
	
	if (!isHasCivicOption((CivicOptionTypes)(GC.getCivicInfo(eCivic).getCivicOptionType())) && !(GET_TEAM(getTeam()).isHasTech((TechTypes)(GC.getCivicInfo(eCivic).getTechPrereq()))))
	{
		return false;
	}

[COLOR="SeaGreen"]	//Versuch
	for (int iI = 0; iI < GC.getNUM_OR_CIVILIZATION_PREREQS(); iI++)//Musst du so anpassen, dass die Schleife alle Einträge erfasst, die in PrereqCivs gelistet werden
	{
		CivilizationTypes ePrereq = (CivilizationTypes)GC.getCivicInfo(eCivic).getPrereqOrCivs(iI);//Überprüf das mit dem PrereqCivs   Better do this [COLOR="Red"]CivilizationTypes getPrereqOrCiv(int iI) const;[/COLOR]
		if (ePrereq != NO_CIVILIZATION)
		{
			
			if ( getCivilizationType() == ePrereq )
			{
				bFoundValid = true;
				break;
			}	
		}
	}

	if (!bFoundValid)
	{
		return false;
	}
	//Versuch[/COLOR]


CyGlobalContext.h

Code:
//////////////////////
	// Globals Defines
	//////////////////////

	CyVariableSystem* getCyDefinesVarSystem();
	int getDefineINT( const char * szName ) const { return GC.getDefineINT( szName ); }
	float getDefineFLOAT( const char * szName ) const { return GC.getDefineFLOAT( szName ); }
	const char * getDefineSTRING( const char * szName ) const { return GC.getDefineSTRING( szName ); }
	void setDefineINT( const char * szName, int iValue ) { return GC.setDefineINT( szName, iValue ); }
	void setDefineFLOAT( const char * szName, float fValue ) { return GC.setDefineFLOAT( szName, fValue ); }
	void setDefineSTRING( const char * szName, const char * szValue ) { return GC.setDefineSTRING( szName, szValue ); }

	int getMOVE_DENOMINATOR() const { return GC.getMOVE_DENOMINATOR(); }
	int getNUM_UNIT_PREREQ_OR_BONUSES() const { return GC.getNUM_UNIT_PREREQ_OR_BONUSES(); }
	int getNUM_BUILDING_PREREQ_OR_BONUSES() const { return GC.getNUM_BUILDING_PREREQ_OR_BONUSES(); }
	int getFOOD_CONSUMPTION_PER_POPULATION() const { return GC.getFOOD_CONSUMPTION_PER_POPULATION(); }
	int getMAX_HIT_POINTS() const { return GC.getMAX_HIT_POINTS(); }
	int getHILLS_EXTRA_DEFENSE() const { return GC.getHILLS_EXTRA_DEFENSE(); }
	int getRIVER_ATTACK_MODIFIER() const { return GC.getRIVER_ATTACK_MODIFIER(); }
	int getAMPHIB_ATTACK_MODIFIER() const { return GC.getAMPHIB_ATTACK_MODIFIER(); }
	int getHILLS_EXTRA_MOVEMENT() const { return GC.getHILLS_EXTRA_MOVEMENT(); }
	int getMAX_PLOT_LIST_ROWS() const { return GC.getMAX_PLOT_LIST_ROWS(); }
	int getUNIT_MULTISELECT_MAX() const { return GC.getUNIT_MULTISELECT_MAX(); }
	int getPERCENT_ANGER_DIVISOR() const { return GC.getPERCENT_ANGER_DIVISOR(); }
	int getEVENT_MESSAGE_TIME() const { return GC.getEVENT_MESSAGE_TIME(); }
	int getROUTE_FEATURE_GROWTH_MODIFIER() const { return GC.getROUTE_FEATURE_GROWTH_MODIFIER(); }
	int getFEATURE_GROWTH_MODIFIER() const { return GC.getFEATURE_GROWTH_MODIFIER(); }
	int getMIN_CITY_RANGE() const { return GC.getMIN_CITY_RANGE(); }
	int getCITY_MAX_NUM_BUILDINGS() const { return GC.getCITY_MAX_NUM_BUILDINGS(); }
	int getNUM_UNIT_AND_TECH_PREREQS() const { return GC.getNUM_UNIT_AND_TECH_PREREQS(); }
	int getNUM_AND_TECH_PREREQS() const { return GC.getNUM_AND_TECH_PREREQS(); }
	int getNUM_OR_TECH_PREREQS() const { return GC.getNUM_OR_TECH_PREREQS(); }
[COLOR="SeaGreen"]	//Versuch
	int getNUM_OR_CIVILIZATION_PREREQS() const { return GC.getNUM_OR_CIVILIZATION_PREREQS(); }
	//Versuch[/COLOR]


CvGlobals.cpp

Code:
CvGlobals gGlobals;

//
// CONSTRUCTOR
//
CvGlobals::CvGlobals() :
m_bGraphicsInitialized(false),
m_bLogging(false),
m_bRandLogging(false),
m_bOverwriteLogs(false),
m_bSynchLogging(false),
m_bDLLProfiler(false),
m_pkMainMenu(NULL),
m_iNewPlayers(0),
m_bZoomOut(false),
m_bZoomIn(false),
m_bLoadGameFromFile(false),
m_pFMPMgr(NULL),
m_asyncRand(NULL),
m_interface(NULL),
m_game(NULL),
m_messageQueue(NULL),
m_hotJoinMsgQueue(NULL),
m_messageControl(NULL),
m_messageCodes(NULL),
m_dropMgr(NULL),
m_portal(NULL),
m_setupData(NULL),
m_initCore(NULL),
m_statsReporter(NULL),
m_map(NULL),
m_diplomacyScreen(NULL),
m_mpDiplomacyScreen(NULL),
m_pathFinder(NULL),
m_interfacePathFinder(NULL),
m_stepFinder(NULL),
m_routeFinder(NULL),
m_borderFinder(NULL),
m_areaFinder(NULL),
m_plotGroupFinder(NULL),
m_pDLL(NULL),
m_aiPlotDirectionX(NULL),
m_aiPlotDirectionY(NULL),
m_aiPlotCardinalDirectionX(NULL),
m_aiPlotCardinalDirectionY(NULL),
m_aiCityPlotX(NULL),
m_aiCityPlotY(NULL),
m_aiCityPlotPriority(NULL),
m_aeTurnLeftDirection(NULL),
m_aeTurnRightDirection(NULL),
//m_aGameOptionsInfo(NULL),
//m_aPlayerOptionsInfo(NULL),
m_Profiler(NULL),
m_VarSystem(NULL),
m_iMOVE_DENOMINATOR(0),
m_iNUM_UNIT_PREREQ_OR_BONUSES(0),
m_iNUM_BUILDING_PREREQ_OR_BONUSES(0),
m_iFOOD_CONSUMPTION_PER_POPULATION(0),
m_iMAX_HIT_POINTS(0),
m_iPATH_DAMAGE_WEIGHT(0),
m_iHILLS_EXTRA_DEFENSE(0),
m_iRIVER_ATTACK_MODIFIER(0),
m_iAMPHIB_ATTACK_MODIFIER(0),
m_iHILLS_EXTRA_MOVEMENT(0),
m_iMAX_PLOT_LIST_ROWS(0),
m_iUNIT_MULTISELECT_MAX(0),
m_iPERCENT_ANGER_DIVISOR(0),
m_iEVENT_MESSAGE_TIME(0),
m_iROUTE_FEATURE_GROWTH_MODIFIER(0),
m_iFEATURE_GROWTH_MODIFIER(0),
m_iMIN_CITY_RANGE(0),
m_iCITY_MAX_NUM_BUILDINGS(0),
m_iNUM_UNIT_AND_TECH_PREREQS(0),
m_iNUM_AND_TECH_PREREQS(0),
m_iNUM_OR_TECH_PREREQS(0),
[COLOR="SeaGreen"]//Versuch
m_iNUM_OR_CIVILIZATION_PREREQS(0),
//Versuch[/COLOR]


CvGlobals.h

Code:
	///////////////// BEGIN global defines
	// THESE ARE READ-ONLY
	//

	DllExport FVariableSystem* getDefinesVarSystem();
	DllExport void cacheGlobals();

	// ***** EXPOSED TO PYTHON *****
	DllExport int getDefineINT( const char * szName ) const;
	DllExport float getDefineFLOAT( const char * szName ) const;
	DllExport const char * getDefineSTRING( const char * szName ) const;
	DllExport void setDefineINT( const char * szName, int iValue );
	DllExport void setDefineFLOAT( const char * szName, float fValue );
	DllExport void setDefineSTRING( const char * szName, const char * szValue );

	int getMOVE_DENOMINATOR();
	int getNUM_UNIT_PREREQ_OR_BONUSES();
	int getNUM_BUILDING_PREREQ_OR_BONUSES();
	int getFOOD_CONSUMPTION_PER_POPULATION();
	int getMAX_HIT_POINTS();
	int getPATH_DAMAGE_WEIGHT();
	int getHILLS_EXTRA_DEFENSE();
	int getRIVER_ATTACK_MODIFIER();
	int getAMPHIB_ATTACK_MODIFIER();
	int getHILLS_EXTRA_MOVEMENT();
	DllExport int getMAX_PLOT_LIST_ROWS();
	DllExport int getUNIT_MULTISELECT_MAX();
	int getPERCENT_ANGER_DIVISOR();
	DllExport int getEVENT_MESSAGE_TIME();
	int getROUTE_FEATURE_GROWTH_MODIFIER();
	int getFEATURE_GROWTH_MODIFIER();
	int getMIN_CITY_RANGE();
	int getCITY_MAX_NUM_BUILDINGS();
	int getNUM_UNIT_AND_TECH_PREREQS();
	int getNUM_AND_TECH_PREREQS();
	int getNUM_OR_TECH_PREREQS();
	[COLOR="SeaGreen"]//Versuch
	int getNUM_OR_CIVILIZATION_PREREQS();
	//Versuch[/COLOR]


Code:
//////////////////////////////////////////////////////////////////////////
	// Formerly Global Defines
	//////////////////////////////////////////////////////////////////////////

	FVariableSystem* m_VarSystem;

	int m_iMOVE_DENOMINATOR;
	int m_iNUM_UNIT_PREREQ_OR_BONUSES;
	int m_iNUM_BUILDING_PREREQ_OR_BONUSES;
	int m_iFOOD_CONSUMPTION_PER_POPULATION;
	int m_iMAX_HIT_POINTS;
	int m_iPATH_DAMAGE_WEIGHT;
	int m_iHILLS_EXTRA_DEFENSE;
	int m_iRIVER_ATTACK_MODIFIER;
	int m_iAMPHIB_ATTACK_MODIFIER;
	int m_iHILLS_EXTRA_MOVEMENT;
	int m_iMAX_PLOT_LIST_ROWS;
	int m_iUNIT_MULTISELECT_MAX;
	int m_iPERCENT_ANGER_DIVISOR;
	int m_iEVENT_MESSAGE_TIME;
	int m_iROUTE_FEATURE_GROWTH_MODIFIER;
	int m_iFEATURE_GROWTH_MODIFIER;
	int m_iMIN_CITY_RANGE;
	int m_iCITY_MAX_NUM_BUILDINGS;
	int m_iNUM_UNIT_AND_TECH_PREREQS;
	int m_iNUM_AND_TECH_PREREQS;
	int m_iNUM_OR_TECH_PREREQS;
	[COLOR="SeaGreen"]//Versuch
	int m_iNUM_OR_CIVILIZATION_PREREQS;
	//Versuch[/COLOR]


CvInfos.cpp

Code:
//======================================================================================================
//					CvCivicInfo
//======================================================================================================

//------------------------------------------------------------------------------------------------------
//
//  FUNCTION:   CvCivicInfo()
//
//  PURPOSE :   Default constructor
//
//------------------------------------------------------------------------------------------------------
CvCivicInfo::CvCivicInfo() :
m_iCivicOptionType(NO_CIVICOPTION),
//Versuch
//m_iCivPrereq(NO_CIVILIZATION),
//Versuch
m_iAnarchyLength(0),
m_iUpkeep(0),
m_iAIWeight(0),
m_iGreatPeopleRateModifier(0),
m_iGreatGeneralRateModifier(0),
m_iDomesticGreatGeneralRateModifier(0),
m_iStateReligionGreatPeopleRateModifier(0),
m_iDistanceMaintenanceModifier(0),
m_iNumCitiesMaintenanceModifier(0),
m_iCorporationMaintenanceModifier(0),
m_iExtraHealth(0),
m_iFreeExperience(0),
m_iWorkerSpeedModifier(0),
m_iImprovementUpgradeRateModifier(0),
m_iMilitaryProductionModifier(0),
m_iBaseFreeUnits(0),
m_iBaseFreeMilitaryUnits(0),
m_iFreeUnitsPopulationPercent(0),
m_iFreeMilitaryUnitsPopulationPercent(0),
m_iGoldPerUnit(0),
m_iGoldPerMilitaryUnit(0),
m_iHappyPerMilitaryUnit(0),
m_iLargestCityHappiness(0),
m_iWarWearinessModifier(0),
m_iFreeSpecialist(0),
m_iTradeRoutes(0),
m_iTechPrereq(NO_TECH),
m_iCivicPercentAnger(0),
m_iMaxConscript(0),
m_iStateReligionHappiness(0),
m_iNonStateReligionHappiness(0),
m_iStateReligionUnitProductionModifier(0),
m_iStateReligionBuildingProductionModifier(0),
m_iStateReligionFreeExperience(0),
m_iExpInBorderModifier(0),
m_bMilitaryFoodProduction(false),
m_bNoUnhealthyPopulation(false),
m_bBuildingOnlyHealthy(false),
m_bNoForeignTrade(false),
m_bNoCorporations(false),
m_bNoForeignCorporations(false),
m_bStateReligion(false),
m_bNoNonStateReligionSpread(false),
m_piYieldModifier(NULL),
m_piCapitalYieldModifier(NULL),
m_piTradeYieldModifier(NULL),
m_piCommerceModifier(NULL),
m_piCapitalCommerceModifier(NULL),
m_piSpecialistExtraCommerce(NULL),
[COLOR="SeaGreen"]//Versuch 
m_piPrereqOrCivs(NULL),
//Versuch[/COLOR]

Code:
//------------------------------------------------------------------------------------------------------
//
//  FUNCTION:   ~CvCivicInfo()
//
//  PURPOSE :   Default destructor
//
//------------------------------------------------------------------------------------------------------
CvCivicInfo::~CvCivicInfo()
{
	int iI;

	SAFE_DELETE_ARRAY(m_piYieldModifier);
	SAFE_DELETE_ARRAY(m_piCapitalYieldModifier);
	SAFE_DELETE_ARRAY(m_piTradeYieldModifier);
	SAFE_DELETE_ARRAY(m_piCommerceModifier);
	SAFE_DELETE_ARRAY(m_piCapitalCommerceModifier);
	SAFE_DELETE_ARRAY(m_piSpecialistExtraCommerce);
	[COLOR="SeaGreen"]//Versuch
	SAFE_DELETE_ARRAY(m_piPrereqOrCivs);
	//Versuch[/COLOR]

Code:
// Arrays

int CvCivicInfo::getYieldModifier(int i) const
{
	FAssertMsg(i < NUM_YIELD_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piYieldModifier ? m_piYieldModifier[i] : -1;
}

int* CvCivicInfo::getYieldModifierArray() const
{
	return m_piYieldModifier;
}

int CvCivicInfo::getCapitalYieldModifier(int i) const
{
	FAssertMsg(i < NUM_YIELD_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piCapitalYieldModifier ? m_piCapitalYieldModifier[i] : -1;
}

int* CvCivicInfo::getCapitalYieldModifierArray() const
{
	return m_piCapitalYieldModifier;
}

int CvCivicInfo::getTradeYieldModifier(int i) const
{
	FAssertMsg(i < NUM_YIELD_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piTradeYieldModifier ? m_piTradeYieldModifier[i] : -1;
}

int* CvCivicInfo::getTradeYieldModifierArray() const
{
	return m_piTradeYieldModifier;
}

int CvCivicInfo::getCommerceModifier(int i) const
{
	FAssertMsg(i < NUM_COMMERCE_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piCommerceModifier ? m_piCommerceModifier[i] : -1;
}

int* CvCivicInfo::getCommerceModifierArray() const
{
	return m_piCommerceModifier;
}

int CvCivicInfo::getCapitalCommerceModifier(int i) const
{
	FAssertMsg(i < NUM_COMMERCE_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piCapitalCommerceModifier ? m_piCapitalCommerceModifier[i] : -1;
}

int* CvCivicInfo::getCapitalCommerceModifierArray() const
{
	return m_piCapitalCommerceModifier;
}

int CvCivicInfo::getSpecialistExtraCommerce(int i) const
{
	FAssertMsg(i < NUM_COMMERCE_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piSpecialistExtraCommerce ? m_piSpecialistExtraCommerce[i] : -1;
}

[COLOR="SeaGreen"]//Versuch
int CvCivicInfo::getPrereqOrCivs(int i) const
{
	return m_piPrereqOrCivs ? m_piPrereqOrCivs[i] : -1;
}
//Versuch[/COLOR]

Code:
// Arrays

	SAFE_DELETE_ARRAY(m_piYieldModifier);
	m_piYieldModifier = new int[NUM_YIELD_TYPES];
	stream->Read(NUM_YIELD_TYPES, m_piYieldModifier);

	SAFE_DELETE_ARRAY(m_piCapitalYieldModifier);
	m_piCapitalYieldModifier = new int[NUM_YIELD_TYPES];
	stream->Read(NUM_YIELD_TYPES, m_piCapitalYieldModifier);

	SAFE_DELETE_ARRAY(m_piTradeYieldModifier);
	m_piTradeYieldModifier = new int[NUM_YIELD_TYPES];
	stream->Read(NUM_YIELD_TYPES, m_piTradeYieldModifier);

	SAFE_DELETE_ARRAY(m_piCommerceModifier);
	m_piCommerceModifier = new int[NUM_COMMERCE_TYPES];
	stream->Read(NUM_COMMERCE_TYPES, m_piCommerceModifier);

	SAFE_DELETE_ARRAY(m_piCapitalCommerceModifier);
	m_piCapitalCommerceModifier = new int[NUM_COMMERCE_TYPES];
	stream->Read(NUM_COMMERCE_TYPES, m_piCapitalCommerceModifier);

	SAFE_DELETE_ARRAY(m_piSpecialistExtraCommerce);
	m_piSpecialistExtraCommerce = new int[NUM_COMMERCE_TYPES];
	stream->Read(NUM_COMMERCE_TYPES, m_piSpecialistExtraCommerce);

[COLOR="SeaGreen"]	//Versuch
	SAFE_DELETE_ARRAY(m_piPrereqOrCivs);
	m_piPrereqOrCivs = new int[GC.getNUM_OR_CIVILIZATION_PREREQS()];
	stream->Read(GC.getNUM_OR_CIVILIZATION_PREREQS(), m_piPrereqOrCivs);
	//Versuch[/COLOR]

Code:
// Arrays

	stream->Write(NUM_YIELD_TYPES, m_piYieldModifier);
	stream->Write(NUM_YIELD_TYPES, m_piCapitalYieldModifier);
	stream->Write(NUM_YIELD_TYPES, m_piTradeYieldModifier);
	stream->Write(NUM_COMMERCE_TYPES, m_piCommerceModifier);
	stream->Write(NUM_COMMERCE_TYPES, m_piCapitalCommerceModifier);
	stream->Write(NUM_COMMERCE_TYPES, m_piSpecialistExtraCommerce);
	[COLOR="SeaGreen"]//Versuch
	stream->Write(GC.getNUM_OR_CIVILIZATION_PREREQS(), m_piPrereqOrCivs);
	//Verssuch[/COLOR]


Code:
[COLOR="SeaGreen"]//Versuch

bool CvCivicInfo::readPass2(CvXMLLoadUtility* pXML)
{
	CvString szTextVal;

	if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"OrPreReqs"))
	{
		if (pXML->SkipToNextVal())
		{
			int iMaxCivs = GC.getNUM_OR_CIVILIZATION_PREREQS();
			int iCiv = 0;
			FAssertMsg((0 < iMaxCivs) ,"Allocating zero or less memory CvCivicInfo::readpass2 / OrPreReqs");
			pXML->InitList(&m_piPrereqOrCivs, iMaxCivs, -1);

			// Read the entries
			if ( gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(), "PrereqCiv" ) )
			{
				do
				{
					FAssertMsg((iMaxCivs > iCiv) ,"There are more siblings than memory allocated for them - CvCivicInfo::readpass2 / OrPreReqs");
					if (iCiv < iMaxCivs)
					{
						pXML->GetChildXmlValByName(szTextVal, "PrereqCivType");
						m_piPrereqOrCivs[iCiv++] = GC.getInfoTypeForString(szTextVal);
					}

				}
				while ( gDLL->getXMLIFace()->LocateNextSiblingNodeByTagName(pXML->GetXML(), "PrereqCiv"));
				gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
			}

		}
		gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
	}

	return true;
}
//Versuch[/COLOR]


CvInfo.h



Code:
// Arrays

	int getYieldModifier(int i) const;				// Exposed to Python
	int* getYieldModifierArray() const;
	int getCapitalYieldModifier(int i) const;				// Exposed to Python
	int* getCapitalYieldModifierArray() const;
	int getTradeYieldModifier(int i) const;				// Exposed to Python
	int* getTradeYieldModifierArray() const;
	int getCommerceModifier(int i) const;				// Exposed to Python
	int* getCommerceModifierArray() const;
	int getCapitalCommerceModifier(int i) const;				// Exposed to Python
	int* getCapitalCommerceModifierArray() const;
	int getSpecialistExtraCommerce(int i) const;				// Exposed to Python
	int* getSpecialistExtraCommerceArray() const;
	[COLOR="SeaGreen"]//Versuch
	int getPrereqOrCivs(int i) const;		// Exposed to Python
	//Versuch[/COLOR]
	int getBuildingHappinessChanges(int i) const;				// Exposed to Python
	int getBuildingHealthChanges(int i) const;				// Exposed to Python
	int getFeatureHappinessChanges(int i) const;				// Exposed to Python

	bool isHurry(int i) const;													// Exposed to Python
	bool isSpecialBuildingNotRequired(int i) const;			// Exposed to Python
	bool isSpecialistValid(int i) const;								// Exposed to Python

	int getImprovementYieldChanges(int i, int j) const;				// Exposed to Python

	void read(FDataStreamBase* stream);
	void write(FDataStreamBase* stream);

	bool read(CvXMLLoadUtility* pXML);
	[COLOR="SeaGreen"]//Versuch
	bool readPass2(CvXMLLoadUtility* pXML);
	//Versuch[/COLOR]


Maybe the readpass2 will not be readed...
My intention was to copy the prereqOrTech tag and past it to the CivicInfos to add a prereq Civ for a civic...
After all it dont work. I had no compiling errors...it only dont work as it should.
 
CvXMLLoadUtilitySet.cpp
Code:
LoadGlobalClassInfo(GC.getCivicInfo(), "CIV4CivicInfos", "GameInfo", "Civ4CivicInfos/CivicInfos/CivicInfo", [B]false[/B], &CvDLLUtilityIFaceBase::createCivicInfoCacheObject);
The bold bool tells if the game should use readPass2. Change it to true and see if that solves the problem.

readPass2 is automatically called in Colonization without any additional setup other than adding the function. One of the small, yet important differences to the otherwise nearly identical code.
 
It is on true as you can see.


Code:
Code:
//Versuch
	LoadGlobalClassInfo(GC.getCivicInfo(), "CIV4CivicInfos", "GameInfo", "Civ4CivicInfos/CivicInfos/CivicInfo", true, &CvDLLUtilityIFaceBase::createCivicInfoCacheObject); // Edited for CoC - 2nd pass should also readed in CvInfo.cpp and .h
	//Versuch
	for (int i=0; i < GC.getNumVoteSourceInfos(); ++i)
	{
		GC.getVoteSourceInfo((VoteSourceTypes)i).readPass3();
	}
 
I spotted an issue.

In CvCivicInfo::read(CvXMLLoadUtility* pXML), pXML points to the correct civic in the file. However in CvCivicInfo::readPass2(CvXMLLoadUtility* pXML), pXML points to the last, or perhaps even the civic after the last. In other words, you can't actually use pXML to read data from the xml file in readPass2 or readPass3 for that matter.

The issue here is that you don't know the strings for CivilizationTypes until some time after you have read CivicInfo. In fact you still don't know them when you reach readPass2. readPass3 is made for this purpose, though I will propose something else.

I have completely redesigned XML reading in Medieval Conquest and Fallout: Tame The Waste. In this redesign, each XML file is read twice. The first time reads the basic info, like types. The second time is the standard vanilla read. This two step process ensures that order issues like this one vanishes completely and order only matters if something other than type is needed. My plan is to make a generic package people can drag-n-drop into mods, but it will take a while before that can be used (especially since I'm not working on it at the moment).

However this doesn't mean the core idea can't be used here. Read the civilization types before reading civics and the problem is solved. To do this, do the following:

CvInfos.cpp:
Code:
[B]extern bool bGlobalFirstRead;[/B]

bool CvCivicInfo::read(CvXMLLoadUtility* pXML)
{
	CvString szTextVal;
	if (!CvInfoBase::read(pXML))
	{
		return false;
	}

	[B]if (bGlobalFirstRead)
	{
		return true;
	}[/B]

In CvXMLLoadUtilitySet.cpp
Code:
[B]bool bGlobalFirstRead;[/B]

bool CvXMLLoadUtility::LoadPreMenuGlobals()
{
	if (!CreateFXml())
	{
		return false;
	}

	[B]bGlobalFirstRead = true;[/B]
	[B]LoadGlobalClassInfo(GC.getCivilizationInfo(), "CIV4CivilizationInfos", "Civilizations", "Civ4CivilizationInfos/CivilizationInfos/CivilizationInfo", false);[/B]
	[B]bGlobalFirstRead = false;[/B]
Civ info and civics are both read later in LoadPreMenuGlobals. However with bGlobalFirstRead set to true, the types will be read and CivicInfo::read can use them when reading the array without any issues and without using anything like readPass2.

It should be noted that extern makes the bool a global variable and this is generally considered ugly coding. Most warnings about it usually relates to threaded applications and XML reading is done single threaded. Still you may want to place it in CvGlobals or something.

This approach can be used on other files as well. The only thing, which goes bad is if Type is empty (like in hints). If used on hints, it will read the hints and then read the hints and add those to the end instead of overwriting the already read hints, in which case each hint is added twice. If the file uses Type, then reading a type, which is already read will force the game to overwrite that index instead of creating a new one.

I hope this solves the problem. I really don't like the xml read order issues because they quickly turn nasty, hence the reason why I redesigned the code to begin with.
 
...i dont change nothing at the code in post #4, only add yours from post #7...after that i get an xml loading error.:(
Are you sure you disabled the XML cache? Also what is the error?

Error or not, readPass2 is used before civ types are read, which will cause your code to fail. The question is how to fix it without causing a new problem, not if it is a problem to begin with.
 
I could Post the XML loading errors later, im at work now..;(
I always disabled cache.

I have also tried to copy this Code

Code:
//Versuch

	if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"OrPreReqs"))
	{
		if (pXML->SkipToNextVal())
		{
			int iMaxCivs = GC.getNUM_OR_CIVILIZATION_PREREQS();
			int iCiv = 0;
			FAssertMsg((0 < iMaxCivs) ,"Allocating zero or less memory CvCivicInfo::readpass2 / OrPreReqs");
			pXML->InitList(&m_piPrereqOrCivs, iMaxCivs, -1);

			// Read the entries
			if ( gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(), "PrereqCiv" ) )
			{
				do
				{
					FAssertMsg((iMaxCivs > iCiv) ,"There are more siblings than memory allocated for them - CvCivicInfo::readpass2 / OrPreReqs");
					if (iCiv < iMaxCivs)
					{
						pXML->GetChildXmlValByName(szTextVal, "PrereqCivType");
						m_piPrereqOrCivs[iCiv++] = GC.getInfoTypeForString(szTextVal);
					}

				}
				while ( gDLL->getXMLIFace()->LocateNextSiblingNodeByTagName(pXML->GetXML(), "PrereqCiv"));
				gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
			}

		}
		gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
	}

	return true;
}
//Versuch

under the normal readpass methode at the Last Position.
I delated the readpass2 Part in the CvInfo.h
and also your codepart from post #7.

No Problems with compiling or loading...
But it dont work as it should be...
The normal Civs dont be able to choose the unique Civic of the Aliens Civs, thats Works fine.
But the 2 Alien Civs can't choose they unique Civic as well.
Its the same Code wich i have posted in #4
 
Do you have the code on a git or svn server somewhere? I think it would be way faster if I just download it and start in a debugger. I think that would give me the answer within a few minutes and not all thing thinking and forum writing.

If not, then consider starting such a server. It's highly recommended because it allows you to go back to before you screwed up something or point to a single change and revert it.
 
Thanks for your help Nightinggale!!! Thank you for investing so much time for answering. :thumbsup:
I have solved the problem in a different way, I took the TerrainMakesValid Tag as a reference .
And now it works like it should!
I will do the same for the Religions, so i have unique Civics and Religions.
Okay, maybe it is not so special like Asaf's work, but his modcomponent change a little bit too much for my mod.
I dont like the "replace" thing...


But I would be very happy if you could look again at the asteroid problem .
That is the last thing on my Agenda. I uploaded my last version on my Dropbox .
I 've sent you the link via PM .
 
Back
Top Bottom