diff --git a/src/actor.h b/src/actor.h index 18c3ecb17..e896e205b 100644 --- a/src/actor.h +++ b/src/actor.h @@ -562,8 +562,14 @@ inline T *GetDefault () struct line_t; struct secplane_t; +struct msecnode_t; struct FStrifeDialogueNode; +struct FLinkContext +{ + msecnode_t *sector_list = nullptr; +}; + class DDropItem : public DObject { DECLARE_CLASS(DDropItem, DObject) @@ -1220,8 +1226,8 @@ private: bool FixMapthingPos(); public: - void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL); - void UnlinkFromWorld (); + void LinkToWorld (FLinkContext *ctx, bool spawningmapthing=false, sector_t *sector = NULL); + void UnlinkFromWorld(FLinkContext *ctx); void AdjustFloorClip (); bool InStateSequence(FState * newstate, FState * basestate); int GetTics(FState * newstate); diff --git a/src/b_game.cpp b/src/b_game.cpp index 9d6419787..b99b97a60 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -118,23 +118,24 @@ void FCajunMaster::Main () } //Check if player should go observer. Or un observe + FLinkContext ctx; if (bot_observer && !observer && !netgame) { Printf ("%s is now observer\n", players[consoleplayer].userinfo.GetName()); observer = true; - players[consoleplayer].mo->UnlinkFromWorld (); + players[consoleplayer].mo->UnlinkFromWorld (&ctx); players[consoleplayer].mo->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY; players[consoleplayer].mo->flags2 |= MF2_FLY; - players[consoleplayer].mo->LinkToWorld (); + players[consoleplayer].mo->LinkToWorld (&ctx); } else if (!bot_observer && observer && !netgame) //Go back { Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.GetName()); observer = false; - players[consoleplayer].mo->UnlinkFromWorld (); + players[consoleplayer].mo->UnlinkFromWorld (&ctx); players[consoleplayer].mo->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY; players[consoleplayer].mo->flags2 &= ~MF2_FLY; - players[consoleplayer].mo->LinkToWorld (); + players[consoleplayer].mo->LinkToWorld (&ctx); } } diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index 42af5e87f..f019a8053 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -636,14 +636,9 @@ void AInventory::BecomeItem () { if (!(flags & (MF_NOBLOCKMAP|MF_NOSECTOR))) { - UnlinkFromWorld (); - if (sector_list) - { - P_DelSeclist (sector_list); - sector_list = NULL; - } + UnlinkFromWorld (nullptr); flags |= MF_NOBLOCKMAP|MF_NOSECTOR; - LinkToWorld (); + LinkToWorld (nullptr); } RemoveFromHash (); flags &= ~MF_SPECIAL; @@ -674,9 +669,9 @@ void AInventory::BecomePickup () } if (flags & (MF_NOBLOCKMAP|MF_NOSECTOR)) { - UnlinkFromWorld (); + UnlinkFromWorld (nullptr); flags &= ~(MF_NOBLOCKMAP|MF_NOSECTOR); - LinkToWorld (); + LinkToWorld (nullptr); P_FindFloorCeiling (this); } flags = (GetDefault()->flags | MF_DROPPED) & ~MF_COUNTITEM; diff --git a/src/g_level.cpp b/src/g_level.cpp index 4bb78461a..321810589 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1196,8 +1196,7 @@ void G_StartTravel () // Only living players travel. Dead ones get a new body on the new level. if (players[i].health > 0) { - pawn->UnlinkFromWorld (); - P_DelSector_List (); + pawn->UnlinkFromWorld (nullptr); int tid = pawn->tid; // Save TID pawn->RemoveFromHash (); pawn->tid = tid; // Restore TID (but no longer linked into the hash chain) @@ -1206,8 +1205,7 @@ void G_StartTravel () for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) { inv->ChangeStatNum (STAT_TRAVELLING); - inv->UnlinkFromWorld (); - P_DelSector_List (); + inv->UnlinkFromWorld (nullptr); } } } @@ -1304,7 +1302,7 @@ void G_FinishTravel () { pawndup->Destroy(); } - pawn->LinkToWorld (); + pawn->LinkToWorld (nullptr); pawn->ClearInterpolation(); pawn->AddToHash (); pawn->SetState(pawn->SpawnState); @@ -1313,7 +1311,7 @@ void G_FinishTravel () for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) { inv->ChangeStatNum (STAT_INVENTORY); - inv->LinkToWorld (); + inv->LinkToWorld (nullptr); inv->Travelled (); } if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED) diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp index a1ffe5dc6..c09d93fd5 100644 --- a/src/g_shared/a_movingcamera.cpp +++ b/src/g_shared/a_movingcamera.cpp @@ -364,6 +364,7 @@ void APathFollower::NewNode () bool APathFollower::Interpolate () { DVector3 dpos(0, 0, 0); + FLinkContext ctx; if ((args[2] & 8) && Time > 0.f) { @@ -372,7 +373,7 @@ bool APathFollower::Interpolate () if (CurrNode->Next==NULL) return false; - UnlinkFromWorld (); + UnlinkFromWorld (&ctx); DVector3 newpos; if (args[2] & 1) { // linear @@ -389,7 +390,7 @@ bool APathFollower::Interpolate () newpos.Z = Splerp(PrevNode->Z(), CurrNode->Z(), CurrNode->Next->Z(), CurrNode->Next->Next->Z()); } SetXYZ(newpos); - LinkToWorld (); + LinkToWorld (&ctx); if (args[2] & 6) { @@ -541,10 +542,11 @@ void AActorMover::Activate (AActor *activator) tracer->flags |= MF_NOGRAVITY; if (args[2] & 128) { - tracer->UnlinkFromWorld (); + FLinkContext ctx; + tracer->UnlinkFromWorld (&ctx); tracer->flags |= MF_NOBLOCKMAP; tracer->flags &= ~MF_SOLID; - tracer->LinkToWorld (); + tracer->LinkToWorld (&ctx); } if (tracer->flags3 & MF3_ISMONSTER) { @@ -563,9 +565,10 @@ void AActorMover::Deactivate (AActor *activator) Super::Deactivate (activator); if (tracer != NULL) { - tracer->UnlinkFromWorld (); + FLinkContext ctx; + tracer->UnlinkFromWorld (&ctx); tracer->flags = ActorFlags::FromInt (special1); - tracer->LinkToWorld (); + tracer->LinkToWorld (&ctx); tracer->flags2 = ActorFlags2::FromInt (special2); } } diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index e292447bf..4136ec331 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -5229,12 +5229,13 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, double xydist, double zdist) } else { - self->UnlinkFromWorld (); + FLinkContext ctx; + self->UnlinkFromWorld (&ctx); self->flags |= MF_NOBLOCKMAP; // We need to do portal offsetting here explicitly, because SetXY cannot do that. newpos -= self->Pos().XY(); self->SetXY(self->Vec2Offset(newpos.X, newpos.Y)); - self->LinkToWorld (); + self->LinkToWorld (&ctx); } self->WeaveIndexXY = weaveXY; } @@ -6862,17 +6863,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetSize) double oldradius = self->radius; double oldheight = self->Height; - self->UnlinkFromWorld(); + FLinkContext ctx; + self->UnlinkFromWorld(&ctx); self->radius = newradius; self->Height = newheight; - self->LinkToWorld(); + self->LinkToWorld(&ctx); if (testpos && !P_TestMobjLocation(self)) { - self->UnlinkFromWorld(); + self->UnlinkFromWorld(&ctx); self->radius = oldradius; self->Height = oldheight; - self->LinkToWorld(); + self->LinkToWorld(&ctx); ACTION_RETURN_BOOL(false); } diff --git a/src/p_local.h b/src/p_local.h index 4244005c3..25b465d26 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -245,10 +245,6 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false, // -// If "floatok" true, move would be ok -// if within "tmfloorz - tmceilingz". -extern msecnode_t *sector_list; // phares 3/16/98 - struct spechit_t { line_t *line; @@ -395,11 +391,10 @@ enum int P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, FName damageType, int flags, int fulldamagedistance=0); -void P_DelSector_List(); void P_DelSeclist(msecnode_t *); // phares 3/16/98 msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist); msecnode_t* P_DelSecnode(msecnode_t *, msecnode_t *sector_t::*head); -void P_CreateSecNodeList(AActor*); // phares 3/14/98 +msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list); void P_LinkRenderSectors(AActor*); void P_UnlinkRenderSectors(AActor*); double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98 diff --git a/src/p_map.cpp b/src/p_map.cpp index e90d24bed..9dcd165c2 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -82,9 +82,6 @@ static FRandom pr_crunch("DoCrunch"); TArray spechit; TArray portalhit; -// Temporary holder for thing_sectorlist threads -msecnode_t* sector_list = NULL; // phares 3/16/98 - //========================================================================== // // FindRefPoint @@ -2390,10 +2387,11 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, FLinePortal *port = ld->getPortal(); if (port->mType == PORTT_LINKED) { - thing->UnlinkFromWorld(); + FLinkContext ctx; + thing->UnlinkFromWorld(&ctx); thing->SetXY(tm.pos + port->mDisplacement); thing->Prev += port->mDisplacement; - thing->LinkToWorld(); + thing->LinkToWorld(&ctx); P_FindFloorCeiling(thing); portalcrossed = true; tm.portalstep = false; @@ -2414,11 +2412,12 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, thing->flags6 &= ~MF6_INTRYMOVE; return false; } - thing->UnlinkFromWorld(); + FLinkContext ctx; + thing->UnlinkFromWorld(&ctx); thing->SetXYZ(pos); P_TranslatePortalVXVY(ld, thing->Vel.X, thing->Vel.Y); P_TranslatePortalAngle(ld, thing->Angles.Yaw); - thing->LinkToWorld(); + thing->LinkToWorld(&ctx); P_FindFloorCeiling(thing); thing->ClearInterpolation(); portalcrossed = true; @@ -2459,7 +2458,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, if (!portalcrossed) { // the move is ok, so link the thing into its new position - thing->UnlinkFromWorld(); + FLinkContext ctx; + thing->UnlinkFromWorld(&ctx); oldsector = thing->Sector; thing->floorz = tm.floorz; @@ -2472,7 +2472,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, thing->ceilingsector = tm.ceilingsector; thing->SetXY(pos); - thing->LinkToWorld(); + thing->LinkToWorld(&ctx); } if (thing->flags2 & MF2_FLOORCLIP) @@ -2565,13 +2565,14 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, // If the actor stepped through a ceiling portal we need to reacquire the actual position info after the transition if (tm.portalstep) { + FLinkContext ctx; DVector3 oldpos = thing->Pos(); - thing->UnlinkFromWorld(); + thing->UnlinkFromWorld(&ctx); thing->SetXYZ(thing->PosRelative(thing->Sector->GetOppositePortalGroup(sector_t::ceiling))); thing->Prev = thing->Pos() - oldpos; thing->Sector = P_PointInSector(thing->Pos()); thing->PrevPortalGroup = thing->Sector->PortalGroup; - thing->LinkToWorld(); + thing->LinkToWorld(&ctx); P_FindFloorCeiling(thing); } @@ -6532,23 +6533,6 @@ msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead) return NULL; } // phares 3/13/98 -//============================================================================= -// -// P_DelSector_List -// -// Deletes the sector_list and NULLs it. -// -//============================================================================= - -void P_DelSector_List() -{ - if (sector_list != NULL) - { - P_DelSeclist(sector_list); - sector_list = NULL; - } -} - //============================================================================= // // P_DelSeclist @@ -6572,7 +6556,7 @@ void P_DelSeclist(msecnode_t *node) // //============================================================================= -void P_CreateSecNodeList(AActor *thing) +msecnode_t *P_CreateSecNodeList(AActor *thing, msecnode_t *sector_list) { msecnode_t *node; @@ -6638,6 +6622,7 @@ void P_CreateSecNodeList(AActor *thing) node = node->m_tnext; } } + return sector_list; } diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 57c86587d..d7d5fd658 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -242,9 +242,9 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, co // //========================================================================== -void AActor::UnlinkFromWorld () +void AActor::UnlinkFromWorld (FLinkContext *ctx) { - sector_list = NULL; + if (ctx != nullptr) ctx->sector_list = nullptr; if (!(flags & MF_NOSECTOR)) { // invisible things don't need to be in sector list @@ -275,7 +275,8 @@ void AActor::UnlinkFromWorld () // If this Thing is being removed entirely, then the calling // routine will clear out the nodes in sector_list. - sector_list = touching_sectorlist; + if (ctx != nullptr) ctx->sector_list = touching_sectorlist; + else P_DelSeclist(touching_sectorlist); touching_sectorlist = NULL; //to be restored by P_SetThingPosition P_UnlinkRenderSectors(this); @@ -390,7 +391,7 @@ bool AActor::FixMapthingPos() DEFINE_ACTION_FUNCTION(AActor, UnlinkFromWorld) { PARAM_SELF_PROLOGUE(AActor); - self->UnlinkFromWorld(); + self->UnlinkFromWorld(nullptr); // fixme return 0; } @@ -403,7 +404,7 @@ DEFINE_ACTION_FUNCTION(AActor, UnlinkFromWorld) // //========================================================================== -void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) +void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sector) { bool spawning = spawningmapthing; @@ -455,9 +456,7 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) // When a node is deleted, its sector links (the links starting // at sector_t->touching_thinglist) are broken. When a node is // added, new sector links are created. - P_CreateSecNodeList(this); - touching_sectorlist = sector_list; // Attach to thing - sector_list = NULL; // clear for next time + touching_sectorlist = P_CreateSecNodeList(this, ctx != nullptr? ctx->sector_list : nullptr); // Attach to thing P_LinkRenderSectors(this); } @@ -522,15 +521,16 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) DEFINE_ACTION_FUNCTION(AActor, LinkToWorld) { PARAM_SELF_PROLOGUE(AActor); - self->LinkToWorld(); + self->LinkToWorld(nullptr); // fixme return 0; } void AActor::SetOrigin(double x, double y, double z, bool moving) { - UnlinkFromWorld (); + FLinkContext ctx; + UnlinkFromWorld (&ctx); SetXYZ(x, y, z); - LinkToWorld (); + LinkToWorld (&ctx); P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS); if (!moving) ClearInterpolation(); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index aa0ce7096..1955f6b4e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -514,7 +514,7 @@ void AActor::PostSerialize() touching_sectorlist = NULL; if (touching_render_sectors) delete touching_render_sectors; touching_render_sectors = NULL; - LinkToWorld(false, Sector); + LinkToWorld(nullptr, false, Sector); AddToHash(); if (player) @@ -3690,12 +3690,13 @@ DVector3 AActor::GetPortalTransition(double byoffset, sector_t **pSec) void AActor::CheckPortalTransition(bool islinked) { bool moved = false; + FLinkContext ctx; while (!Sector->PortalBlocksMovement(sector_t::ceiling)) { if (Z() >= Sector->GetPortalPlaneZ(sector_t::ceiling)) { DVector3 oldpos = Pos(); - if (islinked && !moved) UnlinkFromWorld(); + if (islinked && !moved) UnlinkFromWorld(&ctx); SetXYZ(PosRelative(Sector->GetOppositePortalGroup(sector_t::ceiling))); Prev = Pos() - oldpos; Sector = P_PointInSector(Pos()); @@ -3712,7 +3713,7 @@ void AActor::CheckPortalTransition(bool islinked) if (Z() < portalz && floorz < portalz) { DVector3 oldpos = Pos(); - if (islinked && !moved) UnlinkFromWorld(); + if (islinked && !moved) UnlinkFromWorld(&ctx); SetXYZ(PosRelative(Sector->GetOppositePortalGroup(sector_t::floor))); Prev = Pos() - oldpos; Sector = P_PointInSector(Pos()); @@ -3722,7 +3723,7 @@ void AActor::CheckPortalTransition(bool islinked) else break; } } - if (islinked && moved) LinkToWorld(); + if (islinked && moved) LinkToWorld(&ctx); } // @@ -3785,11 +3786,12 @@ void AActor::Tick () if (!Vel.isZero() || !(flags & MF_NOBLOCKMAP)) { - UnlinkFromWorld(); + FLinkContext ctx; + UnlinkFromWorld(&ctx); flags |= MF_NOBLOCKMAP; SetXYZ(Vec3Offset(Vel)); CheckPortalTransition(false); - LinkToWorld(); + LinkToWorld(&ctx); } } else @@ -4553,7 +4555,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a actor->Speed = actor->GetClass()->FastSpeed; // set subsector and/or block links - actor->LinkToWorld (SpawningMapThing); + actor->LinkToWorld (nullptr, SpawningMapThing); actor->ClearInterpolation(); actor->dropoffz = actor->floorz = actor->Sector->floorplane.ZatPoint(pos); @@ -4930,12 +4932,9 @@ void AActor::Destroy () RemoveFromHash (); // unlink from sector and block lists - UnlinkFromWorld (); + UnlinkFromWorld (nullptr); flags |= MF_NOSECTOR|MF_NOBLOCKMAP; - // Delete all nodes on the current sector_list phares 3/16/98 - P_DelSector_List(); - // Transform any playing sound into positioned, non-actor sounds. S_RelinkSound (this, NULL); @@ -7486,9 +7485,10 @@ void AActor::RestoreSpecialPosition() // Move item back to its original location DVector2 sp = SpawnPoint; - UnlinkFromWorld(); + FLinkContext ctx; + UnlinkFromWorld(&ctx); SetXY(sp); - LinkToWorld(true); + LinkToWorld(&ctx, true); SetZ(Sector->floorplane.ZatPoint(sp)); P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS | FFCF_NOPORTALS); // no portal checks here so that things get spawned in this sector. diff --git a/src/p_user.cpp b/src/p_user.cpp index 47c64d063..40a3cb2f6 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2939,7 +2939,8 @@ void P_UnPredictPlayer () // could cause it to change during prediction. player->camera = savedcamera; - act->UnlinkFromWorld(); + FLinkContext ctx; + act->UnlinkFromWorld(&ctx); memcpy(&act->snext, PredictionActorBackup, sizeof(APlayerPawn) - ((BYTE *)&act->snext - (BYTE *)act)); // The blockmap ordering needs to remain unchanged, too. @@ -2968,7 +2969,7 @@ void P_UnPredictPlayer () } // Destroy old refrences - msecnode_t *node = sector_list; + msecnode_t *node = ctx.sector_list; while (node) { node->m_thing = NULL; @@ -2976,22 +2977,23 @@ void P_UnPredictPlayer () } // Make the sector_list match the player's touching_sectorlist before it got predicted. - P_DelSeclist(sector_list); - sector_list = NULL; + P_DelSeclist(ctx.sector_list); + ctx.sector_list = NULL; for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) { - sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list, PredictionTouchingSectorsBackup[i]->touching_thinglist); + ctx.sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, ctx.sector_list, PredictionTouchingSectorsBackup[i]->touching_thinglist); } - act->touching_sectorlist = sector_list; // Attach to thing - sector_list = NULL; // clear for next time + act->touching_sectorlist = ctx.sector_list; // Attach to thing + ctx.sector_list = NULL; // clear for next time - node = sector_list; + // Huh??? + node = ctx.sector_list; while (node) { if (node->m_thing == NULL) { - if (node == sector_list) - sector_list = node->m_tnext; + if (node == ctx.sector_list) + ctx.sector_list = node->m_tnext; node = P_DelSecnode(node, §or_t::touching_thinglist); } else diff --git a/src/portal.cpp b/src/portal.cpp index f1454cdc6..4b8a81dc1 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -1140,8 +1140,9 @@ void P_CreateLinkedPortals() P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->Pos(), actor->Top(), actor->radius, check); if (check.Size() > 0) { - actor->UnlinkFromWorld(); - actor->LinkToWorld(); + FLinkContext ctx; + actor->UnlinkFromWorld(&ctx); + actor->LinkToWorld(&ctx); } } } diff --git a/src/r_things.cpp b/src/r_things.cpp index 4cf056aed..8d326b319 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1217,7 +1217,6 @@ static void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID p // [RH] Save which side of heightsec sprite is on here. void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) { - AActor *thing; F3DFloor *fakeceiling = NULL; F3DFloor *fakefloor = NULL; diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 08dd62dfb..27b7ab2d3 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -216,9 +216,10 @@ bool ModActorFlag(AActor *actor, FString &flagname, bool set, bool printerror) // If these 2 flags get changed we need to update the blockmap and sector links. bool linkchange = flagp == &actor->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR); - if (linkchange) actor->UnlinkFromWorld(); + FLinkContext ctx; + if (linkchange) actor->UnlinkFromWorld(&ctx); ModActorFlag(actor, fd, set); - if (linkchange) actor->LinkToWorld(); + if (linkchange) actor->LinkToWorld(&ctx); } if (actor->CountsAsKill() && actor->health > 0) ++level.total_monsters;