diff --git a/include/core.h b/include/core.h index 34dd0a8..44305a7 100644 --- a/include/core.h +++ b/include/core.h @@ -636,6 +636,7 @@ struct ExperienceSave // bot creation tab struct CreateQueue { + bool console; int difficulty; int team; int member; @@ -1203,9 +1204,8 @@ public: void TryHeadTowardRadioEntity (void); void Kill (void); - void Kick (void); + void Kick (bool keepQuota = false); void ResetDoubleJumpState (void); - void MoveToVector (const Vector &to); int FindPlantedBomb(void); bool HasHostage (void); @@ -1248,7 +1248,7 @@ private: edict_t *m_killerEntity; // killer entity for bots protected: - int CreateBot (const String &name, int difficulty, int personality, int team, int member); + int CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd); public: BotManager (void); @@ -1280,13 +1280,13 @@ public: void Free (void); void Free (int index); - void AddRandom (void) { AddBot ("", -1, -1, -1, -1); } - void AddBot (const String &name, int difficulty, int personality, int team, int member); - void AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member); + void AddRandom (bool isConsoleCmd = true) { AddBot ("", -1, -1, -1, -1, isConsoleCmd); } + void AddBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd = true); + void AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member, bool isConsoleCmd = true); void FillServer (int selection, int personality = PERSONALITY_NORMAL, int difficulty = -1, int numToAdd = -1); - void RemoveAll (bool zeroQuota = true); - void RemoveRandom (void); + void RemoveAll (void); + void RemoveRandom (bool keepQuota = false); void RemoveFromTeam (Team team, bool removeAll = false); void RemoveMenu (edict_t *ent, int selection); void KillAll (int team = -1); diff --git a/include/engine.h b/include/engine.h index b709e28..db07e47 100644 --- a/include/engine.h +++ b/include/engine.h @@ -318,7 +318,7 @@ public: FORCEINLINE int GetInt (void) { return static_cast (m_eptr->value); } FORCEINLINE float GetFloat (void) { return m_eptr->value; } FORCEINLINE const char *GetString (void) { return m_eptr->string; } - FORCEINLINE void SetFloat (float val) { m_eptr->value = val; } + FORCEINLINE void SetFloat (float val) { g_engfuncs.pfnCVarSetFloat (m_eptr->name, val); } FORCEINLINE void SetInt (int val) { SetFloat (static_cast (val)); } FORCEINLINE void SetString (const char *val) { g_engfuncs.pfnCvar_DirectSet (m_eptr, const_cast (val)); } }; diff --git a/include/globals.h b/include/globals.h index 5f40d7f..ca8f776 100644 --- a/include/globals.h +++ b/include/globals.h @@ -20,7 +20,6 @@ extern bool g_autoWaypoint; extern bool g_botsCanPause; extern bool g_editNoclip; extern bool g_isMetamod; -extern bool g_sendAudioFinished; extern bool g_isCommencing; extern bool g_leaderChoosen[2]; diff --git a/project/yapb.vcxproj b/project/yapb.vcxproj index 3d9d590..6005c14 100644 --- a/project/yapb.vcxproj +++ b/project/yapb.vcxproj @@ -62,7 +62,7 @@ DynamicLibrary false - v140_xp + v120_xp diff --git a/source/basecode.cpp b/source/basecode.cpp index 239125f..03c1f3c 100644 --- a/source/basecode.cpp +++ b/source/basecode.cpp @@ -984,7 +984,7 @@ void Bot::InstantChatterMessage (int type) { // this function sends instant chatter messages. - if (yb_communication_type.GetInt () != 2 || g_chatterFactory[type].IsEmpty () || (g_gameFlags & GAME_LEGACY) || !g_sendAudioFinished) + if (yb_communication_type.GetInt () != 2 || g_chatterFactory[type].IsEmpty () || (g_gameFlags & GAME_LEGACY)) return; if (m_notKilled) @@ -1009,8 +1009,6 @@ void Bot::InstantChatterMessage (int type) if (!IsValidPlayer (ent) || IsValidBot (ent) || engine.GetTeam (ent) != m_team) continue; - g_sendAudioFinished = false; - MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_SENDAUDIO), NULL, ent); // begin message WRITE_BYTE (GetIndex ()); @@ -1021,8 +1019,6 @@ void Bot::InstantChatterMessage (int type) WRITE_SHORT (m_voicePitch); MESSAGE_END (); - - g_sendAudioFinished = true; } } @@ -1597,7 +1593,7 @@ void Bot::PurchaseWeapons (void) break; case BUYSTATE_SECONDARY_WEAPON: // if bot has still some money, buy a better secondary weapon - if (isPistolMode || (HasPrimaryWeapon () && (pev->weapons & ((1 << WEAPON_USP) | (1 << WEAPON_GLOCK))) && m_moneyAmount > Random.Long (7500, 9000))) + if (false || isPistolMode || (HasPrimaryWeapon () && (pev->weapons & ((1 << WEAPON_USP) | (1 << WEAPON_GLOCK))) && m_moneyAmount > Random.Long (7500, 9000))) { do { @@ -2511,7 +2507,9 @@ void Bot::CheckRadioCommands (void) SelectWeaponByName ("weapon_knife"); DeleteSearchNodes (); - MoveToVector (waypoints.GetBombPosition ()); + + m_position = waypoints.GetBombPosition (); + PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0f, true); RadioMessage (Radio_Affirmative); } @@ -2961,40 +2959,6 @@ void Bot::ThinkFrame (void) engine.IssueBotCommand (GetEntity (), "votemap %d", m_voteMap); m_voteMap = 0; } - extern ConVar yb_chat; - - if (yb_chat.GetBool () && !RepliesToPlayer () && m_lastChatTime + 10.0 < engine.Time () && g_lastChatTime + 5.0f < engine.Time ()) // bot chatting turned on? - { - // say a text every now and then - if (Random.Long (1, 1500) < 2) - { - m_lastChatTime = engine.Time (); - g_lastChatTime = engine.Time (); - - char *pickedPhrase = const_cast (g_chatFactory[CHAT_DEAD].GetRandomElement ().GetBuffer ()); - bool sayBufferExists = false; - - // search for last messages, sayed - FOR_EACH_AE (m_sayTextBuffer.lastUsedSentences, i) - { - if (strncmp (m_sayTextBuffer.lastUsedSentences[i].GetBuffer (), pickedPhrase, m_sayTextBuffer.lastUsedSentences[i].GetLength ()) == 0) - sayBufferExists = true; - } - - if (!sayBufferExists) - { - PrepareChatMessage (pickedPhrase); - PushMessageQueue (GSM_SAY); - - // add to ignore list - m_sayTextBuffer.lastUsedSentences.Push (pickedPhrase); - } - - // clear the used line buffer every now and then - if (m_sayTextBuffer.lastUsedSentences.GetElementNumber () > Random.Long (4, 6)) - m_sayTextBuffer.lastUsedSentences.RemoveAll (); - } - } } else if (m_notKilled && m_buyingFinished && !(pev->maxspeed < 10.0f && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB) && !yb_freeze_bots.GetBool ()) botMovement = true; @@ -3007,7 +2971,7 @@ void Bot::ThinkFrame (void) CheckMessageQueue (); // check for pending messages // remove voice icon - if (g_lastRadioTime[g_clients[engine.IndexOfEntity (GetEntity ()) - 1].team2] + Random.Float (0.8f, 2.1f) < engine.Time ()) + if (!(g_gameFlags & GAME_LEGACY) && g_lastRadioTime[g_clients[GetIndex () - 1].team2] + Random.Float (0.8f, 2.1f) < engine.Time ()) SwitchChatterIcon (false); // hide icon if (botMovement) @@ -3031,6 +2995,41 @@ void Bot::PeriodicThink (void) CheckSpawnTimeConditions (); + extern ConVar yb_chat; + + if (m_notKilled && yb_chat.GetBool () && m_lastChatTime + 10.0 < engine.Time () && g_lastChatTime + 5.0f < engine.Time () && !RepliesToPlayer ()) // bot chatting turned on? + { + // say a text every now and then + if (Random.Long (1, 1500) < 2) + { + m_lastChatTime = engine.Time (); + g_lastChatTime = engine.Time (); + + char *pickedPhrase = const_cast (g_chatFactory[CHAT_DEAD].GetRandomElement ().GetBuffer ()); + bool sayBufferExists = false; + + // search for last messages, sayed + FOR_EACH_AE (m_sayTextBuffer.lastUsedSentences, i) + { + if (strncmp (m_sayTextBuffer.lastUsedSentences[i].GetBuffer (), pickedPhrase, m_sayTextBuffer.lastUsedSentences[i].GetLength ()) == 0) + sayBufferExists = true; + } + + if (!sayBufferExists) + { + PrepareChatMessage (pickedPhrase); + PushMessageQueue (GSM_SAY); + + // add to ignore list + m_sayTextBuffer.lastUsedSentences.Push (pickedPhrase); + } + + // clear the used line buffer every now and then + if (m_sayTextBuffer.lastUsedSentences.GetElementNumber () > Random.Long (4, 6)) + m_sayTextBuffer.lastUsedSentences.RemoveAll (); + } + } + // clear enemy far away if (!m_lastEnemyOrigin.IsZero () && !engine.IsNullEntity (m_lastEnemy) && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0f) { @@ -4374,6 +4373,15 @@ void Bot::RunTask_EscapeFromBomb (void) if (lastSelectedGoal < 0) lastSelectedGoal = waypoints.FindFarest (pev->origin, safeRadius); + // still no luck? + if (lastSelectedGoal < 0) + { + TaskComplete (); // we're done + + // we have no destination point, so just sit down and camp + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + 10.0f, true); + return; + } m_prevGoalIndex = lastSelectedGoal; GetTask ()->data = lastSelectedGoal; @@ -4984,7 +4992,7 @@ void Bot::DisplayDebugOverlay (void) { bool displayDebugOverlay = false; - if (g_hostEntity->v.iuser2 == engine.IndexOfEntity (GetEntity ())) + if (g_hostEntity->v.iuser2 == GetIndex ()) displayDebugOverlay = true; if (!displayDebugOverlay && yb_debug.GetInt () >= 2) @@ -5590,7 +5598,7 @@ void Bot::DebugMsg (const char *format, ...) bool playMessage = false; - if (level == 3 && !engine.IsNullEntity (g_hostEntity) && g_hostEntity->v.iuser2 == engine.IndexOfEntity (GetEntity ())) + if (level == 3 && !engine.IsNullEntity (g_hostEntity) && g_hostEntity->v.iuser2 == GetIndex ()) playMessage = true; else if (level != 3) playMessage = true; @@ -5731,14 +5739,6 @@ Vector Bot::CheckBombAudible (void) return Vector::GetZero (); } -void Bot::MoveToVector (const Vector &to) -{ - if (to.IsZero ()) - return; - - FindPath (m_currentWaypointIndex, waypoints.FindNearest (to), SEARCH_PATH_FASTEST); -} - byte Bot::ThrottledMsec (void) { // estimate msec to use for this command based on time passed from the previous command diff --git a/source/globals.cpp b/source/globals.cpp index 6f4415e..fedb486 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -9,19 +9,11 @@ #include -// forward for super-globals -//NetworkMsg netmsg; -//Localizer locale; -//Waypoint waypoints; -//BotManager bots; -//Engine engine; - bool g_canSayBombPlanted = true; bool g_isMetamod = false; bool g_radioInsteadVoice = false; bool g_roundEnded = true; bool g_botsCanPause = false; -bool g_sendAudioFinished = true; bool g_bombPlanted = false; bool g_bombSayString = false; bool g_isCommencing = false; diff --git a/source/interface.cpp b/source/interface.cpp index c160ba4..41cf928 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -1103,7 +1103,7 @@ void UpdateClientData (const struct edict_s *ent, int sendweapons, struct client { extern ConVar yb_latency_display; - if (yb_latency_display.GetInt () == 2) + if (!(g_gameFlags & GAME_LEGACY) && yb_latency_display.GetInt () == 2) bots.SendPingDataOffsets (const_cast (ent)); if (g_isMetamod) @@ -2452,7 +2452,6 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed // is this message for a bot? if (index != -1 && !(ed->v.flags & FL_DORMANT)) { - engine.ResetMessageCapture (); engine.SetOngoingMessageReceiver (index); // message handling is done in usermsg.cpp @@ -2471,8 +2470,6 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed } else if (msgDest == MSG_ALL) { - engine.ResetMessageCapture (); - engine.TryCaptureMessage (msgType, NETMSG_SCOREINFO); engine.TryCaptureMessage (msgType, NETMSG_DEATH); engine.TryCaptureMessage (msgType, NETMSG_TEXTMSG); @@ -2786,8 +2783,10 @@ void pfnAlertMessage (ALERT_TYPE alertType, char *format, ...) if (bot != NULL && bot->m_team == TERRORIST && bot->m_notKilled) { - bot->ResetTasks (); - bot->MoveToVector (waypoints.GetBombPosition ()); + bot->DeleteSearchNodes (); + + bot->m_position = waypoints.GetBombPosition (); + bot->PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0f, true); } } } diff --git a/source/manager.cpp b/source/manager.cpp index fad393b..06b4dc7 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -10,7 +10,7 @@ #include ConVar yb_autovacate ("yb_autovacate", "0"); -ConVar yb_autovacate_smart_kick ("yb_autovacate_smart_kick", "1"); +ConVar yb_autovacate_smart_kick ("yb_autovacate_smart_kick", "0"); ConVar yb_quota ("yb_quota", "0", VT_NORMAL); ConVar yb_quota_mode ("yb_quota_mode", "normal"); @@ -108,11 +108,10 @@ void BotManager::CallGameEntity (entvars_t *vars) player (vars); } -int BotManager::CreateBot (const String &name, int difficulty, int personality, int team, int member) +int BotManager::CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd) { // this function completely prepares bot entity (edict) for creation, creates team, difficulty, sets name etc, and // then sends result to bot constructor - edict_t *bot = NULL; char outputName[33]; @@ -195,8 +194,9 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality, if (!IsNullString (prefixedName)) strcpy (outputName, prefixedName); } + bot = g_engfuncs.pfnCreateFakeClient (outputName); - if (engine.IsNullEntity ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName)))) + if (engine.IsNullEntity (bot)) { engine.CenterPrintf ("Maximum players reached (%d/%d). Unable to create Bot.", engine.MaxClients (), engine.MaxClients ()); return 2; @@ -213,6 +213,9 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality, engine.Printf ("Connecting Bot..."); + if (isConsoleCmd) + yb_quota.SetInt (yb_quota.GetInt () + 1); + return 1; } @@ -296,7 +299,7 @@ void BotManager::PeriodicThink (void) } } -void BotManager::AddBot (const String &name, int difficulty, int personality, int team, int member) +void BotManager::AddBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd) { // this function putting bot creation process to queue to prevent engine crashes @@ -308,12 +311,13 @@ void BotManager::AddBot (const String &name, int difficulty, int personality, in bot.personality = personality; bot.team = team; bot.member = member; + bot.console = isConsoleCmd; // put to queue m_creationTab.Push (bot); } -void BotManager::AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member) +void BotManager::AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member, bool isConsoleCmd) { // this function is same as the function above, but accept as parameters string instead of integers @@ -380,20 +384,20 @@ void BotManager::VerifyPlayersHasJoinedTeam (int &desiredCount) { Client &cl = g_clients[i]; - if ((cl.flags & CF_USED) && cl.team != SPECTATOR && !IsValidBot (cl.ent)) + if (!(cl.flags & CF_USED) || cl.team == SPECTATOR || IsValidBot (cl.ent)) + continue; + + FOR_EACH_AE (m_trackedPlayers, it) { - FOR_EACH_AE (m_trackedPlayers, it) - { - if (cl.ent != m_trackedPlayers[it]) - continue; + if (cl.ent != m_trackedPlayers[it]) + continue; - m_balanceCount--; - desiredCount--; + m_balanceCount--; + desiredCount--; - m_trackedPlayers.RemoveAt (it); + m_trackedPlayers.RemoveAt (it); - break; - } + break; } } } @@ -410,7 +414,7 @@ void BotManager::MaintainBotQuota (void) if (!m_creationTab.IsEmpty () && m_maintainTime < engine.Time ()) { CreateQueue last = m_creationTab.Pop (); - int resultOfCall = CreateBot (last.name, last.difficulty, last.personality, last.team, last.member); + int resultOfCall = CreateBot (last.name, last.difficulty, last.personality, last.team, last.member, last.console); // check the result of creation if (resultOfCall == 0) @@ -429,15 +433,20 @@ void BotManager::MaintainBotQuota (void) // now keep bot number up to date if (m_quotaMaintainTime < engine.Time ()) { - // don't allow that quota is below zero - if (yb_quota.GetInt () < 0) - yb_quota.SetInt (0); + // keep the quota number in valid ranges + { + if (yb_quota.GetInt () < 0) + yb_quota.SetInt (0); + + if (yb_quota.GetInt () > engine.MaxClients ()) + yb_quota.SetInt (engine.MaxClients ()); + } int numBots = GetBotsNum (); - int numHumans = GetHumansJoinedTeam (); + int numHumans = yb_autovacate_smart_kick.GetBool () ? GetHumansNum () : GetHumansJoinedTeam (); int desiredCount = yb_quota.GetInt (); - if (yb_join_after_player.GetInt () > 0 && !numHumans) + if (yb_join_after_player.GetBool () && !numHumans) desiredCount = 0; // quota mode @@ -448,20 +457,17 @@ void BotManager::MaintainBotQuota (void) else if (mode == 'm') // match desiredCount = max (0, yb_quota.GetInt () * numHumans); - if (yb_autovacate.GetBool ()) - desiredCount = min (desiredCount, engine.MaxClients () - (numHumans + 1)); - else - desiredCount = min (desiredCount, engine.MaxClients () - numHumans); - + desiredCount = min (desiredCount, engine.MaxClients () - (numHumans + (yb_autovacate.GetBool () ? 1 : 0))); + if (yb_autovacate_smart_kick.GetBool () && numBots > 1 && desiredCount > 1) VerifyPlayersHasJoinedTeam (desiredCount); if (desiredCount > numBots) - AddRandom (); + AddRandom (false); else if (desiredCount < numBots) - RemoveRandom (); + RemoveRandom (true); - m_quotaMaintainTime = engine.Time () + 0.90f; + m_quotaMaintainTime = engine.Time () + 0.40f; } } @@ -506,30 +512,17 @@ void BotManager::FillServer (int selection, int personality, int difficulty, int for (int i = 0; i <= toAdd; i++) AddBot ("", difficulty, personality, selection, -1); - yb_quota.SetInt (toAdd); engine.CenterPrintf ("Fill Server with %s bots...", &teamDesc[selection][0]); } -void BotManager::RemoveAll (bool zeroQuota) +void BotManager::RemoveAll (void) { // this function drops all bot clients from server (this function removes only yapb's)`q - if (zeroQuota) - engine.CenterPrintf ("Bots are removed from server."); + engine.CenterPrintf ("Bots are removed from server."); - for (int i = 0; i < engine.MaxClients (); i++) - { - if (m_bots[i] != NULL) // is this slot used? - m_bots[i]->Kick (); - } m_creationTab.RemoveAll (); - - // reset cvars - if (zeroQuota) - { - yb_quota.SetInt (0); - yb_autovacate.SetInt (0); - } + yb_quota.SetInt (0); } void BotManager::RemoveFromTeam (Team team, bool removeAll) @@ -625,19 +618,18 @@ void BotManager::KillAll (int team) engine.CenterPrintf ("All Bots died !"); } -void BotManager::RemoveRandom (void) +void BotManager::RemoveRandom (bool keepQuota) { // this function removes random bot from server (only yapb's) bool deadBotFound = false; - // first try to kick the bot that is currently dead for (int i = 0; i < engine.MaxClients (); i++) { if (m_bots[i] != NULL && !m_bots[i]->m_notKilled) // is this slot used? { - m_bots[i]->Kick (); + m_bots[i]->Kick (keepQuota); deadBotFound = true; break; @@ -666,7 +658,7 @@ void BotManager::RemoveRandom (void) // if found some bots if (index != 0) { - m_bots[index]->Kick (); + m_bots[index]->Kick (keepQuota); return; } @@ -675,7 +667,7 @@ void BotManager::RemoveRandom (void) { if (m_bots[i] != NULL) // is this slot used? { - m_bots[i]->Kick (); + m_bots[i]->Kick (keepQuota); break; } } @@ -887,6 +879,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c engine.IssueCmd ("kick \"%s\"", STRING (bot->v.netname)); // kick the bot player if the server refused it bot->v.flags |= FL_KILLME; + return; } MDLL_ClientPutInServer (bot); @@ -957,12 +950,6 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c m_wantedTeam = team; m_wantedClass = member; - int newBotsNum = bots.GetBotsNum () + 1; - - // keep quota number up to date - if (newBotsNum < engine.MaxClients () && newBotsNum > yb_quota.GetInt ()) - yb_quota.SetInt (newBotsNum); - NewRound (); } @@ -1246,12 +1233,7 @@ void Bot::NewRound (void) if (Random.Long (0, 100) < 50) ChatterMessage (Chatter_NewRound); - const float interval = (1.0f / 30.0f) * Random.Float (0.95f, 1.05f); - - if (g_gameFlags & GAME_LEGACY) - m_thinkInterval = 0.0f; - else - m_thinkInterval = interval; + m_thinkInterval = (g_gameFlags & GAME_LEGACY) ? 0.0f : (1.0f / 30.0f) * Random.Float (0.95f, 1.05f); } void Bot::Kill (void) @@ -1262,18 +1244,16 @@ void Bot::Kill (void) bots.TouchWithKillerEntity (this); } -void Bot::Kick (void) +void Bot::Kick (bool keepQuota) { // this function kick off one bot from the server. engine.IssueCmd ("kick \"%s\"", STRING (pev->netname)); engine.CenterPrintf ("Bot '%s' kicked", STRING (pev->netname)); - int newBotsNum = bots.GetBotsNum () - 1; - // keep quota number up to date - if (newBotsNum < engine.MaxClients () && newBotsNum < yb_quota.GetInt ()) - yb_quota.SetInt (newBotsNum); + if (!keepQuota) + yb_quota.SetInt (Clamp (yb_quota.GetInt () - 1, 0, yb_quota.GetInt ())); } void Bot::StartGame (void) diff --git a/source/navigate.cpp b/source/navigate.cpp index cae6b74..455443f 100644 --- a/source/navigate.cpp +++ b/source/navigate.cpp @@ -1264,6 +1264,18 @@ void Bot::FindShortestPath (int srcIndex, int destIndex) { // this function finds the shortest path from source index to destination index + if (srcIndex > g_numWaypoints - 1 || srcIndex < 0) + { + AddLogEntry (true, LL_ERROR, "Pathfinder source path index not valid (%d)", srcIndex); + return; + } + + if (destIndex > g_numWaypoints - 1 || destIndex < 0) + { + AddLogEntry (true, LL_ERROR, "Pathfinder destination path index not valid (%d)", destIndex); + return; + } + DeleteSearchNodes (); m_chosenGoalIndex = srcIndex;