Hooks
static bool BeforeCvPlayer_addFreeUnit(CvPlayer* self, UnitTypes eUnit, UnitAITypes eUnitAI, CvPlot*& result);static void AfterCvPlayer_addFreeUnit(CvPlayer* self, UnitTypes eUnit, UnitAITypes eUnitAI, CvPlot*& result);static CvPlot* ReplaceCvPlayer_addFreeUnit(CvPlot* (*original)(CvPlayer*, UnitTypes, UnitAITypes), CvPlayer* self, UnitTypes eUnit, UnitAITypes eUnitAI);CivRegisterBefore<CivHooks::CvPlayer_addFreeUnit>(host, &BeforeCvPlayer_addFreeUnit);CivRegisterAfter<CivHooks::CvPlayer_addFreeUnit>(host, &AfterCvPlayer_addFreeUnit);CivRegisterReplace<CivHooks::CvPlayer_addFreeUnit>(host, &ReplaceCvPlayer_addFreeUnit);
Code
1724/// Returns plot where new unit was created1725CvPlot* CvPlayer::addFreeUnit(UnitTypes eUnit, UnitAITypes eUnitAI)1726{1727 CvPlot* pStartingPlot;1728#if defined(MOD_BUGFIX_FREE_RELIGIOUS_UNITS)1729 CvPlot* pBestPlot = NULL;1730#else1731 CvPlot* pBestPlot;1732#endif1733 CvPlot* pLoopPlot;1734 CvPlot* pReturnValuePlot = NULL;17351736 CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eUnit);1737 if(pkUnitInfo == NULL)1738 return pReturnValuePlot;17391740#if defined(MOD_BUGFIX_FREE_RELIGIOUS_UNITS)1741 // If pkUnitInfo is a religious unit AND the player has founded a religion, it MUST be dropped in the player's holy city1742 if ((pkUnitInfo->IsSpreadReligion() || pkUnitInfo->IsRemoveHeresy()) && GetReligions()->HasCreatedReligion()) {1743 CvCity* pHolyCity = GetHolyCity();1744 if (pHolyCity && pHolyCity->getOwner() == GetID()) {1745 // We have a holy city and we still own it1746 pBestPlot = pHolyCity->plot();1747 } else {1748 // Ummm, our holy city either doesn't exist (maybe a mod razed it), or it belongs to someone else, better just drop this dude in the capital1749 pBestPlot = getCapitalCity()->plot();1750 }1751 }1752#endif17531754 if(GC.getGame().isOption(GAMEOPTION_ONE_CITY_CHALLENGE) && isHuman())1755 {1756 if((eUnitAI == UNITAI_SETTLE) || (pkUnitInfo->GetDefaultUnitAIType() == UNITAI_SETTLE))1757 {1758 if(GetNumUnitsWithUnitAI(UNITAI_SETTLE) >= 1)1759 {1760 return pReturnValuePlot;1761 }1762 }1763 }17641765 // slewis1766 // If we're Venice1767 if (GetPlayerTraits()->IsNoAnnexing())1768 {1769 // if we're trying to drop a settler1770 if((eUnitAI == UNITAI_SETTLE) || (pkUnitInfo->GetDefaultUnitAIType() == UNITAI_SETTLE))1771 {1772 // if we already have a settler1773 if(GetNumUnitsWithUnitAI(UNITAI_SETTLE) >= 1)1774 {1775 // drop a merchant of venice instead1776 // find the eUnit replacement that's the merchant of venice1777 for(int iI = 0; iI < GC.getNumUnitClassInfos(); iI++)1778 {1779 const UnitClassTypes eUnitClass = static_cast<UnitClassTypes>(iI);1780 CvUnitClassInfo* pkUnitClassInfo = GC.getUnitClassInfo(eUnitClass);1781 if(pkUnitClassInfo)1782 {1783 const UnitTypes eLocalUnit = (UnitTypes) getCivilizationInfo().getCivilizationUnits(eUnitClass);1784 if (eLocalUnit != NO_UNIT)1785 {1786 CvUnitEntry* pUnitEntry = GC.getUnitInfo(eLocalUnit);1787 if (pUnitEntry->IsCanBuyCityState())1788 {1789 // replacing the parameters1790 eUnit = eLocalUnit;1791 eUnitAI = (UnitAITypes)pkUnitInfo->GetDefaultUnitAIType();1792 break;1793 }1794 }1795 }1796 }1797 }1798 } 1799 }18001801 CvCity* pCapital = getCapitalCity();18021803 if(pCapital)1804 {1805 pStartingPlot = pCapital->plot();1806 }1807 else1808 {1809 pStartingPlot = getStartingPlot();1810 }18111812 if(pStartingPlot != NULL)1813 {1814#if defined(MOD_BUGFIX_FREE_RELIGIOUS_UNITS)1815 // If pBestPlot is not NULL, don't do any of this, as we have already determined the best plot1816 if (pBestPlot == NULL) {1817#else1818 pBestPlot = NULL;1819#endif18201821 if (isHuman())1822 {1823 if (!(pkUnitInfo->IsFound()))1824 {1825 DirectionTypes eDirection;18261827 bool bDirectionValid;18281829 int iCount = 0;18301831 // Find a random direction1832 do1833 {1834 bDirectionValid = true;18351836 eDirection = (DirectionTypes)GC.getGame().getJonRandNum(NUM_DIRECTION_TYPES, "Placing Starting Units (Human)");18371838 if (bDirectionValid)1839 {1840 pLoopPlot = plotDirection(pStartingPlot->getX(), pStartingPlot->getY(), eDirection);18411842#if defined(MOD_BUGFIX_NAVAL_FREE_UNITS)1843 if (pkUnitInfo->GetDomainType() == DOMAIN_SEA) {1844 if (pLoopPlot != NULL && pLoopPlot->isWater()) {1845 if (!pLoopPlot->isImpassable()) {1846 if (!(pLoopPlot->isUnit())) {1847 pBestPlot = pLoopPlot;1848 break;1849 }1850 }1851 }1852 }1853 else {1854#endif1855 if (pLoopPlot != NULL && pLoopPlot->getArea() == pStartingPlot->getArea())1856 {1857 if (!pLoopPlot->isImpassable() && !pLoopPlot->isMountain())1858 {1859 if (!(pLoopPlot->isUnit()))1860 {1861 if (!(pLoopPlot->isGoody()))1862 {1863 pBestPlot = pLoopPlot;1864 break;1865 }1866 }1867 }1868 }1869#if defined(MOD_BUGFIX_NAVAL_FREE_UNITS)1870 }1871#endif1872 }18731874 // Emergency escape. Should only really break on Debug Micro map or something really funky1875 iCount++;1876 } while (iCount < 1000);1877 }1878 }18791880 if (pBestPlot == NULL)1881 {1882 pBestPlot = pStartingPlot;1883 }1884#if defined(MOD_BUGFIX_FREE_RELIGIOUS_UNITS)1885 }1886#endif18871888 CvUnit* pNewUnit = initUnit(eUnit, pBestPlot->getX(), pBestPlot->getY(), eUnitAI);1889 CvAssert(pNewUnit != NULL);1890 if (pNewUnit == NULL)1891 return NULL;18921893 // Don't stack any units1894 if(pBestPlot->getNumUnits() > 1)1895 {1896 if (!pNewUnit->jumpToNearestValidPlot())1897 {1898 // Could not find a spot for the unit1899 pNewUnit->kill(false); 1900 return NULL;1901 }1902 }1903 pReturnValuePlot = pNewUnit->plot();1904 }19051906 return pReturnValuePlot;1907}