Bazaar developer reference

CvPlayer::canReceiveGoody(CvPlot *, GoodyTypes, CvUnit *) const

Defined in
CvPlayer.cpp, line 6316
Class
CvPlayer
Hook name
CivHooks::CvPlayer_canReceiveGoody
Lua events
GameEvents.GoodyHutCanNotReceive, GameEvents.GoodyHutCanResearch

Hooks

static bool BeforeCvPlayer_canReceiveGoody(const CvPlayer* self, CvPlot* pPlot, GoodyTypes eGoody, CvUnit* pUnit, bool& result);static void AfterCvPlayer_canReceiveGoody(const CvPlayer* self, CvPlot* pPlot, GoodyTypes eGoody, CvUnit* pUnit, bool& result);static bool ReplaceCvPlayer_canReceiveGoody(bool (*original)(const CvPlayer*, CvPlot*, GoodyTypes, CvUnit*), const CvPlayer* self, CvPlot* pPlot, GoodyTypes eGoody, CvUnit* pUnit);CivRegisterBefore<CivHooks::CvPlayer_canReceiveGoody>(host, &BeforeCvPlayer_canReceiveGoody);CivRegisterAfter<CivHooks::CvPlayer_canReceiveGoody>(host, &AfterCvPlayer_canReceiveGoody);CivRegisterReplace<CivHooks::CvPlayer_canReceiveGoody>(host, &ReplaceCvPlayer_canReceiveGoody);

Code

