Bazaar developer reference

CvPlot::changeAdjacentSight(TeamTypes, int, bool, InvisibleTypes, DirectionTypes, CvUnit *)

Defined in
CvPlot.cpp, line 1529
Class
CvPlot
Hook name
CivHooks::CvPlot_changeAdjacentSight

Hooks

static bool BeforeCvPlot_changeAdjacentSight(CvPlot* self, TeamTypes eTeam, int iRange, bool bIncrement, InvisibleTypes eSeeInvisible, DirectionTypes eFacingDirection, CvUnit* pUnit);static void AfterCvPlot_changeAdjacentSight(CvPlot* self, TeamTypes eTeam, int iRange, bool bIncrement, InvisibleTypes eSeeInvisible, DirectionTypes eFacingDirection, CvUnit* pUnit);static void ReplaceCvPlot_changeAdjacentSight(void (*original)(CvPlot*, TeamTypes, int, bool, InvisibleTypes, DirectionTypes, CvUnit*), CvPlot* self, TeamTypes eTeam, int iRange, bool bIncrement, InvisibleTypes eSeeInvisible, DirectionTypes eFacingDirection, CvUnit* pUnit);CivRegisterBefore<CivHooks::CvPlot_changeAdjacentSight>(host, &BeforeCvPlot_changeAdjacentSight);CivRegisterAfter<CivHooks::CvPlot_changeAdjacentSight>(host, &AfterCvPlot_changeAdjacentSight);CivRegisterReplace<CivHooks::CvPlot_changeAdjacentSight>(host, &ReplaceCvPlot_changeAdjacentSight);

Code

