Bazaar developer reference

CvUnit::convert(CvUnit *, bool)

Defined in
CvUnit.cpp, line 1319
Class
CvUnit
Hook name
CivHooks::CvUnit_convert
Changed in
0.5.0 (added hand-placed hook UnitReplaced)

Hand-placed hooks inside

A replacement for this function that does not call original stops these hooks from running.

Hooks

static bool BeforeCvUnit_convert(CvUnit* self, CvUnit* pUnit, bool bIsUpgrade);static void AfterCvUnit_convert(CvUnit* self, CvUnit* pUnit, bool bIsUpgrade);static void ReplaceCvUnit_convert(void (*original)(CvUnit*, CvUnit*, bool), CvUnit* self, CvUnit* pUnit, bool bIsUpgrade);CivRegisterBefore<CivHooks::CvUnit_convert>(host, &BeforeCvUnit_convert);CivRegisterAfter<CivHooks::CvUnit_convert>(host, &AfterCvUnit_convert);CivRegisterReplace<CivHooks::CvUnit_convert>(host, &ReplaceCvUnit_convert);

Code

1319void CvUnit::convert(CvUnit* pUnit, bool bIsUpgrade)1320{1321	VALIDATE_OBJECT1322	IDInfo* pUnitNode;1323	CvUnit* pTransportUnit;1324	CvUnit* pLoopUnit;1325	CvPlot* pPlot;13261327	pPlot = plot();13281329	// Transfer Promotions over1330	for(int iI = 0; iI < GC.getNumPromotionInfos(); iI++)1331	{1332		const PromotionTypes ePromotion = static_cast<PromotionTypes>(iI);1333		CvPromotionEntry* pkPromotionInfo = GC.getPromotionInfo(ePromotion);1334		if(pkPromotionInfo)1335		{1336			bool bGivePromotion = false;13371338#if defined(MOD_PROMOTIONS_DEEP_WATER_EMBARKATION)1339			if (MOD_PROMOTIONS_DEEP_WATER_EMBARKATION && (pkPromotionInfo->IsAllowsEmbarkation() || pkPromotionInfo->IsEmbarkedAllWater() || pkPromotionInfo->IsEmbarkedDeepWater())) {1340				// if (pUnit->isHasPromotion(ePromotion)) CUSTOMLOG("Removing embarkation promotion %i from %s", iI, getName().c_str());1341				// Embarakation promotions are handled as special case below1342			}1343			else1344			{1345#endif1346				// Old unit has the promotion1347				if (pUnit->isHasPromotion(ePromotion) && !pkPromotionInfo->IsLostWithUpgrade())1348				{1349					bGivePromotion = true;1350				}13511352				// New unit gets promotion for free (as per XML)1353				else if (getUnitInfo().GetFreePromotions(ePromotion) && (!bIsUpgrade || !pkPromotionInfo->IsNotWithUpgrade()))1354				{1355					bGivePromotion = true;1356				}13571358				// if we get this due to a policy or wonder1359				else if (GET_PLAYER(getOwner()).IsFreePromotion(ePromotion) && (1360					::IsPromotionValidForUnitCombatType(ePromotion, getUnitType()) || ::IsPromotionValidForCivilianUnitType(ePromotion, getUnitType())))1361				{1362					bGivePromotion = true;1363				}1364#if defined(MOD_PROMOTIONS_DEEP_WATER_EMBARKATION)1365			}1366#endif13671368			setHasPromotion(ePromotion, bGivePromotion);1369		}1370	}13711372	setGameTurnCreated(pUnit->getGameTurnCreated());1373	setLastMoveTurn(pUnit->getLastMoveTurn());1374#if defined(MOD_UNITS_MAX_HP)1375	// Don't kill the unit if upgrading from a unit with more base hit points!!!1376	setDamage(min(pUnit->getDamage(), GetMaxHitPoints()-1));1377#else1378	setDamage(pUnit->getDamage());1379#endif1380	setMoves(pUnit->getMoves());13811382#if defined(MOD_PROMOTIONS_DEEP_WATER_EMBARKATION)1383	if (MOD_PROMOTIONS_DEEP_WATER_EMBARKATION) {1384		// We need to be a little bit clever about the embarked state for land units1385		// CUSTOMLOG("Converting unit %s, figuring out required embarkation promotion ...", getName().c_str());13861387		// Don't use getDomainType() here as it pulls tricks with the hover domain1388		if (DOMAIN_LAND == (DomainTypes)m_pUnitInfo->GetDomainType()) {1389			// Can the new unit get an embarkation promotion?1390			CvPlayer& kPlayer = GET_PLAYER(getOwner());13911392			if (GET_TEAM(getTeam()).canEmbark() || kPlayer.GetPlayerTraits()->IsEmbarkedAllWater())1393			{1394				PromotionTypes ePromotionEmbarkation = kPlayer.GetDeepWaterEmbarkationPromotion();13951396				if (::IsPromotionValidForUnitCombatType(ePromotionEmbarkation, getUnitType()))1397				{1398					setHasPromotion(ePromotionEmbarkation, true);1399					// CUSTOMLOG("  ... Giving deep water embarkation promotion %i", ePromotionEmbarkation);1400				}1401				else1402				{1403					ePromotionEmbarkation = kPlayer.GetEmbarkationPromotion();14041405					if (::IsPromotionValidForUnitCombatType(ePromotionEmbarkation, getUnitType()))1406					{1407						setHasPromotion(ePromotionEmbarkation, true);1408						// CUSTOMLOG("  ... Giving embarkation promotion %i", ePromotionEmbarkation);1409					}1410					else1411					{1412						// CUSTOMLOG("  ... no valid embarkation promotion");1413					}1414				}1415			}1416			else1417			{1418				// CUSTOMLOG("  ... player cannot embark");1419			}14201421			// With the correct embarkation promotion sorted, we can now work out if the new unit can be here1422			bool bJump = true;1423			// CUSTOMLOG("Converting unit %s, considering location and embarkation state ...", getName().c_str());1424			if (canEnterTerrain(*pPlot) && pPlot->isValidDomainForLocation(*this))1425			{1426				// I can be here, so do nothing1427				bJump = false;1428				// CUSTOMLOG("  ... apparently I can be here");1429			}1430			else if (pPlot->isWater() && (IsHasEmbarkAbility() || IsEmbarkDeepWater()))1431			{1432				// Set embarked and try again1433				setEmbarked(true);14341435				if (canEnterTerrain(*pPlot) && pPlot->isValidDomainForLocation(*this))1436				{1437					// I can be here embarked, so do nothing1438					bJump = false;1439					// CUSTOMLOG("  ... I can be here, but I need to be embarked");1440				}1441				else1442				{1443					// Otherwise remove the embarked state in preparation of getting out of here1444					setEmbarked(false);1445				}1446			}14471448			if (bJump) {1449				// I need to get out of here!1450				/* bool bMoved = */ jumpToNearestValidPlot();1451				// CUSTOMLOG("  ... I need to move%s", (bMoved ? "" : " - but I can't!"));1452			}1453		}1454		else1455		{1456			// CUSTOMLOG("  ... not a land unit, no embarkation promotion required");1457		}1458	} else 1459#endif1460		setEmbarked(pUnit->isEmbarked());14611462#if defined(MOD_API_UNIT_STATS)1463	setStatsTravelled(pUnit->getStatsTravelled());1464	setStatsKilled(pUnit->getStatsKilled());1465#endif1466	setFacingDirection(pUnit->getFacingDirection(false));1467	SetBeenPromotedFromGoody(pUnit->IsHasBeenPromotedFromGoody());1468	SetTourismBlastStrength(pUnit->GetTourismBlastStrength());14691470	if (pUnit->getUnitInfo().GetNumExoticGoods() > 0)1471	{1472		setNumExoticGoods(pUnit->getNumExoticGoods());1473	}14741475	setLevel(pUnit->getLevel());1476	int iOldModifier = std::max(1, 100 + GET_PLAYER(pUnit->getOwner()).getLevelExperienceModifier());1477	int iOurModifier = std::max(1, 100 + GET_PLAYER(getOwner()).getLevelExperienceModifier());1478#if defined(MOD_UNITS_XP_TIMES_100)1479	setExperienceTimes100(std::max(0, (pUnit->getExperienceTimes100() * iOurModifier) / iOldModifier));1480#else1481	setExperience(std::max(0, (pUnit->getExperience() * iOurModifier) / iOldModifier));1482#endif14831484	setName(pUnit->getNameNoDesc());1485	setLeaderUnitType(pUnit->getLeaderUnitType());1486	ChangeNumGoodyHutsPopped(pUnit->GetNumGoodyHutsPopped());14871488	pTransportUnit = pUnit->getTransportUnit();14891490	if(pTransportUnit != NULL)1491	{1492		pUnit->setTransportUnit(NULL);1493		setTransportUnit(pTransportUnit);1494	}14951496	pUnitNode = pPlot->headUnitNode();14971498	while(pUnitNode != NULL)1499	{1500		pLoopUnit = ::getUnit(*pUnitNode);1501		pUnitNode = pPlot->nextUnitNode(pUnitNode);15021503		if(pLoopUnit && pLoopUnit->getTransportUnit() == pUnit)1504		{1505			pLoopUnit->setTransportUnit(this);1506		}1507	}15081509#if defined(CIV_HOST_API)1510	CivHandUnitReplaced(pUnit->getOwner(), pUnit->GetID(), this);hand-placed hook: UnitReplaced1511#endif1512	pUnit->kill(true);1513}

Calls

Called by