From e30f116faf4260ecfad2ed6c6e9f6056459e5581 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 30 Jan 2019 01:38:18 +0100 Subject: [PATCH] - moved bglobal into FLevelLocals This is still all static data, only the location has changed, but none of the access. --- src/b_bot.cpp | 10 +++++----- src/b_bot.h | 6 +++--- src/b_func.cpp | 30 +++++++++++++++--------------- src/b_game.cpp | 10 +++------- src/b_move.cpp | 2 +- src/b_think.cpp | 7 ++----- src/d_main.cpp | 10 +++++----- src/d_net.cpp | 4 ++-- src/dobjgc.cpp | 4 ---- src/g_game.cpp | 11 +++++++---- src/g_level.cpp | 15 +++++++++------ src/g_levellocals.h | 2 ++ src/m_cheat.cpp | 6 ++++-- src/namedef.h | 1 - src/p_interaction.cpp | 4 ++-- src/p_map.cpp | 2 +- src/p_mobj.cpp | 6 +++--- src/p_saveg.cpp | 5 ++--- src/p_sight.cpp | 2 +- src/p_tick.cpp | 9 +++++---- 20 files changed, 72 insertions(+), 74 deletions(-) diff --git a/src/b_bot.cpp b/src/b_bot.cpp index 2ca43dca6c..39067dfa9e 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -144,9 +144,9 @@ void DBot::Tick () } BotThinkCycles.Clock(); - bglobal.m_Thinking = true; + Level->BotInfo.m_Thinking = true; Think (); - bglobal.m_Thinking = false; + Level->BotInfo.m_Thinking = false; BotThinkCycles.Unclock(); } @@ -174,9 +174,9 @@ CCMD (addbot) } if (argv.argc() > 1) - bglobal.SpawnBot (argv[1]); + currentUILevel->BotInfo.SpawnBot (argv[1]); else - bglobal.SpawnBot (nullptr); + currentUILevel->BotInfo.SpawnBot (nullptr); } void FCajunMaster::ClearPlayer (int i, bool keepTeam) @@ -233,7 +233,7 @@ CCMD (freeze) CCMD (listbots) { - botinfo_t *thebot = bglobal.botinfo; + botinfo_t *thebot = currentUILevel->BotInfo.botinfo; int count = 0; while (thebot) diff --git a/src/b_bot.h b/src/b_bot.h index cdcda5b6a2..b7a30d5ebe 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -139,8 +139,9 @@ public: bool IsDangerous (sector_t *sec); TArray getspawned; //Array of bots (their names) which should be spawned when starting a game. - uint8_t freeze; //Game in freeze mode. - uint8_t changefreeze; //Game wants to change freeze mode. + + //uint8_t freeze; //Game in freeze mode. + //uint8_t changefreeze; //Game wants to change freeze mode. int botnum; botinfo_t *botinfo; int spawn_tries; @@ -237,7 +238,6 @@ private: //Externs -extern FCajunMaster bglobal; extern cycle_t BotThinkCycles, BotSupportCycles; EXTERN_CVAR (Float, bot_flag_return_time) diff --git a/src/b_func.cpp b/src/b_func.cpp index ddc4919867..9d0b015dd6 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -105,7 +105,7 @@ bool DBot::Reachable (AActor *rtarget) double ceilingheight = s->ceilingplane.ZatPoint (hitx, hity); double floorheight = s->floorplane.ZatPoint (hitx, hity); - if (!bglobal.IsDangerous (s) && //Any nukage/lava? + if (!Level->BotInfo.IsDangerous (s) && //Any nukage/lava? (floorheight <= (last_z+MAXMOVEHEIGHT) && ((ceilingheight == floorheight && line->special) || (ceilingheight - floorheight) >= player->mo->Height))) //Does it fit? @@ -235,8 +235,8 @@ void DBot::Dofire (ticcmd_t *cmd) // prediction aiming Dist = player->mo->Distance2D(enemy); fm = Dist / GetDefaultByType (GetBotInfo(player->ReadyWeapon).projectileType)->Speed; - bglobal.SetBodyAt(enemy->Pos() + enemy->Vel.XY() * fm * 2, 1); - Angle = player->mo->AngleTo(bglobal.body1); + Level->BotInfo.SetBodyAt(enemy->Pos() + enemy->Vel.XY() * fm * 2, 1); + Angle = player->mo->AngleTo(Level->BotInfo.body1); if (Check_LOS (enemy, SHOOTFOV)) no_fire = false; } @@ -300,7 +300,7 @@ extern int BotWTG; void FCajunMaster::BotTick(AActor *mo) { BotSupportCycles.Clock(); - bglobal.m_Thinking = true; + m_Thinking = true; for (int i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].Bot == NULL) @@ -333,7 +333,7 @@ void FCajunMaster::BotTick(AActor *mo) } } } - bglobal.m_Thinking = false; + m_Thinking = false; BotSupportCycles.Unclock(); } @@ -382,7 +382,7 @@ AActor *DBot::Choose_Mate () && client->mo->health > 0 && client->mo != observer && ((player->mo->health/2) <= client->mo->health || !deathmatch) - && !bglobal.IsLeader(client)) //taken? + && !Level->BotInfo.IsLeader(client)) //taken? { if (P_CheckSight (player->mo, client->mo, SF_IGNOREVISIBILITY)) { @@ -401,7 +401,7 @@ AActor *DBot::Choose_Mate () //Make a introducing to mate. if(target && target!=last_mate) { - if((P_Random()%(200*bglobal.botnum))<3) + if((P_Random()%(200*Level->BotInfo.botnum))<3) { chat = c_teamup; if(target->bot) @@ -543,9 +543,9 @@ DAngle DBot::FireRox (AActor *enemy, ticcmd_t *cmd) AActor *actor; double m; - bglobal.SetBodyAt(player->mo->PosPlusZ(player->mo->Height / 2) + player->mo->Vel.XY() * 5, 2); + Level->BotInfo.SetBodyAt(player->mo->PosPlusZ(player->mo->Height / 2) + player->mo->Vel.XY() * 5, 2); - actor = bglobal.body2; + actor = Level->BotInfo.body2; dist = actor->Distance2D (enemy); if (dist < SAFE_SELF_MISDIST) @@ -553,24 +553,24 @@ DAngle DBot::FireRox (AActor *enemy, ticcmd_t *cmd) //Predict. m = ((dist+1) / GetDefaultByName("Rocket")->Speed); - bglobal.SetBodyAt(DVector3((enemy->Pos() + enemy->Vel * (m + 2)), ONFLOORZ), 1); + Level->BotInfo.SetBodyAt(DVector3((enemy->Pos() + enemy->Vel * (m + 2)), ONFLOORZ), 1); //try the predicted location - if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile + if (P_CheckSight (actor, Level->BotInfo.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile { FCheckPosition tm; - if (bglobal.SafeCheckPosition (player->mo, actor->X(), actor->Y(), tm)) + if (Level->BotInfo.SafeCheckPosition (player->mo, actor->X(), actor->Y(), tm)) { - if (bglobal.FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST) + if (Level->BotInfo.FakeFire (actor, Level->BotInfo.body1, cmd) >= SAFE_SELF_MISDIST) { - return actor->AngleTo(bglobal.body1); + return actor->AngleTo(Level->BotInfo.body1); } } } //Try fire straight. if (P_CheckSight (actor, enemy, 0)) { - if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST) + if (Level->BotInfo.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST) { return player->mo->AngleTo(enemy); } diff --git a/src/b_game.cpp b/src/b_game.cpp index 0f6b699116..603d7ecb83 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -96,9 +96,6 @@ Everything that is changed is marked (maybe commented) with "Added by MC" static FRandom pr_botspawn ("BotSpawn"); -//Externs -FCajunMaster bglobal; - cycle_t BotThinkCycles, BotSupportCycles; int BotWTG; @@ -176,7 +173,6 @@ void FCajunMaster::Init () botnum = 0; firstthing = nullptr; spawn_tries = 0; - freeze = false; observer = false; body1 = nullptr; body2 = nullptr; @@ -520,7 +516,7 @@ bool FCajunMaster::LoadBots () bool gotteam = false; int loaded_bots = 0; - bglobal.ForgetBots (); + ForgetBots (); tmp = M_GetCajunPath(BOTFILENAME); if (tmp.IsEmpty()) { @@ -636,9 +632,9 @@ bool FCajunMaster::LoadBots () appendinfo (newinfo->info, "team"); appendinfo (newinfo->info, "255"); } - newinfo->next = bglobal.botinfo; + newinfo->next = botinfo; newinfo->lastteam = TEAM_NONE; - bglobal.botinfo = newinfo; + botinfo = newinfo; loaded_bots++; } Printf ("%d bots read from %s\n", loaded_bots, BOTFILENAME); diff --git a/src/b_move.cpp b/src/b_move.cpp index 52ae724dc0..a22867af14 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -104,7 +104,7 @@ bool DBot::Move (ticcmd_t *cmd) tryx = player->mo->X() + 8*xspeed[player->mo->movedir]; tryy = player->mo->Y() + 8*yspeed[player->mo->movedir]; - try_ok = bglobal.CleanAhead (player->mo, tryx, tryy, cmd); + try_ok = Level->BotInfo.CleanAhead (player->mo, tryx, tryy, cmd); if (!try_ok) //Anything blocking that could be opened etc.. { diff --git a/src/b_think.cpp b/src/b_think.cpp index a0a30180d5..4152e475d7 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -289,7 +289,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) r = pr_botmove(); if (r < 128) { - auto it = player->mo->Level->GetThinkerIterator(NAME_Inventory, MAX_STATNUM+1, bglobal.firstthing); + auto it = player->mo->Level->GetThinkerIterator(NAME_Inventory, MAX_STATNUM+1, Level->BotInfo.firstthing); auto item = it.Next(); if (item != NULL || (item = it.Next()) != NULL) @@ -304,7 +304,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) { item = it.Next(); } - bglobal.firstthing = item; + Level->BotInfo.firstthing = item; dest = item; } } @@ -356,9 +356,6 @@ void DBot::WhatToGet (AActor *item) } int weapgiveammo = (alwaysapplydmflags || deathmatch) && !(dmflags & DF_WEAPONS_STAY); - //if(pos && !bglobal.thingvis[pos->id][item->id]) continue; -// if (item->IsKindOf (RUNTIME_CLASS(AArtifact))) -// return; // don't know how to use artifacts if (item->IsKindOf(NAME_Weapon)) { // FIXME diff --git a/src/d_main.cpp b/src/d_main.cpp index 55db3cc713..36c921abf7 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -957,7 +957,7 @@ void D_Display () void D_ErrorCleanup () { savegamerestore = false; - bglobal.RemoveAllBots (&level, true); + level.BotInfo.RemoveAllBots (&level, true); D_QuitNetGame (); if (demorecording || demoplayback) G_CheckDemoStatus (); @@ -2553,14 +2553,14 @@ void D_DoomMain (void) PClassActor::StaticSetActorNums(); //Added by MC: - bglobal.getspawned.Clear(); + level.BotInfo.getspawned.Clear(); argcount = Args->CheckParmList("-bots", &args); for (p = 0; p < argcount; ++p) { - bglobal.getspawned.Push(args[p]); + level.BotInfo.getspawned.Push(args[p]); } - bglobal.spawn_tries = 0; - bglobal.wanted_botnum = bglobal.getspawned.Size(); + level.BotInfo.spawn_tries = 0; + level.BotInfo.wanted_botnum = level.BotInfo.getspawned.Size(); if (!batchrun) Printf ("P_Init: Init Playloop state.\n"); StartScreen->LoadingStatus ("Init game engine", 0x3f); diff --git a/src/d_net.cpp b/src/d_net.cpp index c88a0ce123..1f360a8d2a 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2230,11 +2230,11 @@ void Net_DoCommand (int type, uint8_t **stream, int player) break; case DEM_ADDBOT: - bglobal.TryAddBot (&level, stream, player); + level.BotInfo.TryAddBot (&level, stream, player); break; case DEM_KILLBOTS: - bglobal.RemoveAllBots (&level, true); + level.BotInfo.RemoveAllBots (&level, true); Printf ("Removed all bots\n"); break; diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 2b8aefd587..ab1ccf34fc 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -300,10 +300,6 @@ static void MarkRoot() { Level->Mark(); } - // Mark bot stuff. - Mark(bglobal.firstthing); - Mark(bglobal.body1); - Mark(bglobal.body2); // NextToThink must not be freed while thinkers are ticking. Mark(NextToThink); // Mark soft roots. diff --git a/src/g_game.cpp b/src/g_game.cpp index c0ba5398d8..2f170a52b4 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -219,6 +219,8 @@ bool SendLand; const AActor *SendItemUse, *SendItemDrop; int SendItemDropAmount; +extern uint8_t globalfreeze; + EXTERN_CVAR (Int, team) CVAR (Bool, teamplay, false, CVAR_SERVERINFO) @@ -1111,7 +1113,7 @@ void G_Ticker () uint32_t rngsum = FRandom::StaticSumSeeds (); //Added by MC: For some of that bot stuff. The main bot function. - bglobal.Main (&level); + level.BotInfo.Main (&level); for (i = 0; i < MAXPLAYERS; i++) { @@ -1894,7 +1896,7 @@ void G_DoLoadGame () // Read intermission data for hubs G_SerializeHub(arc); - bglobal.RemoveAllBots(&level, true); + level.BotInfo.RemoveAllBots(&level, true); FString cvar; arc("importantcvars", cvar); @@ -1907,7 +1909,8 @@ void G_DoLoadGame () uint32_t time[2] = { 1,0 }; arc("ticrate", time[0]) - ("leveltime", time[1]); + ("leveltime", time[1]) + ("globalfreeze", globalfreeze); // dearchive all the modifications level.time = Scale(time[1], TICRATE, time[0]); @@ -2887,7 +2890,7 @@ DEFINE_GLOBAL(multiplayer) DEFINE_GLOBAL(gameaction) DEFINE_GLOBAL(gamestate) DEFINE_GLOBAL(skyflatnum) -DEFINE_GLOBAL_NAMED(bglobal.freeze, globalfreeze) +DEFINE_GLOBAL(globalfreeze) DEFINE_GLOBAL(gametic) DEFINE_GLOBAL(demoplayback) DEFINE_GLOBAL(automapactive); diff --git a/src/g_level.cpp b/src/g_level.cpp index 60f38ea5e0..bd0d234d2a 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -535,7 +535,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) //Added by MC: Initialize bots. if (!deathmatch) { - bglobal.Init (); + level.BotInfo.Init (); } if (bTitleLevel) @@ -653,7 +653,7 @@ void FLevelLocals::ChangeLevel(const char *levelname, int position, int flags, i } changeflags = flags; - bglobal.End(); //Added by MC: + BotInfo.End(); //Added by MC: // [RH] Give scripts a chance to do something unloading = true; @@ -1070,7 +1070,7 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au //Added by MC: Initialize bots. if (deathmatch) { - bglobal.Init (); + BotInfo.Init (); } if (timingdemo) @@ -1167,7 +1167,7 @@ void FLevelLocals::WorldDone (void) //Added by mc if (deathmatch) { - bglobal.RemoveAllBots(this, consoleplayer != Net_Arbitrator); + BotInfo.RemoveAllBots(this, consoleplayer != Net_Arbitrator); } if (flags & LEVEL_CHANGEMAPCHEAT) @@ -1341,7 +1341,7 @@ void FLevelLocals::StartTravel () } } - bglobal.StartTravel (); + BotInfo.StartTravel (); } //========================================================================== @@ -1461,7 +1461,7 @@ int FLevelLocals::FinishTravel () pawns[pawnsnum++] = pawn; } - bglobal.FinishTravel (); + BotInfo.FinishTravel (); // make sure that, after travelling has completed, no travelling thinkers are left. // Since this list is excluded from regular thinker cleaning, anything that may survive through here @@ -2114,6 +2114,9 @@ void FLevelLocals::Mark() GC::Mark(automap); GC::Mark(interpolator.Head); GC::Mark(SequenceListHead); + GC::Mark(BotInfo.firstthing); + GC::Mark(BotInfo.body1); + GC::Mark(BotInfo.body2); canvasTextureInfo.Mark(); for (auto &c : CorpseQueue) diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 471d7b655d..35dce9eaa0 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -47,6 +47,7 @@ #include "p_tags.h" #include "p_spec.h" #include "actor.h" +#include "b_bot.h" #include "p_effect.h" #include "d_player.h" #include "p_destructible.h" @@ -464,6 +465,7 @@ public: TArray StrifeDialogues; FDialogueIDMap DialogueRoots; FDialogueMap ClassRoots; + FCajunMaster BotInfo; int ii_compatflags = 0; int ii_compatflags2 = 0; diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index b58479c080..31e9853704 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -54,6 +54,8 @@ #include "g_levellocals.h" #include "vm.h" +uint8_t globalfreeze, globalchangefreeze; // user's freeze state. + // [RH] Actually handle the cheat. The cheat code in st_stuff.c now just // writes some bytes to the network data stream, and the network code // later calls us. @@ -514,8 +516,8 @@ void cht_DoCheat (player_t *player, int cheat) break; case CHT_FREEZE: - bglobal.changefreeze ^= 1; - if (bglobal.freeze ^ bglobal.changefreeze) + globalchangefreeze ^= 1; + if (globalfreeze ^ globalchangefreeze) { msg = GStrings("TXT_FREEZEON"); } diff --git a/src/namedef.h b/src/namedef.h index 11a2850796..f47720066c 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -1077,6 +1077,5 @@ xx(InternalDynamicLight) xx(_a_chase_default) xx(MapMarker) xx(Spawn2) -xx(globalfreeze) xx(LevelLocals) xx(Level) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index d1f23094f9..a8e3c0acca 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -569,10 +569,10 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf player->respawn_time = Level->time + TICRATE; //Added by MC: Respawn bots - if (bglobal.botnum && !demoplayback) + if (Level->BotInfo.botnum && !demoplayback) { if (player->Bot != NULL) - player->Bot->t_respawn = (pr_botrespawn()%15)+((bglobal.botnum-1)*2)+TICRATE+1; + player->Bot->t_respawn = (pr_botrespawn()%15)+((Level->BotInfo.botnum-1)*2)+TICRATE+1; //Added by MC: Discard enemies. for (int i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_map.cpp b/src/p_map.cpp index ebfda7f833..eeb11b5450 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2333,7 +2333,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, if (thing->player && thing->player->Bot != NULL && thing->flags & MF_SHOOTABLE) { if (tm.sector != thing->Sector - && bglobal.IsDangerous(tm.sector)) + && thing->Level->BotInfo.IsDangerous(tm.sector)) { thing->player->Bot->prev = thing->player->Bot->dest; thing->player->Bot->dest = nullptr; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 6b11446600..dca94497a3 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3668,10 +3668,10 @@ void AActor::Tick () } } - if (bglobal.botnum && !demoplayback && + if (Level->BotInfo.botnum && !demoplayback && ((flags & (MF_SPECIAL|MF_MISSILE)) || (flags3 & MF3_ISMONSTER))) { - bglobal.BotTick(this); + Level->BotInfo.BotTick(this); } // [RH] Consider carrying sectors here @@ -4375,7 +4375,7 @@ void ConstructActor(AActor *actor, const DVector3 &pos, bool SpawningMapThing) // Actors with zero gravity need the NOGRAVITY flag set. if (actor->Gravity == 0) actor->flags |= MF_NOGRAVITY; - FRandom &rng = bglobal.m_Thinking ? pr_botspawnmobj : pr_spawnmobj; + FRandom &rng = Level->BotInfo.m_Thinking ? pr_botspawnmobj : pr_spawnmobj; if (actor->isFast() && actor->flags3 & MF3_ISMONSTER) actor->reactiontime = 0; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index b11de948c7..49e087250a 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -822,7 +822,7 @@ void CopyPlayer(player_t *dst, player_t *src, const char *name) if (dst->Bot != nullptr) { - botinfo_t *thebot = bglobal.botinfo; + botinfo_t *thebot = level.BotInfo.botinfo; while (thebot && stricmp(name, thebot->name)) { thebot = thebot->next; @@ -831,7 +831,7 @@ void CopyPlayer(player_t *dst, player_t *src, const char *name) { thebot->inuse = BOTINUSE_Yes; } - bglobal.botnum++; + level.BotInfo.botnum++; dst->userinfo.TransferFrom(uibackup2); } else @@ -979,7 +979,6 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload) { InitSkyMap(this); AirControlChanged(); - bglobal.freeze = !!(frozenstate & 2); } Behaviors.SerializeModuleStates(arc); diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 6100253015..cb1dc8243d 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -871,7 +871,7 @@ sightcounts[0]++; // Cannot see an invisible object if ((flags & SF_IGNOREVISIBILITY) == 0 && ((t2->renderflags & RF_INVISIBLE) || !t2->RenderStyle.IsVisible(t2->Alpha))) { // small chance of an attack being made anyway - if ((bglobal.m_Thinking ? pr_botchecksight() : pr_checksight()) > 50) + if ((t1->Level->BotInfo.m_Thinking ? pr_botchecksight() : pr_checksight()) > 50) { res = false; goto done; diff --git a/src/p_tick.cpp b/src/p_tick.cpp index cec6e2b062..88649f0d54 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -39,6 +39,7 @@ #include "actorinlines.h" extern gamestate_t wipegamestate; +extern uint8_t globalfreeze, globalchangefreeze; //========================================================================== // @@ -99,14 +100,14 @@ void P_Ticker (void) // This may not be perfect but it is not really relevant for sublevels that tracer homing behavior is preserved. if ((currentUILevel->maptime & 3) == 0) { - if (bglobal.changefreeze) + if (globalchangefreeze) { + globalfreeze ^= 1; + globalchangefreeze = 0; for (auto Level : AllLevels()) { - Level->frozenstate ^= 2; + Level->frozenstate = (Level->frozenstate & ~2) | (2 * globalfreeze); } - bglobal.freeze ^= 1; - bglobal.changefreeze = 0; } }