void CASW_Campaign_Save::VoteEnded() { if (!ASWGameRules()) return; if (!ASWGameRules()->GetCampaignInfo()) return; Msg("CampVote ended\n"); m_bNextMissionVoteEnded = true; CASW_Campaign_Info *pCI = ASWGameRules()->GetCampaignInfo(); // decide which mission to launch // find the highest voted launchable, int iHighestMission = -1; int iHighestVotes = -1; CUtlVector<int> Draws; for (int i=0;i<pCI->GetNumMissions();i++) { //CASW_Campaign_Info::CASW_Campaign_Mission_t* pMission = pCI-> if (m_MissionComplete[i] != 0) // already complete continue; if (!IsMissionLinkedToACompleteMission(i, pCI) || i <= 0) // launchable continue; if (m_NumVotes[i] > iHighestVotes) { iHighestVotes = m_NumVotes[i]; Draws.Purge(); Draws.AddToTail(i); iHighestMission = i; } else if (m_NumVotes[i] == iHighestVotes) { Draws.AddToTail(i); } } int iMission = iHighestMission; Msg("highest mission is %d draws is %d\n", iMission, Draws.Count()); if (Draws.Count() > 1) { // some missions have equal votes, pick one at random int iPick = random->RandomInt(0, Draws.Count() - 1); iMission = Draws[iPick]; } Msg("Moving to %d\n", iMission); // move there ASWGameRules()->RequestCampaignMove(iMission); }
void CASW_Campaign_Save::SelectDefaultNextCampaignMission() { if ( !ASWGameRules() || !ASWGameResource() ) return; CASW_Campaign_Info *pInfo = ASWGameRules()->GetCampaignInfo(); if ( !pInfo ) return; // find the first valid mission selection in our list for ( int i = 1; i < pInfo->GetNumMissions(); i++ ) // skip first dummy entry { if ( !m_MissionComplete[i] && IsMissionLinkedToACompleteMission( i, pInfo ) ) { ASWGameResource()->m_iNextCampaignMission = i; return; } } }
bool CASW_Campaign_Save::BuildCampaignRoute(int iStart, int iEnd) { if (!ASWGameRules() || !ASWGameRules()->GetCampaignInfo()) return false; CASW_Campaign_Info *pCI = ASWGameRules()->GetCampaignInfo(); if (iStart < 0 || iStart >= pCI->GetNumMissions()) return false; if (iEnd < 0 || iEnd >= pCI->GetNumMissions()) return false; // do A* m_ClosedList.Purge(); m_OpenList.Purge(); m_iRouteDest = iEnd; m_iRouteStart = iStart; // add starting mission to the open list campaign_route_node_t start_node; start_node.iMission = iStart; start_node.iParentMission = iStart; start_node.g = 0; start_node.h = EstimateCost(pCI, iStart, iEnd); start_node.f = start_node.g + start_node.h; m_OpenList.AddToTail(start_node); int iOverflow = 0; while (iOverflow < 1000) { // find the lowest node on the open list int iLowestF = -1; float fLowestF_Value = 99999; //Msg("%d nodes in open list\n", m_OpenList.Count()); for (int i=0;i<m_OpenList.Count();i++) { if (m_OpenList[i].f < fLowestF_Value) { //Msg(" and node %d is lower than lowest\n", i); fLowestF_Value = m_OpenList[i].f; iLowestF = i; } } // if open list is empty, that means we've searched all routes and still didn't arrive at the dest if (iLowestF == -1) { //Msg("Failed to find route\n"); return false; } // move it to the closed list int iCurrentMission = m_OpenList[iLowestF].iMission; float fCurrentCost = m_OpenList[iLowestF].f; m_ClosedList.AddToTail(m_OpenList[iLowestF]); m_OpenList.Remove(iLowestF); if (iCurrentMission == iEnd) // found the target { //Msg("current mission is the destination!\n"); return true; } //Msg("Current mission is %d, open list size %d closed list size %d\n", iCurrentMission, m_OpenList.Count(), m_ClosedList.Count()); // check all linked missions CASW_Campaign_Info::CASW_Campaign_Mission_t *pMission = pCI->GetMission(iCurrentMission); if (!pMission) { //Msg("Failed to get current mission in BuildCampaignRoute\n"); return false; } //Msg("Current mission (%d) has %d links\n", iCurrentMission, pMission->m_Links.Count()); for (int i=0;i<pMission->m_Links.Count();i++) { int iOtherMission = pMission->m_Links[i]; //Msg("other mission[%d] is %d\n", i, iOtherMission); CASW_Campaign_Info::CASW_Campaign_Mission_t *pOtherMission = pCI->GetMission(pMission->m_Links[i]); if (!pOtherMission) continue; // check if it's on the open list int iOnOpenList = -1; for (int k=0;k<m_OpenList.Count();k++) { if (m_OpenList[k].iMission == iOtherMission) { //Msg("Other mission (%d) is on the open list\n", iOtherMission); iOnOpenList = k; break; } } // if not, check if it's already on the closed list if (iOnOpenList == -1) { int iOnClosedList = -1; for (int k=0;k<m_ClosedList.Count();k++) { if (m_ClosedList[k].iMission == iOtherMission) { //Msg("Other mission (%d) is on the closed list already, so ignoring\n", iOtherMission); iOnClosedList = k; break; } } if (iOnClosedList != -1) { continue; } } // if not, add it and calculate costs if (iOnOpenList == -1) { //Msg("other mission %d not on the open list, so adding it...", iOtherMission); campaign_route_node_t new_node; new_node.iMission = iOtherMission; new_node.iParentMission = iCurrentMission; new_node.g = fCurrentCost + EstimateCost(pCI, iCurrentMission, iOtherMission); // actual cost from start to here new_node.h = EstimateCost(pCI, iOtherMission, iEnd); new_node.f = new_node.g + new_node.h; m_OpenList.AddToTail(new_node); } else // if it is, check if going there from us is cheaper, if so update parent and costs { //Msg("other mission %d already on open list, checking costs\n", iOtherMission); float my_g_cost = fCurrentCost + EstimateCost(pCI, iCurrentMission, iOtherMission); if (my_g_cost < m_OpenList[iOnOpenList].g) { m_OpenList[iOnOpenList].iParentMission = iCurrentMission; m_OpenList[iOnOpenList].g = my_g_cost; m_OpenList[iOnOpenList].f = m_OpenList[iOnOpenList].g + m_OpenList[iOnOpenList].h; } } } iOverflow++; } //Msg("Error, BuildCampaignRoute overflow!\n"); return false; }