Update/change Specialist Health value by civic

OrionVeteran

Deity
Joined
Dec 25, 2003
Messages
2,443
Location
Newport News VA
I have been attempting to add the default Specialist Health value (3), with the Specialist Doctor extra Health by Civic value via SDK. The array for Specialist Doctor extra Health values all work and show the correct values for each civic. In a test failure I wanted to add one additional health value to the default specialist doctor, which comes from the civic despotism. All SDK functions compile but failed to update/change the the specialist health to 4. Can anyone help with making a function that would perform the update by civic? See attached pictures. I know. Nothing that I ask for help on is easy any more. Only the more difficult SDK work is left to do. Many thanks in advanced...
 

Attachments

  • DespotismSpecialistDoctorHealthChange.jpg
    DespotismSpecialistDoctorHealthChange.jpg
    40.5 KB · Views: 160
  • SpecialistDoctorDefault.jpg
    SpecialistDoctorDefault.jpg
    62 KB · Views: 167
  • SpecialistDoctorHealthbyCivic.jpg
    SpecialistDoctorHealthbyCivic.jpg
    126.1 KB · Views: 211
I have more details:

CIV4SpecialistInfos.xml
Spoiler :

Code:
<SpecialistInfo>
	<Type>SPECIALIST_DOCTOR</Type>
	<Description>TXT_KEY_UNIT_DOCTOR</Description>
	<Civilopedia>TXT_KEY_CONCEPT_SPECIALISTS_PEDIA</Civilopedia>
	<Strategy>TXT_KEY_SPECIALIST_DOCTOR_STRATEGY</Strategy>
	<Help/>
	<Texture>Art/Interface/MainScreen/CityScreen/Doctor.dds</Texture>
	<bVisible>1</bVisible>
	<GreatPeopleUnitClass>UNITCLASS_DOCTOR</GreatPeopleUnitClass>
	<iGreatPeopleRateChange>3</iGreatPeopleRateChange>
	<Yields/>
	<Commerces>
		<iCommerce>0</iCommerce>
		<iCommerce>1</iCommerce>
		<iCommerce>0</iCommerce>
		<iCommerce>0</iCommerce>
	</Commerces>
	[COLOR="Red"]<iHealth>3</iHealth>[/COLOR]
	<iHappiness>0</iHappiness>
	<iExperience>0</iExperience>
	<Flavors>
		<Flavor>
			<FlavorType>FLAVOR_GROWTH</FlavorType>
			<iFlavor>1</iFlavor>
		</Flavor>
	</Flavors>
	<HotKey/>
	<bAltDown>0</bAltDown>
	<bShiftDown>0</bShiftDown>
	<bCtrlDown>0</bCtrlDown>
	<iHotKeyPriority>0</iHotKeyPriority>
	<Button>Art/Interface/MainScreen/CityScreen/Doctor.dds</Button>
</SpecialistInfo>


CIV4CivicInfos.xml
Spoiler :

