Bazaar developer reference

CvUnit::UnitAttack(int, int, int, int)

Defined in
CvUnit.cpp, line 22774
Class
CvUnit
Hook name
CivHooks::CvUnit_UnitAttack

Hooks

static bool BeforeCvUnit_UnitAttack(CvUnit* self, int iX, int iY, int iFlags, int iSteps, bool& result);static void AfterCvUnit_UnitAttack(CvUnit* self, int iX, int iY, int iFlags, int iSteps, bool& result);static bool ReplaceCvUnit_UnitAttack(bool (*original)(CvUnit*, int, int, int, int), CvUnit* self, int iX, int iY, int iFlags, int iSteps);CivRegisterBefore<CivHooks::CvUnit_UnitAttack>(host, &BeforeCvUnit_UnitAttack);CivRegisterAfter<CivHooks::CvUnit_UnitAttack>(host, &AfterCvUnit_UnitAttack);CivRegisterReplace<CivHooks::CvUnit_UnitAttack>(host, &ReplaceCvUnit_UnitAttack);

Code

22773// Returns true if attack was made...22774bool CvUnit::UnitAttack(int iX, int iY, int iFlags, int iSteps)22775{22776	VALIDATE_OBJECT22777	CvMap& kMap = GC.getMap();22778	CvPlot* pDestPlot = kMap.plot(iX, iY);2277922780	CvAssertMsg(pDestPlot != NULL, "DestPlot is not assigned a valid value");22781	if(!pDestPlot)22782	{22783		return false;22784	}2278522786#if defined(MOD_GLOBAL_BREAK_CIVILIAN_RESTRICTIONS)22787	if (MOD_GLOBAL_BREAK_CIVILIAN_RESTRICTIONS && IsCivilianUnit())22788		return false;22789#endif2279022791	// Test if this attack requires war to be declared first22792	if(isHuman() && getOwner() == GC.getGame().getActivePlayer() && pDestPlot->isVisible(getTeam()))22793	{22794		TeamTypes eRivalTeam = GetDeclareWarMove(*pDestPlot);2279522796		if(eRivalTeam != NO_TEAM)22797		{22798			CvPopupInfo kPopup(BUTTONPOPUP_DECLAREWARMOVE);22799			kPopup.iData1 = eRivalTeam;22800			kPopup.iData2 = pDestPlot->getX();22801			kPopup.iData3 = pDestPlot->getY();22802			kPopup.bOption1 = false;22803			kPopup.bOption2 = pDestPlot->getTeam() != eRivalTeam;22804			if(pDestPlot->isCity())22805			{22806				kPopup.iFlags = DOW_MOVE_ONTO_CITY;22807			}22808			// If a unit was present, put up the standard DOW message22809#if defined(MOD_BUGFIX_USE_GETTERS)22810			else if (pDestPlot->isVisibleOtherUnit(getOwner()))22811#else22812			else if (pDestPlot->isVisibleOtherUnit(m_eOwner))22813#endif22814			{22815				kPopup.iFlags = DOW_MOVE_ONTO_UNIT;22816			}22817			// Otherwise put out one about entering enemy territory22818			else22819			{22820				kPopup.iFlags = DOW_MOVE_INTO_TERRITORY;22821			}22822			DLLUI->AddPopup(kPopup);2282322824			return false;22825		}22826	}2282722828	const CvPathNodeArray& kPathNodeArray = GetPathNodeArray();2282922830	if(iFlags & MOVE_UNITS_THROUGH_ENEMY)22831	{22832		if(GeneratePath(pDestPlot, iFlags))22833		{22834			pDestPlot = GetPathFirstPlot();22835		}22836	}22837	else22838	{22839		if(getDomainType() != DOMAIN_AIR)22840		{22841			iSteps += 0;2284222843			UpdatePathCache(pDestPlot, iFlags);22844		}22845	}2284622847	CvAssertMsg(pDestPlot != NULL, "DestPlot is not assigned a valid value");2284822849	if(!pDestPlot)22850	{22851		return false;22852	}2285322854	bool bAttack = false;22855	bool bAdjacent = false;2285622857	// No path or air unit?22858	if(kPathNodeArray.size() == 0 || getDomainType() == DOMAIN_AIR)22859	{22860		// Manually check for adjacency22861		if((getDomainType() == DOMAIN_AIR) || (plotDistance(getX(), getY(), iX, iY) == 1))22862		{22863			if((iFlags & MISSION_MODIFIER_DIRECT_ATTACK) || (getDomainType() == DOMAIN_AIR) || (GeneratePath(pDestPlot, iFlags) && (GetPathFirstPlot() == pDestPlot)))22864			{22865				bAdjacent = true;22866			}22867		}22868	}22869	// Multi-turn move22870	else if(kPathNodeArray.size() != 0)22871	{22872		if(kPathNodeArray.size() > 1)22873		{22874			// Previous node is the same plot as the one before the destination (attack point)?22875			// Prevents unit from stopping while adjacent to the enemy, but on top of another unit so it has to move to another tile before it can attack22876			const CvPathNode& kNode = kPathNodeArray[1];22877			if(kNode.m_iX == getX() && kNode.m_iY == getY())22878			{22879				// The path may not be all the way to the destination, it may be only to the unit's turn limit, so check against the final destination22880				const CvPathNode& kDestNode = kPathNodeArray[0];22881				if (kDestNode.m_iX == iX && kDestNode.m_iY == iY)22882				{22883					bAdjacent = true;22884				}22885			}22886		}22887	}2288822889	if(bAdjacent)22890	{22891		if(!isOutOfAttacks() && (!IsCityAttackOnly() || pDestPlot->isEnemyCity(*this) || !pDestPlot->getBestDefender(NO_PLAYER)))22892		{22893			// don't allow an attack if we already have one22894			if(isFighting() || pDestPlot->isFighting())22895			{22896				return true;22897			}2289822899			// Air mission22900			if(getDomainType() == DOMAIN_AIR && GetBaseCombatStrength() == 0)22901			{22902				if(canRangeStrikeAt(iX, iY))22903				{22904					CvUnitCombat::AttackAir(*this, *pDestPlot, (iFlags &  MISSION_MODIFIER_NO_DEFENSIVE_SUPPORT)?CvUnitCombat::ATTACK_OPTION_NO_DEFENSIVE_SUPPORT:CvUnitCombat::ATTACK_OPTION_NONE);22905					bAttack = true;22906				}22907			}2290822909			// City combat22910			else if(pDestPlot->isCity())22911			{22912				if(GET_TEAM(getTeam()).isAtWar(pDestPlot->getPlotCity()->getTeam()))22913				{22914					if(getDomainType() != DOMAIN_AIR)22915					{22916						// Ranged units that are embarked can't do a move-attack22917						if(isRanged() && isEmbarked())22918						{22919							return false;22920						}2292122922						CvUnitCombat::AttackCity(*this, *pDestPlot, (iFlags &  MISSION_MODIFIER_NO_DEFENSIVE_SUPPORT)?CvUnitCombat::ATTACK_OPTION_NO_DEFENSIVE_SUPPORT:CvUnitCombat::ATTACK_OPTION_NONE);22923						bAttack = true;22924					}22925				}22926			}2292722928			// Normal unit combat22929			else22930			{22931				// if there are no defenders, do not attack22932				UnitHandle pBestDefender = pDestPlot->getBestDefender(NO_PLAYER, getOwner(), this, true);22933				if(!pBestDefender)22934				{22935					return false;22936				}2293722938				// Ranged units that are embarked can't do a move-attack22939				if(isRanged() && isEmbarked())22940				{22941					return false;22942				}2294322944				bAttack = true;22945				CvUnitCombat::Attack(*this, *pDestPlot, (iFlags &  MISSION_MODIFIER_NO_DEFENSIVE_SUPPORT)?CvUnitCombat::ATTACK_OPTION_NO_DEFENSIVE_SUPPORT:CvUnitCombat::ATTACK_OPTION_NONE);22946			}2294722948			// Barb camp here that was attacked?22949			if(pDestPlot->getImprovementType() == GC.getBARBARIAN_CAMP_IMPROVEMENT())22950			{22951				CvBarbarians::DoCampAttacked(pDestPlot);22952			}22953		}22954	}2295522956	return bAttack;22957}

Calls

Called by