Hooks
static bool BeforeCvPlayer_pushResearch(CvPlayer* self, TechTypes eTech, bool bClear, bool& result);static void AfterCvPlayer_pushResearch(CvPlayer* self, TechTypes eTech, bool bClear, bool& result);static bool ReplaceCvPlayer_pushResearch(bool (*original)(CvPlayer*, TechTypes, bool), CvPlayer* self, TechTypes eTech, bool bClear);CivRegisterBefore<CivHooks::CvPlayer_pushResearch>(host, &BeforeCvPlayer_pushResearch);CivRegisterAfter<CivHooks::CvPlayer_pushResearch>(host, &AfterCvPlayer_pushResearch);CivRegisterReplace<CivHooks::CvPlayer_pushResearch>(host, &ReplaceCvPlayer_pushResearch);
Code
21518// Pushes research onto the queue. If it is an append if will put it21519// and its pre-reqs into the queue. If it is not an append it will change21520// research immediately and should be used with clear. Clear will clear the entire queue.21521bool CvPlayer::pushResearch(TechTypes eTech, bool bClear)21522{21523 int i;21524 int iNumSteps;21525 int iShortestPath;21526 bool bOrPrereqFound;21527 TechTypes ePreReq;21528 TechTypes eShortestOr;2152921530 CvAssertMsg(eTech != NO_TECH, "Tech is not assigned a valid value");2153121532 CvTechEntry* pkTechInfo = GC.getTechInfo(eTech);21533 if(pkTechInfo == NULL)21534 return false;215352153621537 if(GET_TEAM(getTeam()).GetTeamTechs()->HasTech(eTech) || m_pPlayerTechs->IsResearchingTech(eTech))21538 {21539 // We have this tech, no reason to add this to the pre-reqs21540 return true;21541 }2154221543 if(!GetPlayerTechs()->CanEverResearch(eTech))21544 {21545 return false;21546 }2154721548 // Pop the entire queue...21549 if(bClear)21550 {21551 clearResearchQueue();21552 }2155321554 // Add in all the pre-reqs for the and techs...21555 for(i = 0; i < GC.getNUM_AND_TECH_PREREQS(); i++)21556 {21557 ePreReq = (TechTypes)pkTechInfo->GetPrereqAndTechs(i);2155821559 if(ePreReq != NO_TECH)21560 {21561 if(!pushResearch(ePreReq))21562 {21563 return false;21564 }21565 }21566 }2156721568 // Will return the shortest path of all the or techs. Tie breaker goes to the first one...21569 eShortestOr = NO_TECH;21570 iShortestPath = INT_MAX;21571 bOrPrereqFound = false;21572 // Cycle through all the OR techs21573 for(i = 0; i < GC.getNUM_OR_TECH_PREREQS(); i++)21574 {21575 ePreReq = (TechTypes)pkTechInfo->GetPrereqOrTechs(i);2157621577 if(ePreReq != NO_TECH)21578 {21579 bOrPrereqFound = true;2158021581 // If the pre-req exists, and we have it, it is the shortest path, get out, we're done21582 if(GET_TEAM(getTeam()).GetTeamTechs()->HasTech(ePreReq))21583 {21584 eShortestOr = ePreReq;21585 break;21586 }2158721588 if(GetPlayerTechs()->CanEverResearch(ePreReq))21589 {21590 // Find the length of the path to this pre-req21591 iNumSteps = findPathLength(ePreReq);2159221593 // If this pre-req is a valid tech, and its the shortest current path, set it as such21594 if(iNumSteps < iShortestPath)21595 {21596 eShortestOr = ePreReq;21597 iShortestPath = iNumSteps;21598 }21599 }21600 }21601 }2160221603 // If the shortest path tech is valid, push it (and its children) on to the research queue recursively21604 if(eShortestOr != NO_TECH)21605 {21606 if(!pushResearch(eShortestOr))21607 {21608 return false;21609 }21610 }21611 else if(bOrPrereqFound)21612 {21613 return false;21614 }2161521616 // Insert this tech at the end of the queue21617 m_researchQueue.insertAtEnd(eTech);2161821619 setResearchingTech(eTech, true);2162021621 // Set the dirty bits21622 if(getTeam() == GC.getGame().getActiveTeam())21623 {21624 GC.GetEngineUserInterface()->setDirty(ResearchButtons_DIRTY_BIT, true);21625 GC.GetEngineUserInterface()->setDirty(GameData_DIRTY_BIT, true);21626 GC.GetEngineUserInterface()->setDirty(Score_DIRTY_BIT, true);21627 }21628 return true;21629}