Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wzapi: change removeObject API function to defer object removal #3736

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions data/base/script/campaign/libcampaign_includes/artifact.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ function __camPickupArtifact(artifact)
camTrace("Artifact", artifact.id, "is not managed");
return;
}
if (Object.hasOwn(ai, "pickedUp") && ai.pickedUp === true)
{
camTrace("Already picked up the artifact", __ALABEL);
return;
}
ai.pickedUp = true;

camTrace("Picked up", ai.tech);
playSound(cam_sounds.artifactRecovered, artifact.x, artifact.y, artifact.z);
Expand Down
3 changes: 2 additions & 1 deletion src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
#include "multigifts.h"
#include "wzscriptdebug.h"
#include "gamehistorylogger.h"
#include "wzapi.h"
#include <array>

#if defined(__clang__)
Expand Down Expand Up @@ -3379,7 +3380,7 @@ bool saveGame(const char *aFileName, GAME_TYPE saveType, bool isAutoSave)
size_t fileExtension;
char CurrentFileName[PATH_MAX] = {'\0'};

triggerEvent(TRIGGER_GAME_SAVING);
executeFnAndProcessScriptQueuedRemovals([]() { triggerEvent(TRIGGER_GAME_SAVING); });

ASSERT_OR_RETURN(false, aFileName && strlen(aFileName) > 4, "Bad savegame filename");
sstrcpy(CurrentFileName, aFileName);
Expand Down
5 changes: 3 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
#include "seqdisp.h"
#include "version.h"
#include "hci/teamstrategy.h"
#include "wzapi.h"

#include <algorithm>
#include <unordered_map>
Expand Down Expand Up @@ -1895,7 +1896,7 @@ bool stageThreeInitialise()

if (getLevelLoadType() == GTYPE_SAVE_MIDMISSION || getLevelLoadType() == GTYPE_SAVE_START)
{
triggerEvent(TRIGGER_GAME_LOADED);
executeFnAndProcessScriptQueuedRemovals([]() { triggerEvent(TRIGGER_GAME_LOADED); });
}
else
{
Expand All @@ -1909,7 +1910,7 @@ bool stageThreeInitialise()
gInputManager.contexts().set(InputContext::DEBUG_MISC, InputContext::State::ACTIVE);
}

triggerEvent(TRIGGER_GAME_INIT);
executeFnAndProcessScriptQueuedRemovals([]() { triggerEvent(TRIGGER_GAME_INIT); });
playerBuiltHQ = structureExists(selectedPlayer, REF_HQ, true, false);
}

Expand Down
86 changes: 49 additions & 37 deletions src/keybind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,49 +387,61 @@ void kf_CloneSelected(int limit)
return; // no-op
}

mutating_list_iterate(apsDroidLists[selectedPlayer], [limit, &sTemplate](DROID* d)
bool selectedAnything = false;
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)
continue;
}
selectedAnything = true;
enumerateTemplates(selectedPlayer, [psDroid = d, &sTemplate](DROID_TEMPLATE* psTempl) {
if (psTempl->name.compare(psDroid->aName) == 0)
{
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;
sTemplate = psTempl;
return false; // stop enumerating
}

// create a new droid army
for (int i = 0; i < limit; i++)
{
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);
}
}
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;
}
droidToClone = d;
// Break out of the loop if we've successfully found the associated droid template.
break;
}
if (!selectedAnything)
{
debug(LOG_INFO, "Nothing was selected?");
return IterationResult::CONTINUE_ITERATION;
});
return;
}
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()
Expand Down
64 changes: 39 additions & 25 deletions src/loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
#include "clparse.h"
#include "gamehistorylogger.h"
#include "profiling.h"
#include "wzapi.h"

#include "warzoneconfig.h"

Expand Down Expand Up @@ -515,7 +516,7 @@ static void gameStateUpdate()

if (!paused && !scriptPaused())
{
updateScripts();
executeFnAndProcessScriptQueuedRemovals([]() { updateScripts(); });
}

// Update abandoned structures
Expand Down Expand Up @@ -544,33 +545,40 @@ static void gameStateUpdate()
//update the current power available for a player
updatePlayerPower(i);