1527// while this looks more complex than the previous version, it should run much faster1528#if defined(MOD_API_EXTENSIONS)1529void CvPlot::changeAdjacentSight(TeamTypes eTeam, int iRange, bool bIncrement, InvisibleTypes eSeeInvisible, DirectionTypes eFacingDirection, CvUnit* pUnit)1530#else1531void CvPlot::changeAdjacentSight(TeamTypes eTeam, int iRange, bool bIncrement, InvisibleTypes eSeeInvisible, DirectionTypes eFacingDirection, bool bBasedOnUnit)1532#endif1533{1534#if defined(MOD_API_EXTENSIONS)1535	bool bBasedOnUnit = (pUnit != NULL);1536#endif1537	//check one extra outer ring1538	int iRangeWithOneExtraRing = iRange + 1;15391540	// start in the center going NE1541	int thisRing = 0;1542	DirectionTypes eDirectionOfNextTileToCheck = DIRECTION_NORTHWEST;1543	CvPlot* pPlotToCheck = this;1544	int iDX = 0;1545	int iDY = 0;1546	int iCenterLevel = seeFromLevel(eTeam);1547	int iPlotCounter = 0;1548	int iMaxPlotNumberOnThisRing = 0;15491550	while(thisRing <= iRangeWithOneExtraRing)1551	{1552		if(pPlotToCheck)1553		{1554			//always reveal adjacent plots when using line of sight - but then clear it out1555			if(thisRing <= 1)1556			{1557				if(eFacingDirection != NO_DIRECTION)1558				{1559#if defined(MOD_API_EXTENSIONS)1560					pPlotToCheck->changeVisibilityCount(eTeam, 1, eSeeInvisible, false /*bInformExplorationTracking*/, false, pUnit);1561					pPlotToCheck->changeVisibilityCount(eTeam, -1, eSeeInvisible, false /*bInformExplorationTracking*/, false, pUnit);1562#else1563					pPlotToCheck->changeVisibilityCount(eTeam, 1, eSeeInvisible, false /*bInformExplorationTracking*/, false);1564					pPlotToCheck->changeVisibilityCount(eTeam, -1, eSeeInvisible, false /*bInformExplorationTracking*/, false);1565#endif1566				}1567			}15681569			// see if this plot is in the visibility wedge1570			if(shouldProcessDisplacementPlot(iDX, iDY, iRange, eFacingDirection))1571			{1572				if(thisRing != 0)1573				{1574					CvPlot* pFirstInwardPlot = NULL;1575					CvPlot* pSecondInwardPlot = NULL;1576					const int INVALID_RING = -1;1577					const int HALF_BLOCKED = 0x01000000;1578					int iRingOfFirstInwardPlot = INVALID_RING;1579					int iRingOfSecondInwardPlot = INVALID_RING;1580					int iFirstInwardLevel = INVALID_RING;1581					int iSecondInwardLevel = INVALID_RING;1582					bool bFirstHalfBlocked = false;1583					bool bSecondHalfBlocked = false;15841585					// try to look at the two plot inwards1586					switch(eDirectionOfNextTileToCheck)1587					{1588					case DIRECTION_NORTHEAST:1589						pFirstInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_EAST);1590						pSecondInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_SOUTHEAST);1591						break;1592					case DIRECTION_EAST:1593						pFirstInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_SOUTHWEST);1594						pSecondInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_SOUTHEAST);1595						break;1596					case DIRECTION_SOUTHEAST:1597						pFirstInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_SOUTHWEST);1598						pSecondInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_WEST);1599						break;1600					case DIRECTION_SOUTHWEST:1601						pFirstInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_WEST);1602						pSecondInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_NORTHWEST);1603						break;1604					case DIRECTION_WEST:1605						pFirstInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_NORTHWEST);1606						pSecondInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_NORTHEAST);1607						break;1608					case DIRECTION_NORTHWEST:1609						pFirstInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_EAST);1610						pSecondInwardPlot = plotDirection(pPlotToCheck->getX(),pPlotToCheck->getY(),DIRECTION_NORTHEAST);1611						break;1612					}1613					if(pFirstInwardPlot)1614					{1615						iRingOfFirstInwardPlot = plotDistance(getX(),getY(),pFirstInwardPlot->getX(),pFirstInwardPlot->getY());1616						if(iRingOfFirstInwardPlot == thisRing - 1)1617						{1618							iFirstInwardLevel = pFirstInwardPlot->getScratchPad();1619							if(iFirstInwardLevel >= HALF_BLOCKED)1620							{1621								iFirstInwardLevel -= HALF_BLOCKED;1622								bFirstHalfBlocked = true;1623							}1624						}1625					}1626					if(pSecondInwardPlot)1627					{1628						iRingOfSecondInwardPlot = plotDistance(getX(),getY(),pSecondInwardPlot->getX(),pSecondInwardPlot->getY());1629						if(iRingOfSecondInwardPlot == thisRing - 1)1630						{1631							iSecondInwardLevel = pSecondInwardPlot->getScratchPad();1632							if(iSecondInwardLevel >= HALF_BLOCKED)1633							{1634								iSecondInwardLevel -= HALF_BLOCKED;1635								bSecondHalfBlocked = true;1636							}1637						}1638					}1639					int iThisPlotLevel = pPlotToCheck->seeThroughLevel(thisRing != iRangeWithOneExtraRing);1640					if(iFirstInwardLevel != INVALID_RING && iSecondInwardLevel != INVALID_RING && iFirstInwardLevel != iSecondInwardLevel && !bFirstHalfBlocked && !bSecondHalfBlocked)1641					{1642						double fP0X = (double) getX();1643						double fP0Y = (double) getY();1644						double fP1X = (double) pPlotToCheck->getX();1645						double fP1Y = (double) pPlotToCheck->getY();1646						if(getY() & 1)1647						{1648							fP0X += 0.5;1649						}1650						if(pPlotToCheck->getY() & 1)1651						{1652							fP1X += 0.5;1653						}16541655						double a = fP1Y - fP0Y;1656						double b = fP0X - fP1X;1657						double c = fP0Y * fP1X - fP1Y * fP0X;16581659						double fFirstInwardX = (double) pFirstInwardPlot->getX();1660						double fFirstInwardY = (double) pFirstInwardPlot->getY();1661						if(pFirstInwardPlot->getY() & 1)1662						{1663							fFirstInwardX += 0.5;1664						}1665						double fFirstDist = a * fFirstInwardX + b * fFirstInwardY + c;1666						fFirstDist = abs(fFirstDist);1667						// skip the extra distance since it is the same for both equations16681669						double fSecondInwardX = (double) pSecondInwardPlot->getX();1670						double fSecondInwardY = (double) pSecondInwardPlot->getY();1671						if(pSecondInwardPlot->getY() & 1)1672						{1673							fSecondInwardX += 0.5;1674						}1675						double fSecondDist = a * fSecondInwardX + b * fSecondInwardY + c;1676						fSecondDist = abs(fSecondDist);1677						// skip the extra distance since it is the same for both equations16781679						if(fFirstDist - fSecondDist > 0.05)  // we are closer to the second point1680						{1681							int iHighestLevel = (iSecondInwardLevel > iThisPlotLevel) ? iSecondInwardLevel : iThisPlotLevel;1682							pPlotToCheck->setScratchPad(iHighestLevel);1683							if(iSecondInwardLevel < iThisPlotLevel || ((iCenterLevel >= iSecondInwardLevel) && (thisRing < iRangeWithOneExtraRing)))1684							{								1685#if defined(MOD_API_EXTENSIONS)1686								pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2) ? true : false, pUnit);1687#else1688								pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2)?true:false);1689#endif1690							}1691						}1692						else if(fSecondDist - fFirstDist > 0.05)   // we are closer to the first point1693						{1694							int iHighestLevel = (iFirstInwardLevel > iThisPlotLevel) ? iFirstInwardLevel : iThisPlotLevel;1695							pPlotToCheck->setScratchPad(iHighestLevel);1696							if(iFirstInwardLevel < iThisPlotLevel || ((iCenterLevel >= iFirstInwardLevel) && (thisRing < iRangeWithOneExtraRing)))1697							{								1698#if defined(MOD_API_EXTENSIONS)1699								pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2) ? true : false, pUnit);1700#else1701								pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2)?true:false);1702#endif1703							}1704						}1705						else1706						{1707							int iHighestInwardLevel = (iFirstInwardLevel > iSecondInwardLevel) ? iFirstInwardLevel : iSecondInwardLevel;1708							int iLowestInwardLevel = (iFirstInwardLevel > iSecondInwardLevel) ? iSecondInwardLevel : iFirstInwardLevel;1709							int iHighestLevel = (iHighestInwardLevel > iThisPlotLevel) ? iHighestInwardLevel : iThisPlotLevel;1710							int iHighestLowestLevel = (iLowestInwardLevel > iThisPlotLevel) ? iLowestInwardLevel : iThisPlotLevel;1711							if(iHighestInwardLevel > iThisPlotLevel)1712							{1713								pPlotToCheck->setScratchPad(iHighestLowestLevel + HALF_BLOCKED);1714							}1715							else1716							{1717								pPlotToCheck->setScratchPad(iHighestLevel);1718							}1719							if(iLowestInwardLevel < iThisPlotLevel || ((iCenterLevel >= iLowestInwardLevel) && (thisRing < iRangeWithOneExtraRing)))1720							{								1721#if defined(MOD_API_EXTENSIONS)1722								pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2) ? true : false, pUnit);1723#else1724								pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2)?true:false);1725#endif1726							}1727						}1728					}1729					else if(iFirstInwardLevel != INVALID_RING && !bFirstHalfBlocked)1730					{1731						int iHighestLevel = (iFirstInwardLevel > iThisPlotLevel) ? iFirstInwardLevel : iThisPlotLevel;1732						pPlotToCheck->setScratchPad(iHighestLevel);1733						if(iFirstInwardLevel < iThisPlotLevel || ((iCenterLevel >= iFirstInwardLevel) && (thisRing < iRangeWithOneExtraRing)))1734						{							1735#if defined(MOD_API_EXTENSIONS)1736							pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2) ? true : false, pUnit);1737#else1738							pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2)?true:false);1739#endif1740						}1741					}1742					else if(iSecondInwardLevel != INVALID_RING && !bSecondHalfBlocked)1743					{1744						int iHighestLevel = (iSecondInwardLevel > iThisPlotLevel) ? iSecondInwardLevel : iThisPlotLevel;1745						pPlotToCheck->setScratchPad(iHighestLevel);1746						if(iSecondInwardLevel < iThisPlotLevel || ((iCenterLevel >= iSecondInwardLevel) && (thisRing < iRangeWithOneExtraRing)))1747						{							1748#if defined(MOD_API_EXTENSIONS)1749							pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2) ? true : false, pUnit);1750#else1751							pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2)?true:false);1752#endif1753						}1754					}1755					else if(iFirstInwardLevel != INVALID_RING)1756					{1757						int iHighestLevel = (iFirstInwardLevel > iThisPlotLevel) ? iFirstInwardLevel : iThisPlotLevel;1758						pPlotToCheck->setScratchPad(iHighestLevel);1759						if(iFirstInwardLevel < iThisPlotLevel || ((iCenterLevel >= iFirstInwardLevel) && (thisRing < iRangeWithOneExtraRing)))1760						{1761#if defined(MOD_API_EXTENSIONS)1762							pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2) ? true : false, pUnit);1763#else1764							pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2)?true:false);1765#endif1766						}1767					}1768					else if(iSecondInwardLevel != INVALID_RING)1769					{1770						int iHighestLevel = (iSecondInwardLevel > iThisPlotLevel) ? iSecondInwardLevel : iThisPlotLevel;1771						pPlotToCheck->setScratchPad(iHighestLevel);1772						if(iSecondInwardLevel < iThisPlotLevel || ((iCenterLevel >= iSecondInwardLevel) && (thisRing < iRangeWithOneExtraRing)))1773						{							1774#if defined(MOD_API_EXTENSIONS)1775							pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2) ? true : false, pUnit);1776#else1777							pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2)?true:false);1778#endif1779						}1780					}1781					else // I have no idea how this can happen, but...1782					{1783						// set our value in the scratch pad1784						pPlotToCheck->setScratchPad(iThisPlotLevel);1785					}1786				}1787				else // this is the center point1788				{					1789#if defined(MOD_API_EXTENSIONS)1790					pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2) ? true : false, pUnit);1791#else1792					pPlotToCheck->changeVisibilityCount(eTeam, ((bIncrement) ? 1 : -1), eSeeInvisible, true, (bBasedOnUnit && thisRing < 2)?true:false);1793#endif1794					pPlotToCheck->setScratchPad(0);1795				}1796			}17971798		}17991800		int iNextDX;1801		int iNextDY;1802		if(iPlotCounter >= iMaxPlotNumberOnThisRing)  // we have processed all of the plots in this ring1803		{1804			// if that fails go out one ring in the NE direction traveling E1805			eDirectionOfNextTileToCheck = DIRECTION_NORTHEAST;1806			iNextDX = iDX + GC.getPlotDirectionX()[eDirectionOfNextTileToCheck];1807			iNextDY = iDY + GC.getPlotDirectionY()[eDirectionOfNextTileToCheck];1808			thisRing++;1809			iMaxPlotNumberOnThisRing += thisRing * 6;1810			eDirectionOfNextTileToCheck = DIRECTION_EAST;1811			// (if that is further out than the extended range, we are done)1812		}1813		else1814		{1815			iNextDX = iDX + GC.getPlotDirectionX()[eDirectionOfNextTileToCheck];1816			iNextDY = iDY + GC.getPlotDirectionY()[eDirectionOfNextTileToCheck];1817			if(hexDistance(iNextDX,iNextDY) > thisRing)1818			{1819				// try to turn right1820				eDirectionOfNextTileToCheck = GC.getTurnRightDirection(eDirectionOfNextTileToCheck);1821				iNextDX = iDX + GC.getPlotDirectionX()[eDirectionOfNextTileToCheck];1822				iNextDY = iDY + GC.getPlotDirectionY()[eDirectionOfNextTileToCheck];1823			}1824		}18251826		iPlotCounter++;18271828		iDX = iNextDX;1829		iDY = iNextDY;1830		pPlotToCheck = plotXYWithRangeCheck(getX(),getY(),iDX,iDY,iRangeWithOneExtraRing);1831	}18321833}

Calls

Called by