Code:
<CivicInfo>
	<CivicOptionType>CIVICOPTION_GOVERNMENT</CivicOptionType>
	<Type>CIVIC_DESPOTISM</Type>
	<Description>TXT_KEY_CIVIC_DESPOTISM</Description>
	<Civilopedia>TXT_KEY_CIVIC_DESPOTISM_PEDIA</Civilopedia>
	<Strategy>TXT_KEY_CIVIC_DESPOTISM_STRATEGY</Strategy>
	<Button>,Art/Interface/Buttons/Civics/Despotism.dds,Art/Interface/Buttons/Civics_Civilizations_Religions_Atlas.dds,5,1</Button>
	<TechPrereq>TECH_LANGUAGE</TechPrereq>
	<iAnarchyLength>1</iAnarchyLength>
	<Upkeep>UPKEEP_LOW</Upkeep>
	<iAIWeight>0</iAIWeight>
	<iGreatPeopleRateModifier>0</iGreatPeopleRateModifier>
	<iGreatGeneralRateModifier>0</iGreatGeneralRateModifier>
	<iDomesticGreatGeneralRateModifier>0</iDomesticGreatGeneralRateModifier>
	<iStateReligionGreatPeopleRateModifier>0</iStateReligionGreatPeopleRateModifier>
	<iDistanceMaintenanceModifier>25</iDistanceMaintenanceModifier>
	<iNumCitiesMaintenanceModifier>0</iNumCitiesMaintenanceModifier>
	<iCorporationMaintenanceModifier>0</iCorporationMaintenanceModifier>
	<iExtraHealth>0</iExtraHealth>
	<iFreeExperience>0</iFreeExperience>
	<iWorkerSpeedModifier>0</iWorkerSpeedModifier>
	<iImprovementUpgradeRateModifier>0</iImprovementUpgradeRateModifier>
	<iMilitaryProductionModifier>25</iMilitaryProductionModifier>
	<iBaseFreeUnits>0</iBaseFreeUnits>
	<iBaseFreeMilitaryUnits>0</iBaseFreeMilitaryUnits>
	<iFreeUnitsPopulationPercent>0</iFreeUnitsPopulationPercent>
	<iFreeMilitaryUnitsPopulationPercent>0</iFreeMilitaryUnitsPopulationPercent>
	<iGoldPerUnit>0</iGoldPerUnit>
	<iGoldPerMilitaryUnit>0</iGoldPerMilitaryUnit>
	<iHappyPerMilitaryUnit>0</iHappyPerMilitaryUnit>
	<bMilitaryFoodProduction>0</bMilitaryFoodProduction>
	<iMaxConscript>2</iMaxConscript>
	<bNoUnhealthyPopulation>0</bNoUnhealthyPopulation>
	<iExpInBorderModifier>0</iExpInBorderModifier>
	<bBuildingOnlyHealthy>0</bBuildingOnlyHealthy>
	<iLargestCityHappiness>0</iLargestCityHappiness>
	<iWarWearinessModifier>-25</iWarWearinessModifier>
	<iFreeSpecialist>0</iFreeSpecialist>
	<iTradeRoutes>0</iTradeRoutes>
	<bNoForeignTrade>1</bNoForeignTrade>
	<bNoCorporations>0</bNoCorporations>
	<bNoForeignCorporations>0</bNoForeignCorporations>
	<iCivicPercentAnger>0</iCivicPercentAnger>
	<bStateReligion>0</bStateReligion>
	<bNoNonStateReligionSpread>0</bNoNonStateReligionSpread>
	<iStateReligionHappiness>0</iStateReligionHappiness>
	<iNonStateReligionHappiness>0</iNonStateReligionHappiness>
	<iStateReligionUnitProductionModifier>0</iStateReligionUnitProductionModifier>
	<iStateReligionBuildingProductionModifier>0</iStateReligionBuildingProductionModifier>
	<iStateReligionFreeExperience>0</iStateReligionFreeExperience>
	<YieldModifiers/>
	<CapitalYieldModifiers/>
	<TradeYieldModifiers/>
	<CommerceModifiers>
		<iCommerce>0</iCommerce> <!-- Gold -->
		<iCommerce>-10</iCommerce><!-- Research -->
		<iCommerce>-3</iCommerce> <!-- Culture -->
		<iCommerce>0</iCommerce> <!-- Espionage -->
	</CommerceModifiers>
	<CapitalCommerceModifiers/>
	<SpecialistExtraCommerces/>
	<Hurrys/>
	<SpecialBuildingNotRequireds/>
	<SpecialistValids/>
	<BuildingHappinessChanges>
		<BuildingHappinessChange>
			<BuildingType>BUILDINGCLASS_ART_OF_WAR</BuildingType>
			<iHappinessChange>1</iHappinessChange>
		</BuildingHappinessChange>
	</BuildingHappinessChanges>
	<BuildingHealthChanges/>
	<FeatureHappinessChanges/>
	<ImprovementYieldChanges/>
	<!-- Civic Specialist Changes -->
	[COLOR="Red"]<SpecialistHealthChanges>
		<SpecialistHealthChange>
			<SpecialistType>SPECIALIST_DOCTOR</SpecialistType>
			<iHealthChange>1</iHealthChange>
		</SpecialistHealthChange>
	</SpecialistHealthChanges>[/COLOR]	
	<SpecialistHappinessChanges/>
	<SpecialistYieldChanges>
		<SpecialistYieldChange>
			<SpecialistType>SPECIALIST_ENGINEER</SpecialistType>
			<YieldChanges>
				<iYield>0</iYield> <!-- Food -->
				<iYield>1</iYield> <!-- Hammers -->
				<iYield>0</iYield> <!-- Commerce -->
			</YieldChanges>
		</SpecialistYieldChange>
	</SpecialistYieldChanges>
	<SpecialistCommerceChanges/>
	<!-- Civic Specialist Changes END -->
	<WeLoveTheKing>TXT_KEY_CIVIC_WE_LOVE_DESPOT</WeLoveTheKing>