mutating_list_iterate(apsDroidLists[i], [](DROID* d)
{
droidUpdate(d);
return IterationResult::CONTINUE_ITERATION;
executeFnAndProcessScriptQueuedRemovals([i]() {
mutating_list_iterate(apsDroidLists[i], [](DROID* d)
{
droidUpdate(d);
return IterationResult::CONTINUE_ITERATION;
});
});
mutating_list_iterate(mission.apsDroidLists[i], [](DROID* d)
{
missionDroidUpdate(d);
return IterationResult::CONTINUE_ITERATION;
executeFnAndProcessScriptQueuedRemovals([i]() {
mutating_list_iterate(mission.apsDroidLists[i], [](DROID* d)
{
missionDroidUpdate(d);
return IterationResult::CONTINUE_ITERATION;
});
});

// FIXME: These for-loops are code duplication
mutating_list_iterate(apsStructLists[i], [](STRUCTURE* s)
{
structureUpdate(s, false);
return IterationResult::CONTINUE_ITERATION;
executeFnAndProcessScriptQueuedRemovals([i]() {
mutating_list_iterate(apsStructLists[i], [](STRUCTURE* s)
{
structureUpdate(s, false);
return IterationResult::CONTINUE_ITERATION;
});
});
mutating_list_iterate(mission.apsStructLists[i], [](STRUCTURE* s)
{
structureUpdate(s, true); // update for mission
return IterationResult::CONTINUE_ITERATION;
executeFnAndProcessScriptQueuedRemovals([i]() {
mutating_list_iterate(mission.apsStructLists[i], [](STRUCTURE* s)
{
structureUpdate(s, true); // update for mission
return IterationResult::CONTINUE_ITERATION;
});
});
}

missionTimerUpdate();

proj_UpdateAll();
executeFnAndProcessScriptQueuedRemovals([]() { proj_UpdateAll(); });

for (FEATURE *psCFeat : apsFeatureLists[0])
{
Expand Down Expand Up @@ -641,7 +649,7 @@ GAMECODE gameLoop()
{
// Receive NET_BLAH messages.
// Receive GAME_BLAH messages, and if it's time, process exactly as many GAME_BLAH messages as required to be able to tick the gameTime.
recvMessage();
executeFnAndProcessScriptQueuedRemovals([]() { recvMessage(); });

bool selectedPlayerIsSpectator = bMultiPlayer && NetPlay.players[selectedPlayer].isSpectator;
bool multiplayerHostDisconnected = bMultiPlayer && !NetPlay.isHostAlive && NetPlay.bComms && !NetPlay.isHost; // do not fast-forward after the host has disconnected
Expand Down Expand Up @@ -694,10 +702,16 @@ GAMECODE gameLoop()
NETflush(); // Make sure that we aren't waiting too long to send data.
}

unsigned before = wzGetTicks();
GAMECODE renderReturn = renderLoop();
pie_ScreenFrameRenderEnd(); // must happen here for proper renderBudget calculation
unsigned after = wzGetTicks();
unsigned before, after;
GAMECODE renderReturn;
executeFnAndProcessScriptQueuedRemovals([&before, &after, &renderReturn]()
{
before = wzGetTicks();
renderReturn = renderLoop();
pie_ScreenFrameRenderEnd(); // must happen here for proper renderBudget calculation
after = wzGetTicks();
});


#if defined(__EMSCRIPTEN__)
lastRenderDelta = (after - before);
Expand Down Expand Up @@ -753,7 +767,7 @@ void videoLoop()
{
displayGameOver(getScriptWinLoseVideo() == PLAY_WIN, false);
}
triggerEvent(TRIGGER_VIDEO_QUIT);
executeFnAndProcessScriptQueuedRemovals([]() { triggerEvent(TRIGGER_VIDEO_QUIT); });
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
#include "wzcrashhandlingproviders.h"
#include "wzpropertyproviders.h"
#include "3rdparty/gsl_finally.h"
#include "wzapi.h"

#if defined(WZ_OS_UNIX)
# include <signal.h>
Expand Down Expand Up @@ -987,7 +988,7 @@ static void startGameLoop()
{
addMissionTimerInterface();
}
triggerEvent(TRIGGER_START_LEVEL);
executeFnAndProcessScriptQueuedRemovals([]() { triggerEvent(TRIGGER_START_LEVEL); });
screen_disableMapPreview();

if (!bMultiPlayer && getCamTweakOption_AutosavesOnly())
Expand Down
8 changes: 6 additions & 2 deletions src/mission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
#include "lib/framework/wztime.h"
#include "keybind.h"
#include "campaigninfo.h"
#include "wzapi.h"

#define IDMISSIONRES_TXT 11004
#define IDMISSIONRES_LOAD 11005
Expand Down Expand Up @@ -2113,7 +2114,10 @@ void intUpdateTransporterTimer(WIDGET *psWidget, const W_CONTEXT *psContext)
if (psTransporter->action == DACTION_TRANSPORTWAITTOFLYIN)
{
missionFlyTransportersIn(selectedPlayer, false);
triggerEvent(TRIGGER_TRANSPORTER_ARRIVED, psTransporter);
executeFnAndProcessScriptQueuedRemovals([psTransporter]()
{
triggerEvent(TRIGGER_TRANSPORTER_ARRIVED, psTransporter);
});
}
}
}
Expand Down Expand Up @@ -2859,7 +2863,7 @@ void missionTimerUpdate()
if ((SDWORD)(gameTime - mission.startTime) > mission.time)
{
//the script can call the end game cos have failed!
triggerEvent(TRIGGER_MISSION_TIMEOUT);
executeFnAndProcessScriptQueuedRemovals([]() { triggerEvent(TRIGGER_MISSION_TIMEOUT); });
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/transporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "visibility.h"
#include "multiplay.h"
#include "hci/groups.h"
#include "wzapi.h"

//#define IDTRANS_FORM 9000 //The Transporter base form
#define IDTRANS_CLOSE 9002 //The close button icon
Expand Down Expand Up @@ -1280,7 +1281,7 @@ void processLaunchTransporter()
//set the data for the transporter timer
widgSetUserData(psWScreen, IDTRANTIMER_DISPLAY, (void *)psCurrTransporter);

triggerEvent(TRIGGER_TRANSPORTER_LAUNCH, psCurrTransporter);
executeFnAndProcessScriptQueuedRemovals([]() { triggerEvent(TRIGGER_TRANSPORTER_LAUNCH, psCurrTransporter); });
}
}
}
Expand Down
Loading
Loading