From 5f98ae8976f8705db44113b9f2b45ba46ae4c412 Mon Sep 17 00:00:00 2001 From: Pavel Solodovnikov Date: Mon, 15 Apr 2024 11:17:02 +0300 Subject: [PATCH] keybind: get rid of `mutating_list_iterate` inside `kf_CloneSelected()` Signed-off-by: Pavel Solodovnikov --- src/keybind.cpp | 82 ++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/src/keybind.cpp b/src/keybind.cpp index 287404790ce..83a8ea9ec12 100644 --- a/src/keybind.cpp +++ b/src/keybind.cpp @@ -387,49 +387,55 @@ void kf_CloneSelected(int limit) return; // no-op } - mutating_list_iterate(apsDroidLists[selectedPlayer], [limit, &sTemplate](DROID* d) + const DROID* droidToClone = nullptr; + for (const DROID* d : apsDroidLists[selectedPlayer]) { - if (d->selected) + if (!d->selected) { - enumerateTemplates(selectedPlayer, [psDroid = d, &sTemplate](DROID_TEMPLATE* psTempl) { - if (psTempl->name.compare(psDroid->aName) == 0) - { - sTemplate = psTempl; - return false; // stop enumerating - } - return true; - }); - - if (!sTemplate) - { - debug(LOG_ERROR, "Cloning vat has been destroyed. We can't find the template for this droid: %s, id:%u, type:%d!", d->aName, d->id, d->droidType); - return IterationResult::BREAK_ITERATION; - } - - // create a new droid army - for (int i = 0; i < limit; i++) + debug(LOG_INFO, "Nothing was selected?"); + continue; + } + enumerateTemplates(selectedPlayer, [psDroid = d, &sTemplate](DROID_TEMPLATE* psTempl) { + if (psTempl->name.compare(psDroid->aName) == 0) { - Vector2i pos = d->pos.xy() + iSinCosR(40503 * i, iSqrt(50 * 50 * (i + 1))); // 40503 = 65536/φ (A bit more than a right angle) - DROID* psNewDroid = buildDroid(sTemplate, pos.x, pos.y, d->player, false, nullptr); - if (psNewDroid) - { - addDroid(psNewDroid, apsDroidLists); - triggerEventDroidBuilt(psNewDroid, nullptr); - } - else if (!bMultiMessages) - { - debug(LOG_ERROR, "Cloning has failed for template:%s id:%d", getID(sTemplate), sTemplate->multiPlayerID); - } + sTemplate = psTempl; + return false; // stop enumerating } - std::string msg = astringf(_("Player %u is cheating a new droid army of: %d × %s."), selectedPlayer, limit, d->aName); - sendInGameSystemMessage(msg.c_str()); - Cheated = true; - audio_PlayTrack(ID_SOUND_NEXUS_LAUGH1); - return IterationResult::BREAK_ITERATION; + return true; + }); + if (!sTemplate) + { + debug(LOG_ERROR, "Cloning vat has been destroyed. We can't find the template for this droid: %s, id:%u, type:%d!", d->aName, d->id, d->droidType); + break; } - debug(LOG_INFO, "Nothing was selected?"); - return IterationResult::CONTINUE_ITERATION; - }); + droidToClone = d; + // Break out of the loop if we've successfully found the associated droid template. + break; + } + if (!sTemplate) + { + return; + } + ASSERT(droidToClone != nullptr, "No droid to clone found"); + // create a new droid army + for (int i = 0; i < limit; i++) + { + Vector2i pos = droidToClone->pos.xy() + iSinCosR(40503 * i, iSqrt(50 * 50 * (i + 1))); // 40503 = 65536/φ (A bit more than a right angle) + DROID* psNewDroid = buildDroid(sTemplate, pos.x, pos.y, droidToClone->player, false, nullptr); + if (psNewDroid) + { + addDroid(psNewDroid, apsDroidLists); + triggerEventDroidBuilt(psNewDroid, nullptr); + } + else if (!bMultiMessages) + { + debug(LOG_ERROR, "Cloning has failed for template:%s id:%d", getID(sTemplate), sTemplate->multiPlayerID); + } + } + std::string msg = astringf(_("Player %u is cheating a new droid army of: %d × %s."), selectedPlayer, limit, droidToClone->aName); + sendInGameSystemMessage(msg.c_str()); + Cheated = true; + audio_PlayTrack(ID_SOUND_NEXUS_LAUGH1); } void kf_MakeMeHero()