</CivicInfo>


CvCity.h
Spoiler :

Code:
void updateSpecialistHealth(SpecialistTypes eIndex);
void changeSpecialistGoodHealth(SpecialistTypes eSpecialist, int iChange);
void changeSpecialistBadHealth(SpecialistTypes eSpecialist, int iChange);

int m_iExtraSpecialistGoodHealth;
int m_iExtraSpecialistBadHealth;


CvCity.cpp
Spoiler :

Code:
m_iExtraSpecialistGoodHealth = 0;
m_iExtraSpecialistBadHealth = 0;

iHealth = getExtraSpecialistBadHealth();
if (iHealth < 0)
{
	iTotalHealth += iHealth;
}


void CvCity::changeSpecialistGoodHealth(SpecialistTypes eIndex, int iChange)
{
	if (iChange != 0)
	{
		for (int iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
		{
			if (((SpecialistTypes)iI) == ((SpecialistTypes)eIndex))
			{
				m_iSpecialistGoodHealth += iChange;
				FAssert(getSpecialistGoodHealth() >= 0);

				AI_setAssignWorkDirty(true);

				if (getTeam() == GC.getGameINLINE().getActiveTeam())
				{
					setInfoDirty(true);
				}
			}
		}
	}
}


void CvCity::changeSpecialistBadHealth(SpecialistTypes eIndex, int iChange)
{
	if (iChange != 0)
	{
		for (int iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
		{
			if (((SpecialistTypes)iI) == ((SpecialistTypes)eIndex))
			{
				m_iSpecialistBadHealth += iChange;
				FAssert(getSpecialistGoodHealth() >= 0);

				AI_setAssignWorkDirty(true);

				if (getTeam() == GC.getGameINLINE().getActiveTeam())
				{
					setInfoDirty(true);
				}
			}
		}
	}
}


void CvCity::updateSpecialistHealth(SpecialistTypes eIndex)
{
	int intTotalExtraGoodHealth = 0;
	int intTotalExtraBadHealth = 0;
	
	
	for (int iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
	{
		if (((SpecialistTypes)iI) == ((SpecialistTypes)eIndex))
		{
			if (GET_PLAYER(getOwnerINLINE()).getExtraSpecialistHealth(SpecialistTypes(iI)) > 0)
			{
				intTotalExtraGoodHealth += GET_PLAYER(getOwnerINLINE()).getExtraSpecialistHealth(SpecialistTypes(iI)); 	
			}
			else
			{
				intTotalExtraBadHealth += GET_PLAYER(getOwnerINLINE()).getExtraSpecialistHealth(SpecialistTypes(iI)); 	
			}
		}
	}
	
	if ((getSpecialistGoodHealth() != intTotalExtraGoodHealth) || (getSpecialistBadHealth() != intTotalExtraBadHealth))
	{
		m_iSpecialistGoodHealth = intTotalExtraGoodHealth;
		m_iSpecialistBadHealth = intTotalExtraGoodHealth;
		FAssert(getSpecialistGoodHealth() >= 0);
		FAssert(getSpecialistBadHealth() <= 0);

		AI_setAssignWorkDirty(true);
	
		if (getTeam() == GC.getGameINLINE().getActiveTeam())
		{
			setInfoDirty(true);
		}
	}
}

int CvCity::getExtraSpecialistGoodHealth() const
{
	return m_iExtraSpecialistGoodHealth;
}


int CvCity::getExtraSpecialistBadHealth() const
{
	return m_iExtraSpecialistBadHealth;
}


pStream->Read(&m_iExtraSpecialistGoodHealth);
pStream->Read(&m_iExtraSpecialistBadHealth);


pStream->Write(m_iExtraSpecialistGoodHealth);
pStream->Write(m_iExtraSpecialistBadHealth);


CvGameTextMgr.cpp
Spoiler :

Code:
iLast = 0;

for (iI = 0; iI < GC.getNumSpecialistInfos(); ++iI)
{
	if (GC.getCivicInfo(eCivic).getSpecialistHealthChanges(iI) != 0)
	{
		//szFirstBuffer = gDLL->getText("TXT_KEY_BUILDING_FROM_IN_ALL_CITIES", GC.getSpecialistInfo((SpecialistTypes) iI).getTextKeyWide());
		//setYieldChangeHelp(szHelpText, L"", L"", szFirstBuffer, GC.getCivicInfo(eCivic).getSpecialistYieldChangeArray(iI));
		szFirstBuffer.Format(L"%s%s", NEWLINE, gDLL->getText("TXT_KEY_CIVIC_SPECIALIST_HEALTH", abs(GC.getCivicInfo(eCivic).getSpecialistHealthChanges(iI)), ((GC.getCivicInfo(eCivic).getSpecialistHealthChanges(iI) > 0) ? gDLL->getSymbolID(HEALTHY_CHAR) : gDLL->getSymbolID(UNHEALTHY_CHAR))).c_str());
		CvWString szSpecialist;
		szSpecialist.Format(L"<link=literal>%s</link>", GC.getSpecialistInfo((SpecialistTypes)iI).getDescription());
		setListHelp(szHelpText, szFirstBuffer, szSpecialist, L", ", (GC.getCivicInfo(eCivic).getSpecialistHealthChanges(iI) != iLast));
		iLast = GC.getCivicInfo(eCivic).getSpecialistHealthChanges(iI);
	}
}


CvInfos.h
Spoiler :

Code:
int getSpecialistHealthChanges(int i) const;

int* m_paiSpecialistHealthChanges;


CvInfos.cpp
Spoiler :

Code:
m_paiSpecialistHealthChanges(NULL),

SAFE_DELETE_ARRAY(m_paiSpecialistHealthChanges);

int CvCivicInfo::getSpecialistHealthChanges(int i) const
{
	FAssertMsg(i < GC.getNumSpecialistInfos(), "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_paiSpecialistHealthChanges ? m_paiSpecialistHealthChanges[i] : -1;
}

SAFE_DELETE_ARRAY(m_paiSpecialistHealthChanges);
m_paiSpecialistHealthChanges = new int[GC.getNumSpecialistInfos()];
stream->Read(GC.getNumSpecialistInfos(), m_paiSpecialistHealthChanges);

stream->Write(GC.getNumSpecialistInfos(), m_paiSpecialistHealthChanges);

	pXML->SetVariableListTagPair(&m_paiSpecialistHealthChanges, "SpecialistHealthChanges", sizeof(GC.getSpecialistInfo((SpecialistTypes)0)), GC.getNumSpecialistInfos());


CvPlayer.h
Spoiler :

Code:
void updateExtraSpecialistHealth();

int getExtraSpecialistHealth(SpecialistTypes eIndex) const;		
void changeExtraSpecialistHealth(SpecialistTypes eIndex, int iChange);

int* m_paiSpecialistHealth;
int* m_paiExtraSpecialistHealth;


CvPlayer.cpp
Spoiler :

Code:
m_paiExtraSpecialistHealth = NULL;

SAFE_DELETE_ARRAY(m_paiExtraSpecialistHealth);

FAssertMsg(m_paiExtraSpecialistHealth==NULL, "about to leak memory, CvPlayer::m_paiExtraSpecialistHealth");
m_paiExtraSpecialistHealth = new int [GC.getNumSpecialistInfos()];
for (iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
{
	m_paiExtraSpecialistHealth[iI] = 0;
}

void CvPlayer::updateExtraSpecialistHealth()
{
	CvCity* pLoopCity;
	int iLoop;

	for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
	{
		pLoopCity->updateExtraSpecialistHealth();
	}
}

int CvPlayer::getExtraSpecialistHealth(SpecialistTypes eIndex) const 
{
	FAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex < GC.getNumSpecialistInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");
	return m_paiExtraSpecialistHealth[eIndex];
}


void CvPlayer::changeExtraSpecialistHealth(SpecialistTypes eIndex, int iChange)
{
	FAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex < GC.getNumSpecialistInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");

	if (iChange != 0)
	{
		m_paiExtraSpecialistHealth[eIndex] = (m_paiExtraSpecialistHealth[eIndex] + iChange);

		updateExtraSpecialistHealth();
	}
}


for (iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
	{
		changeExtraSpecialistHealth(((SpecialistTypes)iI), (GC.getCivicInfo(eCivic).getSpecialistHealthChanges(iI) * iChange));
		//changeSpecialistHealth(((SpecialistTypes)iI), iChange);
	}

pStream->Read(GC.getNumSpecialistInfos(), m_paiExtraSpecialistHealth);

pStream->Write(GC.getNumSpecialistInfos(), m_paiExtraSpecialistHealth);
 
Back
Top Bottom