//------------------------------------------------------------------------------
void CvDllNetMessageHandler::ResponseResearch(PlayerTypes ePlayer, TechTypes eTech, int iDiscover, PlayerTypes ePlayerToStealFrom, bool bShift)
{
	CvPlayerAI& kPlayer = GET_PLAYER(ePlayer);
	CvTeam& kTeam = GET_TEAM(kPlayer.getTeam());

	// Free tech
	if(iDiscover > 0)
	{
		// Make sure we can research this tech for free
		if(kPlayer.GetPlayerTechs()->CanResearchForFree(eTech))
		{
			kTeam.setHasTech(eTech, true, ePlayer, true, true);

			if(iDiscover > 1)
			{
				if(ePlayer == GC.getGame().getActivePlayer())
				{
					kPlayer.chooseTech(iDiscover - 1);
				}
			}
			kPlayer.SetNumFreeTechs(max(0, iDiscover - 1));
		}
	}
	// Stealing tech
	else if(ePlayerToStealFrom != NO_PLAYER)
	{
		// make sure we can still take a tech
		CvAssertMsg(kPlayer.GetEspionage()->m_aiNumTechsToStealList[ePlayerToStealFrom] > 0, "No techs to steal from player");
		CvAssertMsg(kPlayer.GetEspionage()->m_aaPlayerStealableTechList[ePlayerToStealFrom].size() > 0, "No techs to be stolen from this player");
		CvAssertMsg(kPlayer.GetPlayerTechs()->CanResearch(eTech), "Player can't research this technology");
		CvAssertMsg(GET_TEAM(GET_PLAYER(ePlayerToStealFrom).getTeam()).GetTeamTechs()->HasTech(eTech), "ePlayerToStealFrom does not have the requested tech");
		if (kPlayer.GetEspionage()->m_aiNumTechsToStealList[ePlayerToStealFrom] > 0)
		{
			kTeam.setHasTech(eTech, true, ePlayer, true, true);
			kPlayer.GetEspionage()->m_aiNumTechsToStealList[ePlayerToStealFrom]--;
		}
	}
	// Normal tech
	else
	{
		CvPlayerTechs* pPlayerTechs = kPlayer.GetPlayerTechs();
		CvTeamTechs* pTeamTechs = kTeam.GetTeamTechs();

		if(eTech == NO_TECH)
		{
			kPlayer.clearResearchQueue();
		}
		else if(pPlayerTechs->CanEverResearch(eTech))
		{
			if((pTeamTechs->HasTech(eTech) || pPlayerTechs->IsResearchingTech(eTech)) && !bShift)
			{
				kPlayer.clearResearchQueue();
			}

			kPlayer.pushResearch(eTech, !bShift);
		}
	}
}
예제 #2
0
//------------------------------------------------------------------------------
bool CvDllPlayer::GetCurrentResearchTech(TechTypes* pkTech, int *pkTurnsLeft) const
{
	CvPlayerTechs* pkTechs = m_pPlayer->GetPlayerTechs();
	if (pkTechs)
	{
		if (pkTech)
			*pkTech = pkTechs->GetCurrentResearch();
		if (pkTurnsLeft)
			*pkTurnsLeft = pkTechs->GetResearchTurnsLeft(pkTechs->GetCurrentResearch(), false);
		return true;
	}
	return false;
}
예제 #3
0
void CvAdvisorRecommender::UpdateTechRecommendations (PlayerTypes ePlayer)
{
	ResetTechs();
	CvPlayerTechs* pPlayerTechs = GET_PLAYER(ePlayer).GetPlayerTechs();
	CvTechAI* pPlayerTechAI = pPlayerTechs->GetTechAI();

	RandomNumberDelegate fcn;
	int iTechLoop;

	// Use the synchronous random number generate
	// Asynchronous one would be:
	fcn = MakeDelegate (&GC.getGame(), &CvGame::getAsyncRandNum);
	//fcn = MakeDelegate (&GC.getGame(), &CvGame::getJonRandNum);

	// Loop through adding the researchable techs
	for (iTechLoop = 0; iTechLoop < pPlayerTechs->GetTechs()->GetNumTechs(); iTechLoop++)
	{
		TechTypes eTech = (TechTypes)iTechLoop;
		if (pPlayerTechs->CanResearch(eTech))
		{
			m_aResearchableTechs.push_back (iTechLoop, pPlayerTechAI->GetWeight(eTech));
		}
	}

	// weigh by cost
	for (int iI = 0; iI < m_aResearchableTechs.size(); iI++)
	{
		TechTypes eTech = (TechTypes) m_aResearchableTechs.GetElement(iI);
		int iTurnsLeft = 0;

		iTurnsLeft = pPlayerTechs->GetResearchTurnsLeft(eTech, true);

		double fWeightDivisor;

		// 10 turns will add 0.02; 80 turns will add 0.16
		double fAdditionalTurnCostFactor = GC.getAI_RESEARCH_WEIGHT_MOD_PER_TURN_LEFT() * iTurnsLeft;	// 0.015
		double fTotalCostFactor = GC.getAI_RESEARCH_WEIGHT_BASE_MOD() + fAdditionalTurnCostFactor;	// 0.15

		fWeightDivisor = pow((double) iTurnsLeft, fTotalCostFactor);

		// if the tech is free, then we don't want inverse the weighting. More expensive techs = better.
		int iNewWeight = 0;
		if (GET_PLAYER(ePlayer).GetNumFreeTechs() == 0)
		{
			iNewWeight = int(double(m_aResearchableTechs.GetWeight(iI)) / fWeightDivisor);
		}
		else
		{
			iNewWeight = m_aResearchableTechs.GetWeight(iI) * max(iTurnsLeft / 2, 1);
		}

		// Now actually change the weight
		m_aResearchableTechs.SetWeight(iI, iNewWeight);
	}

	m_aResearchableTechs.SortItems();

	// move techs into final round!
	for (int i = 0; i < NUM_ADVISOR_TYPES; i++)
	{
		// if index is out of bounds
		if (i >= m_aResearchableTechs.size())
		{
			break;
		}

		m_aFinalRoundTechs.push_back(m_aResearchableTechs.GetElement(i), m_aResearchableTechs.GetWeight(i));
	}

	for (int i = 0; i < m_aFinalRoundTechs.size(); i++)
	{
		m_aFinalRoundTechs.SortItems();

		TechTypes eTech = (TechTypes)m_aFinalRoundTechs.GetElement(0);
		int iScore = m_aFinalRoundTechs.GetWeight(0);

		AdvisorTypes eAvailableAdvisor = FindUnassignedAdvisorForTech(ePlayer, eTech);
		if (eAvailableAdvisor != NO_ADVISOR_TYPE)
		{
			m_aRecommendedTechs[eAvailableAdvisor] = eTech;
		}

		m_aFinalRoundTechs.SetWeight(0, iScore / 2);
	}
}