6315/// Is a Particular Goody ID a valid Goody for a certain plot?6316bool CvPlayer::canReceiveGoody(CvPlot* pPlot, GoodyTypes eGoody, CvUnit* pUnit) const6317{6318	CvCity* pCity;6319	UnitTypes eUnit;6320	bool bTechFound;6321	int iI;63226323	Database::SingleResult kResult;6324	CvGoodyInfo kGoodyInfo;6325	const bool bResult = DB.SelectAt(kResult, "GoodyHuts", eGoody);6326	DEBUG_VARIABLE(bResult);6327	CvAssertMsg(bResult, "Cannot find goody info.");6328	kGoodyInfo.CacheResult(kResult);63296330#if defined(MOD_EVENTS_GOODY_CHOICE)6331	if (MOD_EVENTS_GOODY_CHOICE) {6332		bool bPick = (pUnit && pUnit->isHasPromotion((PromotionTypes)GC.getPROMOTION_GOODY_HUT_PICKER()));6333		int iUnit = pUnit ? pUnit->GetID() : -1;6334		if (GAMEEVENTINVOKE_TESTANY(GAMEEVENT_GoodyHutCanNotReceive, GetID(), iUnit, eGoody, bPick) == GAMEEVENTRETURN_TRUE) {6335			return false;6336		}6337	}6338#endif63396340	if(!CvGoodyHuts::IsCanPlayerReceiveGoody(GetID(), eGoody))6341	{6342		return false;6343	}63446345	// No XP in first 10 turns6346	if(kGoodyInfo.getExperience() > 0)6347	{6348		if((pUnit == NULL) || !(pUnit->canAcquirePromotionAny()) || (GC.getGame().getElapsedGameTurns() < 10))6349		{6350			return false;6351		}6352	}63536354	// Unit Healing6355	if(kGoodyInfo.getDamagePrereq() > 0)6356	{6357		if((pUnit == NULL) || (pUnit->getDamage() < ((pUnit->GetMaxHitPoints() * kGoodyInfo.getDamagePrereq()) / 100)))6358		{6359			return false;6360		}6361	}63626363	// Early pantheon6364	if(kGoodyInfo.isPantheonFaith())6365	{6366		if(GC.getGame().getElapsedGameTurns() < 20)6367		{6368			return false;6369		}6370		else6371		{6372			return (!GetReligions()->HasCreatedPantheon() && !GetReligions()->HasCreatedReligion());6373		}6374	}63756376	// Faith toward Great Prophet6377	if(kGoodyInfo.getProphetPercent() > 0)6378	{6379		if(GC.getGame().getElapsedGameTurns() < 20)6380		{6381			return false;6382		}6383		else6384		{6385			return (GetReligions()->HasCreatedPantheon() && !GetReligions()->HasCreatedReligion());6386		}6387	}63886389	// Population6390	if(kGoodyInfo.getPopulation() > 0)6391	{6392		if(getNumCities() == 0)6393		{6394			return false;6395		}63966397		// Don't give more Population if we're already over our Pop limit6398		if(IsEmpireUnhappy())6399		{6400			return false;6401		}6402	}64036404	// Reveal Nearby Barbs6405	if(kGoodyInfo.getRevealNearbyBarbariansRange() > 0)6406	{6407		int iDX, iDY;6408		int iBarbCampDistance = kGoodyInfo.getRevealNearbyBarbariansRange();6409		CvPlot* pNearbyPlot;64106411		int iNumCampsFound = 0;64126413		ImprovementTypes barbCampType = (ImprovementTypes) GC.getBARBARIAN_CAMP_IMPROVEMENT();64146415		// Look at nearby Plots to make sure another camp isn't too close6416		for(iDX = -(iBarbCampDistance); iDX <= iBarbCampDistance; iDX++)6417		{6418			for(iDY = -(iBarbCampDistance); iDY <= iBarbCampDistance; iDY++)6419			{6420				pNearbyPlot = plotXY(pPlot->getX(), pPlot->getY(), iDX, iDY);64216422				if(pNearbyPlot != NULL)6423				{6424					if(plotDistance(pNearbyPlot->getX(), pNearbyPlot->getY(), pPlot->getX(), pPlot->getY()) <= iBarbCampDistance)6425					{6426						if(pNearbyPlot->getImprovementType() == barbCampType)6427						{6428							iNumCampsFound++;6429						}6430					}6431				}6432			}6433		}64346435		// Needs to be at least 2 nearby Camps6436		if(iNumCampsFound < 2)6437		{6438			return false;6439		}6440	}64416442	// Reveal Unknown Resource6443	if(kGoodyInfo.isRevealUnknownResource())6444	{6445		// Can't get this if you have no Capital City6446		if(getCapitalCity() == NULL)6447		{6448			return false;6449		}64506451		CvResourceInfo* pResource;6452		ResourceClassTypes eResourceClassBonus = (ResourceClassTypes) GC.getInfoTypeForString("RESOURCECLASS_BONUS");64536454		bool bPlayerDoesntKnowOfResource = false;64556456		int iNumResourceInfos = GC.getNumResourceInfos();6457		for(int iResourceLoop = 0; iResourceLoop < iNumResourceInfos; iResourceLoop++)6458		{6459			pResource = GC.getResourceInfo((ResourceTypes) iResourceLoop);64606461			// No "Bonus" Resources (that only give Yield), because those are lame to get from a Hut6462			if(pResource != NULL && pResource->getResourceClassType() != eResourceClassBonus)6463			{6464				if(!GET_TEAM(getTeam()).GetTeamTechs()->HasTech((TechTypes) pResource->getTechReveal()))6465				{6466					bPlayerDoesntKnowOfResource = true;6467				}6468			}6469		}64706471		// If the player already knows where all the Resources are then there's no point in this Goody6472		if(!bPlayerDoesntKnowOfResource)6473		{6474			return false;6475		}6476	}64776478	// Unit Upgrade6479	if(kGoodyInfo.isUpgradeUnit())6480	{6481		if(pUnit == NULL)6482		{6483			return false;6484		}64856486		if(pUnit->IsHasBeenPromotedFromGoody())6487		{6488			return false;6489		}64906491		UnitClassTypes eUpgradeUnitClass = (UnitClassTypes) GC.getUnitInfo(pUnit->getUnitType())->GetGoodyHutUpgradeUnitClass();64926493		if(eUpgradeUnitClass == NO_UNITCLASS)6494		{6495			return false;6496		}64976498		UnitTypes eUpgradeUnit = (UnitTypes) getCivilizationInfo().getCivilizationUnits(eUpgradeUnitClass);64996500		if(eUpgradeUnit == NO_UNIT)6501		{6502			return false;6503		}6504	}65056506	// Tech6507	if(kGoodyInfo.isTech())6508	{6509		bTechFound = false;65106511		int iNumTechInfos = GC.getNumTechInfos();6512		for(iI = 0; iI < iNumTechInfos; iI++)6513		{6514			const TechTypes eTech = static_cast<TechTypes>(iI);6515			CvTechEntry* pkTech = GC.getTechInfo(eTech);6516			if(pkTech != NULL && pkTech->IsGoodyTech())6517			{6518				if(GetPlayerTechs()->CanResearch(eTech))6519				{6520					bool bUseTech = true;6521					ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();6522					if (pkScriptSystem) 6523					{6524						CvLuaArgsHandle args;6525						args->Push(GetID());6526						args->Push(eTech);65276528						// Attempt to execute the game events.6529						// Will return false if there are no registered listeners.6530						bool bScriptResult = false;6531						if (LuaSupport::CallTestAll(pkScriptSystem, "GoodyHutCanResearch", args.get(), bScriptResult)) 6532						{6533							bUseTech = bResult;6534						}6535					}65366537					if(bUseTech)6538					{6539						bTechFound = true;6540					}6541					break;6542				}6543			}6544		}65456546		if(!bTechFound)6547		{6548			return false;6549		}6550	}65516552	///////////////////////////////////////6553	///////////////////////////////////////6554	// Bad Goodies follow beneath this line6555	///////////////////////////////////////6556	///////////////////////////////////////65576558	if(kGoodyInfo.isBad())6559	{6560		if((pUnit == NULL) || pUnit->isNoBadGoodies())6561		{6562			return false;6563		}6564	}65656566	if(kGoodyInfo.getUnitClassType() != NO_UNITCLASS)6567	{6568		eUnit = ((UnitTypes)(getCivilizationInfo().getCivilizationUnits(kGoodyInfo.getUnitClassType())));65696570		if(eUnit == NO_UNIT)6571		{6572			return false;6573		}65746575		CvUnitEntry* pUnitInfo = GC.getUnitInfo(eUnit);6576		if(pUnitInfo == NULL)6577		{6578			return false;6579		}65806581		// No combat units in MP in the first 20 turns6582		if(pUnitInfo->GetCombat() > 0)6583		{6584			if(GC.getGame().isGameMultiPlayer() || (GC.getGame().getElapsedGameTurns() < 20))6585			{6586				return false;6587			}6588		}65896590		// Builders6591		if(pUnitInfo->GetWorkRate() > 0)6592		{6593			// Max limit6594			if(GetMaxNumBuilders() > -1 && GetNumBuilders() >= GetMaxNumBuilders())6595			{6596				return false;6597			}65986599			bool bHasTechWhichUnlocksImprovement = false;66006601			// Need a tech which unlocks something to do6602			int iNumTechInfos = GC.getNumTechInfos();6603			int iNumBuildInfos = GC.getNumBuildInfos();6604			for(int iTechLoop = 0; iTechLoop < iNumTechInfos; iTechLoop++)6605			{6606				if(GET_TEAM(getTeam()).GetTeamTechs()->HasTech((TechTypes) iTechLoop))6607				{6608					// Look at Builds6609					for(int iBuildLoop = 0; iBuildLoop < iNumBuildInfos; iBuildLoop++)6610					{6611						CvBuildInfo* pkBuildInfo = GC.getBuildInfo((BuildTypes) iBuildLoop);6612						if(!pkBuildInfo)6613						{6614							continue;6615						}6616						if(pkBuildInfo->getTechPrereq() == (TechTypes) iTechLoop)6617						{6618							if(pkBuildInfo->getImprovement() != NO_IMPROVEMENT || pkBuildInfo->getRoute() != NO_ROUTE)6619							{6620								bHasTechWhichUnlocksImprovement = true;6621								break;6622							}6623						}6624					}6625				}6626				// Already found something6627				if(bHasTechWhichUnlocksImprovement)6628				{6629					break;6630				}6631			}66326633			// Player doesn't have any Tech which allows Improvements6634			if(!bHasTechWhichUnlocksImprovement)6635			{6636				return false;6637			}6638		}66396640		// OCC games - no Settlers6641		if(GetPlayerTraits()->IsNoAnnexing() || (GC.getGame().isOption(GAMEOPTION_ONE_CITY_CHALLENGE) && isHuman()))6642		{6643			if(pUnitInfo->IsFound() || pUnitInfo->IsFoundAbroad())6644			{6645				return false;6646			}6647		}6648	}66496650	// Barbarians6651	if(kGoodyInfo.getBarbarianUnitClass() != NO_UNITCLASS)6652	{6653		if(GC.getGame().isOption(GAMEOPTION_NO_BARBARIANS))6654		{6655			return false;6656		}66576658		if(getNumCities() == 0)6659		{6660			return false;6661		}66626663		if(getNumCities() == 1)6664		{6665			pCity = GC.getMap().findCity(pPlot->getX(), pPlot->getY(), NO_PLAYER, getTeam());66666667			if(pCity != NULL)6668			{6669				if(plotDistance(pPlot->getX(), pPlot->getY(), pCity->getX(), pCity->getY()) <= (8 - getNumCities()))6670				{6671					return false;6672				}6673			}6674		}6675	}66766677	return true;6678}

Calls

Called by