This commit is contained in:
Rachael Alexanderson 2016-12-26 15:46:17 -05:00
commit 7ea4c9508f
21 changed files with 174 additions and 137 deletions

10
game-music-emu/gme/gme_types.h Normal file → Executable file
View file

@ -1,11 +1,13 @@
#ifndef GME_TYPES_H #ifndef GME_TYPES_H
#define GME_TYPES_H #define GME_TYPES_H
/* /* CMake will either define the following to 1, or #undef it,
* This is a default gme_types.h for use when *not* using * depending on the options passed to CMake. This is used to
* CMake. If CMake is in use gme_types.h.in will be * conditionally compile in the various emulator types.
* processed instead. *
* See gme_type_list() in gme.cpp
*/ */
#define USE_GME_AY #define USE_GME_AY
#define USE_GME_GBS #define USE_GME_GBS
#define USE_GME_GYM #define USE_GME_GYM

View file

@ -33,6 +33,7 @@
// States are tied to finite states are tied to animation frames. // States are tied to finite states are tied to animation frames.
#include "info.h" #include "info.h"
#include <forward_list>
#include "doomdef.h" #include "doomdef.h"
#include "textures/textures.h" #include "textures/textures.h"
#include "r_data/renderstyle.h" #include "r_data/renderstyle.h"
@ -561,8 +562,15 @@ inline T *GetDefault ()
struct line_t; struct line_t;
struct secplane_t; struct secplane_t;
struct msecnode_t;
struct FStrifeDialogueNode; struct FStrifeDialogueNode;
struct FLinkContext
{
msecnode_t *sector_list = nullptr;
msecnode_t *render_list = nullptr;
};
class DDropItem : public DObject class DDropItem : public DObject
{ {
DECLARE_CLASS(DDropItem, DObject) DECLARE_CLASS(DDropItem, DObject)
@ -1035,6 +1043,7 @@ public:
struct sector_t *ceilingsector; struct sector_t *ceilingsector;
FTextureID ceilingpic; // contacted sec ceilingpic FTextureID ceilingpic; // contacted sec ceilingpic
double radius, Height; // for movement checking double radius, Height; // for movement checking
double renderradius;
double projectilepassheight; // height for clipping projectile movement against this actor double projectilepassheight; // height for clipping projectile movement against this actor
@ -1141,6 +1150,8 @@ public:
struct msecnode_t *touching_sectorlist; // phares 3/14/98 struct msecnode_t *touching_sectorlist; // phares 3/14/98
struct msecnode_t *render_sectorlist; // same for cross-sectorportal rendering struct msecnode_t *render_sectorlist; // same for cross-sectorportal rendering
struct portnode_t *render_portallist; // and for cross-lineportal struct portnode_t *render_portallist; // and for cross-lineportal
struct msecnode_t *touching_rendersectors; // this is the list of sectors that this thing interesects with it's max(radius, renderradius).
int validcount;
TObjPtr<AInventory> Inventory; // [RH] This actor's inventory TObjPtr<AInventory> Inventory; // [RH] This actor's inventory
@ -1216,8 +1227,8 @@ private:
bool FixMapthingPos(); bool FixMapthingPos();
public: public:
void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL); void LinkToWorld (FLinkContext *ctx, bool spawningmapthing=false, sector_t *sector = NULL);
void UnlinkFromWorld (); void UnlinkFromWorld(FLinkContext *ctx);
void AdjustFloorClip (); void AdjustFloorClip ();
bool InStateSequence(FState * newstate, FState * basestate); bool InStateSequence(FState * newstate, FState * basestate);
int GetTics(FState * newstate); int GetTics(FState * newstate);

View file

@ -118,23 +118,24 @@ void FCajunMaster::Main ()
} }
//Check if player should go observer. Or un observe //Check if player should go observer. Or un observe
FLinkContext ctx;
if (bot_observer && !observer && !netgame) if (bot_observer && !observer && !netgame)
{ {
Printf ("%s is now observer\n", players[consoleplayer].userinfo.GetName()); Printf ("%s is now observer\n", players[consoleplayer].userinfo.GetName());
observer = true; 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->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY;
players[consoleplayer].mo->flags2 |= MF2_FLY; players[consoleplayer].mo->flags2 |= MF2_FLY;
players[consoleplayer].mo->LinkToWorld (); players[consoleplayer].mo->LinkToWorld (&ctx);
} }
else if (!bot_observer && observer && !netgame) //Go back else if (!bot_observer && observer && !netgame) //Go back
{ {
Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.GetName()); Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.GetName());
observer = false; 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->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY;
players[consoleplayer].mo->flags2 &= ~MF2_FLY; players[consoleplayer].mo->flags2 &= ~MF2_FLY;
players[consoleplayer].mo->LinkToWorld (); players[consoleplayer].mo->LinkToWorld (&ctx);
} }
} }

View file

@ -636,14 +636,9 @@ void AInventory::BecomeItem ()
{ {
if (!(flags & (MF_NOBLOCKMAP|MF_NOSECTOR))) if (!(flags & (MF_NOBLOCKMAP|MF_NOSECTOR)))
{ {
UnlinkFromWorld (); UnlinkFromWorld (nullptr);
if (sector_list)
{
P_DelSeclist (sector_list);
sector_list = NULL;
}
flags |= MF_NOBLOCKMAP|MF_NOSECTOR; flags |= MF_NOBLOCKMAP|MF_NOSECTOR;
LinkToWorld (); LinkToWorld (nullptr);
} }
RemoveFromHash (); RemoveFromHash ();
flags &= ~MF_SPECIAL; flags &= ~MF_SPECIAL;
@ -674,9 +669,9 @@ void AInventory::BecomePickup ()
} }
if (flags & (MF_NOBLOCKMAP|MF_NOSECTOR)) if (flags & (MF_NOBLOCKMAP|MF_NOSECTOR))
{ {
UnlinkFromWorld (); UnlinkFromWorld (nullptr);
flags &= ~(MF_NOBLOCKMAP|MF_NOSECTOR); flags &= ~(MF_NOBLOCKMAP|MF_NOSECTOR);
LinkToWorld (); LinkToWorld (nullptr);
P_FindFloorCeiling (this); P_FindFloorCeiling (this);
} }
flags = (GetDefault()->flags | MF_DROPPED) & ~MF_COUNTITEM; flags = (GetDefault()->flags | MF_DROPPED) & ~MF_COUNTITEM;

View file

@ -1196,8 +1196,7 @@ void G_StartTravel ()
// Only living players travel. Dead ones get a new body on the new level. // Only living players travel. Dead ones get a new body on the new level.
if (players[i].health > 0) if (players[i].health > 0)
{ {
pawn->UnlinkFromWorld (); pawn->UnlinkFromWorld (nullptr);
P_DelSector_List ();
int tid = pawn->tid; // Save TID int tid = pawn->tid; // Save TID
pawn->RemoveFromHash (); pawn->RemoveFromHash ();
pawn->tid = tid; // Restore TID (but no longer linked into the hash chain) 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) for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory)
{ {
inv->ChangeStatNum (STAT_TRAVELLING); inv->ChangeStatNum (STAT_TRAVELLING);
inv->UnlinkFromWorld (); inv->UnlinkFromWorld (nullptr);
P_DelSector_List ();
} }
} }
} }
@ -1304,7 +1302,7 @@ void G_FinishTravel ()
{ {
pawndup->Destroy(); pawndup->Destroy();
} }
pawn->LinkToWorld (); pawn->LinkToWorld (nullptr);
pawn->ClearInterpolation(); pawn->ClearInterpolation();
pawn->AddToHash (); pawn->AddToHash ();
pawn->SetState(pawn->SpawnState); pawn->SetState(pawn->SpawnState);
@ -1313,7 +1311,7 @@ void G_FinishTravel ()
for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory)
{ {
inv->ChangeStatNum (STAT_INVENTORY); inv->ChangeStatNum (STAT_INVENTORY);
inv->LinkToWorld (); inv->LinkToWorld (nullptr);
inv->Travelled (); inv->Travelled ();
} }
if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED) if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED)

View file

@ -12,6 +12,7 @@
#include <zlib.h> #include <zlib.h>
#include <new> #include <new>
#include <algorithm> #include <algorithm>
#include <forward_list>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <cassert> #include <cassert>

View file

@ -364,6 +364,7 @@ void APathFollower::NewNode ()
bool APathFollower::Interpolate () bool APathFollower::Interpolate ()
{ {
DVector3 dpos(0, 0, 0); DVector3 dpos(0, 0, 0);
FLinkContext ctx;
if ((args[2] & 8) && Time > 0.f) if ((args[2] & 8) && Time > 0.f)
{ {
@ -372,7 +373,7 @@ bool APathFollower::Interpolate ()
if (CurrNode->Next==NULL) return false; if (CurrNode->Next==NULL) return false;
UnlinkFromWorld (); UnlinkFromWorld (&ctx);
DVector3 newpos; DVector3 newpos;
if (args[2] & 1) if (args[2] & 1)
{ // linear { // linear
@ -389,7 +390,7 @@ bool APathFollower::Interpolate ()
newpos.Z = Splerp(PrevNode->Z(), CurrNode->Z(), CurrNode->Next->Z(), CurrNode->Next->Next->Z()); newpos.Z = Splerp(PrevNode->Z(), CurrNode->Z(), CurrNode->Next->Z(), CurrNode->Next->Next->Z());
} }
SetXYZ(newpos); SetXYZ(newpos);
LinkToWorld (); LinkToWorld (&ctx);
if (args[2] & 6) if (args[2] & 6)
{ {
@ -541,10 +542,11 @@ void AActorMover::Activate (AActor *activator)
tracer->flags |= MF_NOGRAVITY; tracer->flags |= MF_NOGRAVITY;
if (args[2] & 128) if (args[2] & 128)
{ {
tracer->UnlinkFromWorld (); FLinkContext ctx;
tracer->UnlinkFromWorld (&ctx);
tracer->flags |= MF_NOBLOCKMAP; tracer->flags |= MF_NOBLOCKMAP;
tracer->flags &= ~MF_SOLID; tracer->flags &= ~MF_SOLID;
tracer->LinkToWorld (); tracer->LinkToWorld (&ctx);
} }
if (tracer->flags3 & MF3_ISMONSTER) if (tracer->flags3 & MF3_ISMONSTER)
{ {
@ -563,9 +565,10 @@ void AActorMover::Deactivate (AActor *activator)
Super::Deactivate (activator); Super::Deactivate (activator);
if (tracer != NULL) if (tracer != NULL)
{ {
tracer->UnlinkFromWorld (); FLinkContext ctx;
tracer->UnlinkFromWorld (&ctx);
tracer->flags = ActorFlags::FromInt (special1); tracer->flags = ActorFlags::FromInt (special1);
tracer->LinkToWorld (); tracer->LinkToWorld (&ctx);
tracer->flags2 = ActorFlags2::FromInt (special2); tracer->flags2 = ActorFlags2::FromInt (special2);
} }
} }

View file

@ -5229,12 +5229,13 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, double xydist, double zdist)
} }
else else
{ {
self->UnlinkFromWorld (); FLinkContext ctx;
self->UnlinkFromWorld (&ctx);
self->flags |= MF_NOBLOCKMAP; self->flags |= MF_NOBLOCKMAP;
// We need to do portal offsetting here explicitly, because SetXY cannot do that. // We need to do portal offsetting here explicitly, because SetXY cannot do that.
newpos -= self->Pos().XY(); newpos -= self->Pos().XY();
self->SetXY(self->Vec2Offset(newpos.X, newpos.Y)); self->SetXY(self->Vec2Offset(newpos.X, newpos.Y));
self->LinkToWorld (); self->LinkToWorld (&ctx);
} }
self->WeaveIndexXY = weaveXY; self->WeaveIndexXY = weaveXY;
} }
@ -6862,17 +6863,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetSize)
double oldradius = self->radius; double oldradius = self->radius;
double oldheight = self->Height; double oldheight = self->Height;
self->UnlinkFromWorld(); FLinkContext ctx;
self->UnlinkFromWorld(&ctx);
self->radius = newradius; self->radius = newradius;
self->Height = newheight; self->Height = newheight;
self->LinkToWorld(); self->LinkToWorld(&ctx);
if (testpos && !P_TestMobjLocation(self)) if (testpos && !P_TestMobjLocation(self))
{ {
self->UnlinkFromWorld(); self->UnlinkFromWorld(&ctx);
self->radius = oldradius; self->radius = oldradius;
self->Height = oldheight; self->Height = oldheight;
self->LinkToWorld(); self->LinkToWorld(&ctx);
ACTION_RETURN_BOOL(false); ACTION_RETURN_BOOL(false);
} }

View file

@ -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 struct spechit_t
{ {
line_t *line; line_t *line;
@ -395,11 +391,10 @@ enum
int P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, int P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance,
FName damageType, int flags, int fulldamagedistance=0); FName damageType, int flags, int fulldamagedistance=0);
void P_DelSector_List(); void P_DelSeclist(msecnode_t *, msecnode_t *sector_t::*seclisthead);
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_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist);
msecnode_t* P_DelSecnode(msecnode_t *, msecnode_t *sector_t::*head); 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, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead);
double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98 double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98
double P_GetFriction(const AActor *mo, double *frictionfactor); double P_GetFriction(const AActor *mo, double *frictionfactor);

View file

@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <algorithm>
#include "templates.h" #include "templates.h"
@ -81,9 +82,6 @@ static FRandom pr_crunch("DoCrunch");
TArray<spechit_t> spechit; TArray<spechit_t> spechit;
TArray<spechit_t> portalhit; TArray<spechit_t> portalhit;
// Temporary holder for thing_sectorlist threads
msecnode_t* sector_list = NULL; // phares 3/16/98
//========================================================================== //==========================================================================
// //
// FindRefPoint // FindRefPoint
@ -2389,10 +2387,11 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
FLinePortal *port = ld->getPortal(); FLinePortal *port = ld->getPortal();
if (port->mType == PORTT_LINKED) if (port->mType == PORTT_LINKED)
{ {
thing->UnlinkFromWorld(); FLinkContext ctx;
thing->UnlinkFromWorld(&ctx);
thing->SetXY(tm.pos + port->mDisplacement); thing->SetXY(tm.pos + port->mDisplacement);
thing->Prev += port->mDisplacement; thing->Prev += port->mDisplacement;
thing->LinkToWorld(); thing->LinkToWorld(&ctx);
P_FindFloorCeiling(thing); P_FindFloorCeiling(thing);
portalcrossed = true; portalcrossed = true;
tm.portalstep = false; tm.portalstep = false;
@ -2413,11 +2412,12 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
thing->flags6 &= ~MF6_INTRYMOVE; thing->flags6 &= ~MF6_INTRYMOVE;
return false; return false;
} }
thing->UnlinkFromWorld(); FLinkContext ctx;
thing->UnlinkFromWorld(&ctx);
thing->SetXYZ(pos); thing->SetXYZ(pos);
P_TranslatePortalVXVY(ld, thing->Vel.X, thing->Vel.Y); P_TranslatePortalVXVY(ld, thing->Vel.X, thing->Vel.Y);
P_TranslatePortalAngle(ld, thing->Angles.Yaw); P_TranslatePortalAngle(ld, thing->Angles.Yaw);
thing->LinkToWorld(); thing->LinkToWorld(&ctx);
P_FindFloorCeiling(thing); P_FindFloorCeiling(thing);
thing->ClearInterpolation(); thing->ClearInterpolation();
portalcrossed = true; portalcrossed = true;
@ -2458,7 +2458,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
if (!portalcrossed) if (!portalcrossed)
{ {
// the move is ok, so link the thing into its new position // the move is ok, so link the thing into its new position
thing->UnlinkFromWorld(); FLinkContext ctx;
thing->UnlinkFromWorld(&ctx);
oldsector = thing->Sector; oldsector = thing->Sector;
thing->floorz = tm.floorz; thing->floorz = tm.floorz;
@ -2471,7 +2472,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
thing->ceilingsector = tm.ceilingsector; thing->ceilingsector = tm.ceilingsector;
thing->SetXY(pos); thing->SetXY(pos);
thing->LinkToWorld(); thing->LinkToWorld(&ctx);
} }
if (thing->flags2 & MF2_FLOORCLIP) if (thing->flags2 & MF2_FLOORCLIP)
@ -2564,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 the actor stepped through a ceiling portal we need to reacquire the actual position info after the transition
if (tm.portalstep) if (tm.portalstep)
{ {
FLinkContext ctx;
DVector3 oldpos = thing->Pos(); DVector3 oldpos = thing->Pos();
thing->UnlinkFromWorld(); thing->UnlinkFromWorld(&ctx);
thing->SetXYZ(thing->PosRelative(thing->Sector->GetOppositePortalGroup(sector_t::ceiling))); thing->SetXYZ(thing->PosRelative(thing->Sector->GetOppositePortalGroup(sector_t::ceiling)));
thing->Prev = thing->Pos() - oldpos; thing->Prev = thing->Pos() - oldpos;
thing->Sector = P_PointInSector(thing->Pos()); thing->Sector = P_PointInSector(thing->Pos());
thing->PrevPortalGroup = thing->Sector->PortalGroup; thing->PrevPortalGroup = thing->Sector->PortalGroup;
thing->LinkToWorld(); thing->LinkToWorld(&ctx);
P_FindFloorCeiling(thing); P_FindFloorCeiling(thing);
} }
@ -6531,23 +6533,6 @@ msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead)
return NULL; return NULL;
} // phares 3/13/98 } // 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 // P_DelSeclist
@ -6556,10 +6541,10 @@ void P_DelSector_List()
// //
//============================================================================= //=============================================================================
void P_DelSeclist(msecnode_t *node) void P_DelSeclist(msecnode_t *node, msecnode_t *sector_t::*sechead)
{ {
while (node) while (node)
node = P_DelSecnode(node, &sector_t::touching_thinglist); node = P_DelSecnode(node, sechead);
} }
//============================================================================= //=============================================================================
@ -6571,7 +6556,7 @@ void P_DelSeclist(msecnode_t *node)
// //
//============================================================================= //=============================================================================
void P_CreateSecNodeList(AActor *thing) msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead)
{ {
msecnode_t *node; msecnode_t *node;
@ -6587,7 +6572,7 @@ void P_CreateSecNodeList(AActor *thing)
node = node->m_tnext; node = node->m_tnext;
} }
FBoundingBox box(thing->X(), thing->Y(), thing->radius); FBoundingBox box(thing->X(), thing->Y(), radius);
FBlockLinesIterator it(box); FBlockLinesIterator it(box);
line_t *ld; line_t *ld;
@ -6603,7 +6588,7 @@ void P_CreateSecNodeList(AActor *thing)
// allowed to move to this position, then the sector_list // allowed to move to this position, then the sector_list
// will be attached to the Thing's AActor at touching_sectorlist. // will be attached to the Thing's AActor at touching_sectorlist.
sector_list = P_AddSecnode(ld->frontsector, thing, sector_list, ld->frontsector->touching_thinglist); sector_list = P_AddSecnode(ld->frontsector, thing, sector_list, ld->frontsector->*seclisthead);
// Don't assume all lines are 2-sided, since some Things // Don't assume all lines are 2-sided, since some Things
// like MT_TFOG are allowed regardless of whether their radius takes // like MT_TFOG are allowed regardless of whether their radius takes
@ -6613,12 +6598,12 @@ void P_CreateSecNodeList(AActor *thing)
// Use sidedefs instead of 2s flag to determine two-sidedness. // Use sidedefs instead of 2s flag to determine two-sidedness.
if (ld->backsector) if (ld->backsector)
sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->touching_thinglist); sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->*seclisthead);
} }
// Add the sector of the (x,y) point to sector_list. // Add the sector of the (x,y) point to sector_list.
sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->touching_thinglist); sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->*seclisthead);
// Now delete any nodes that won't be used. These are the ones where // Now delete any nodes that won't be used. These are the ones where
// m_thing is still NULL. // m_thing is still NULL.
@ -6630,16 +6615,16 @@ void P_CreateSecNodeList(AActor *thing)
{ {
if (node == sector_list) if (node == sector_list)
sector_list = node->m_tnext; sector_list = node->m_tnext;
node = P_DelSecnode(node, &sector_t::touching_thinglist); node = P_DelSecnode(node, seclisthead);
} }
else else
{ {
node = node->m_tnext; node = node->m_tnext;
} }
} }
return sector_list;
} }
//============================================================================= //=============================================================================
// //
// P_DelPortalnode // P_DelPortalnode
@ -6770,6 +6755,7 @@ void AActor::UpdateRenderSectorList()
sec = P_PointInSector(newpos); sec = P_PointInSector(newpos);
render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist); render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist);
} }
sec = Sector;
lasth = FLT_MAX; lasth = FLT_MAX;
while (!sec->PortalBlocksMovement(sector_t::floor)) while (!sec->PortalBlocksMovement(sector_t::floor))
{ {

View file

@ -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)) if (!(flags & MF_NOSECTOR))
{ {
// invisible things don't need to be in sector list // invisible things don't need to be in sector list
@ -271,12 +271,19 @@ void AActor::UnlinkFromWorld ()
// put it back into touching_sectorlist. It's done this way to // put it back into touching_sectorlist. It's done this way to
// avoid a lot of deleting/creating for nodes, when most of the // avoid a lot of deleting/creating for nodes, when most of the
// time you just get back what you deleted anyway. // time you just get back what you deleted anyway.
//
// 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)
touching_sectorlist = NULL; //to be restored by P_SetThingPosition {
ctx->sector_list = touching_sectorlist;
ctx->render_list = touching_rendersectors;
}
else
{
P_DelSeclist(touching_sectorlist, &sector_t::touching_thinglist);
P_DelSeclist(touching_rendersectors, &sector_t::touching_renderthings);
}
touching_sectorlist = nullptr; //to be restored by P_SetThingPosition
touching_rendersectors = nullptr;
} }
} }
@ -388,7 +395,7 @@ bool AActor::FixMapthingPos()
DEFINE_ACTION_FUNCTION(AActor, UnlinkFromWorld) DEFINE_ACTION_FUNCTION(AActor, UnlinkFromWorld)
{ {
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
self->UnlinkFromWorld(); self->UnlinkFromWorld(nullptr); // fixme
return 0; return 0;
} }
@ -401,7 +408,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; bool spawning = spawningmapthing;
@ -453,9 +460,13 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector)
// When a node is deleted, its sector links (the links starting // When a node is deleted, its sector links (the links starting
// at sector_t->touching_thinglist) are broken. When a node is // at sector_t->touching_thinglist) are broken. When a node is
// added, new sector links are created. // added, new sector links are created.
P_CreateSecNodeList(this); touching_sectorlist = P_CreateSecNodeList(this, radius, ctx != nullptr? ctx->sector_list : nullptr, &sector_t::touching_thinglist); // Attach to thing
touching_sectorlist = sector_list; // Attach to thing if (renderradius >= 0) touching_rendersectors = P_CreateSecNodeList(this, MAX(radius, renderradius), ctx != nullptr ? ctx->render_list : nullptr, &sector_t::touching_renderthings);
sector_list = NULL; // clear for next time else
{
touching_rendersectors = nullptr;
if (ctx != nullptr) P_DelSeclist(ctx->render_list, &sector_t::touching_renderthings);
}
} }
@ -518,15 +529,16 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector)
DEFINE_ACTION_FUNCTION(AActor, LinkToWorld) DEFINE_ACTION_FUNCTION(AActor, LinkToWorld)
{ {
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
self->LinkToWorld(); self->LinkToWorld(nullptr); // fixme
return 0; return 0;
} }
void AActor::SetOrigin(double x, double y, double z, bool moving) void AActor::SetOrigin(double x, double y, double z, bool moving)
{ {
UnlinkFromWorld (); FLinkContext ctx;
UnlinkFromWorld (&ctx);
SetXYZ(x, y, z); SetXYZ(x, y, z);
LinkToWorld (); LinkToWorld (&ctx);
P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS); P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS);
if (!moving) ClearInterpolation(); if (!moving) ClearInterpolation();
} }

View file

@ -204,6 +204,7 @@ DEFINE_FIELD(AActor, ceilingsector)
DEFINE_FIELD(AActor, ceilingpic) DEFINE_FIELD(AActor, ceilingpic)
DEFINE_FIELD(AActor, Height) DEFINE_FIELD(AActor, Height)
DEFINE_FIELD(AActor, radius) DEFINE_FIELD(AActor, radius)
DEFINE_FIELD(AActor, renderradius)
DEFINE_FIELD(AActor, projectilepassheight) DEFINE_FIELD(AActor, projectilepassheight)
DEFINE_FIELD(AActor, tics) DEFINE_FIELD(AActor, tics)
DEFINE_FIELD_NAMED(AActor, state, curstate) // clashes with type 'state'. DEFINE_FIELD_NAMED(AActor, state, curstate) // clashes with type 'state'.
@ -373,6 +374,7 @@ void AActor::Serialize(FSerializer &arc)
A("floorsector", floorsector) A("floorsector", floorsector)
A("ceilingsector", ceilingsector) A("ceilingsector", ceilingsector)
A("radius", radius) A("radius", radius)
A("renderradius", renderradius)
A("height", Height) A("height", Height)
A("ppassheight", projectilepassheight) A("ppassheight", projectilepassheight)
A("vel", Vel) A("vel", Vel)
@ -509,8 +511,9 @@ void AActor::Serialize(FSerializer &arc)
void AActor::PostSerialize() void AActor::PostSerialize()
{ {
touching_sectorlist = NULL; touching_sectorlist = nullptr;
LinkToWorld(false, Sector); touching_rendersectors = nullptr;
LinkToWorld(nullptr, false, Sector);
AddToHash(); AddToHash();
if (player) if (player)
@ -3686,12 +3689,13 @@ DVector3 AActor::GetPortalTransition(double byoffset, sector_t **pSec)
void AActor::CheckPortalTransition(bool islinked) void AActor::CheckPortalTransition(bool islinked)
{ {
bool moved = false; bool moved = false;
FLinkContext ctx;
while (!Sector->PortalBlocksMovement(sector_t::ceiling)) while (!Sector->PortalBlocksMovement(sector_t::ceiling))
{ {
if (Z() >= Sector->GetPortalPlaneZ(sector_t::ceiling)) if (Z() >= Sector->GetPortalPlaneZ(sector_t::ceiling))
{ {
DVector3 oldpos = Pos(); DVector3 oldpos = Pos();
if (islinked && !moved) UnlinkFromWorld(); if (islinked && !moved) UnlinkFromWorld(&ctx);
SetXYZ(PosRelative(Sector->GetOppositePortalGroup(sector_t::ceiling))); SetXYZ(PosRelative(Sector->GetOppositePortalGroup(sector_t::ceiling)));
Prev = Pos() - oldpos; Prev = Pos() - oldpos;
Sector = P_PointInSector(Pos()); Sector = P_PointInSector(Pos());
@ -3708,7 +3712,7 @@ void AActor::CheckPortalTransition(bool islinked)
if (Z() < portalz && floorz < portalz) if (Z() < portalz && floorz < portalz)
{ {
DVector3 oldpos = Pos(); DVector3 oldpos = Pos();
if (islinked && !moved) UnlinkFromWorld(); if (islinked && !moved) UnlinkFromWorld(&ctx);
SetXYZ(PosRelative(Sector->GetOppositePortalGroup(sector_t::floor))); SetXYZ(PosRelative(Sector->GetOppositePortalGroup(sector_t::floor)));
Prev = Pos() - oldpos; Prev = Pos() - oldpos;
Sector = P_PointInSector(Pos()); Sector = P_PointInSector(Pos());
@ -3718,7 +3722,7 @@ void AActor::CheckPortalTransition(bool islinked)
else break; else break;
} }
} }
if (islinked && moved) LinkToWorld(); if (islinked && moved) LinkToWorld(&ctx);
} }
// //
@ -3781,11 +3785,12 @@ void AActor::Tick ()
if (!Vel.isZero() || !(flags & MF_NOBLOCKMAP)) if (!Vel.isZero() || !(flags & MF_NOBLOCKMAP))
{ {
UnlinkFromWorld(); FLinkContext ctx;
UnlinkFromWorld(&ctx);
flags |= MF_NOBLOCKMAP; flags |= MF_NOBLOCKMAP;
SetXYZ(Vec3Offset(Vel)); SetXYZ(Vec3Offset(Vel));
CheckPortalTransition(false); CheckPortalTransition(false);
LinkToWorld(); LinkToWorld(&ctx);
} }
} }
else else
@ -4543,12 +4548,13 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a
actor->sprite = st->sprite; actor->sprite = st->sprite;
actor->frame = st->GetFrame(); actor->frame = st->GetFrame();
actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | ActorRenderFlags::FromInt (st->GetFullbright()); actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | ActorRenderFlags::FromInt (st->GetFullbright());
actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98 actor->touching_sectorlist = nullptr; // NULL head of sector list // phares 3/13/98
actor->touching_rendersectors = nullptr;
if (G_SkillProperty(SKILLP_FastMonsters) && actor->GetClass()->FastSpeed >= 0) if (G_SkillProperty(SKILLP_FastMonsters) && actor->GetClass()->FastSpeed >= 0)
actor->Speed = actor->GetClass()->FastSpeed; actor->Speed = actor->GetClass()->FastSpeed;
// set subsector and/or block links // set subsector and/or block links
actor->LinkToWorld (SpawningMapThing); actor->LinkToWorld (nullptr, SpawningMapThing);
actor->ClearInterpolation(); actor->ClearInterpolation();
actor->dropoffz = actor->floorz = actor->Sector->floorplane.ZatPoint(pos); actor->dropoffz = actor->floorz = actor->Sector->floorplane.ZatPoint(pos);
@ -4925,12 +4931,9 @@ void AActor::Destroy ()
RemoveFromHash (); RemoveFromHash ();
// unlink from sector and block lists // unlink from sector and block lists
UnlinkFromWorld (); UnlinkFromWorld (nullptr);
flags |= MF_NOSECTOR|MF_NOBLOCKMAP; 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. // Transform any playing sound into positioned, non-actor sounds.
S_RelinkSound (this, NULL); S_RelinkSound (this, NULL);
@ -7481,9 +7484,10 @@ void AActor::RestoreSpecialPosition()
// Move item back to its original location // Move item back to its original location
DVector2 sp = SpawnPoint; DVector2 sp = SpawnPoint;
UnlinkFromWorld(); FLinkContext ctx;
UnlinkFromWorld(&ctx);
SetXY(sp); SetXY(sp);
LinkToWorld(true); LinkToWorld(&ctx, true);
SetZ(Sector->floorplane.ZatPoint(sp)); SetZ(Sector->floorplane.ZatPoint(sp));
P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS | FFCF_NOPORTALS); // no portal checks here so that things get spawned in this sector. P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS | FFCF_NOPORTALS); // no portal checks here so that things get spawned in this sector.

View file

@ -1509,9 +1509,10 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
else // [RH] Translate to new sector special else // [RH] Translate to new sector special
ss->special = P_TranslateSectorSpecial (LittleShort(ms->special)); ss->special = P_TranslateSectorSpecial (LittleShort(ms->special));
tagManager.AddSectorTag(i, LittleShort(ms->tag)); tagManager.AddSectorTag(i, LittleShort(ms->tag));
ss->thinglist = NULL; ss->thinglist = nullptr;
ss->touching_thinglist = NULL; // phares 3/14/98 ss->touching_thinglist = nullptr; // phares 3/14/98
ss->render_thinglist = NULL; ss->render_thinglist = nullptr;
ss->touching_renderthings = nullptr;
ss->seqType = defSeqType; ss->seqType = defSeqType;
ss->SeqName = NAME_None; ss->SeqName = NAME_None;
ss->nextsec = -1; //jff 2/26/98 add fields to support locking out ss->nextsec = -1; //jff 2/26/98 add fields to support locking out

View file

@ -1294,9 +1294,10 @@ public:
sec->SetYScale(sector_t::ceiling, 1.); sec->SetYScale(sector_t::ceiling, 1.);
sec->SetAlpha(sector_t::floor, 1.); sec->SetAlpha(sector_t::floor, 1.);
sec->SetAlpha(sector_t::ceiling, 1.); sec->SetAlpha(sector_t::ceiling, 1.);
sec->thinglist = NULL; sec->thinglist = nullptr;
sec->touching_thinglist = NULL; // phares 3/14/98 sec->touching_thinglist = nullptr; // phares 3/14/98
sec->render_thinglist = NULL; sec->render_thinglist = nullptr;
sec->touching_renderthings = nullptr;
sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1; sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1;
sec->nextsec = -1; //jff 2/26/98 add fields to support locking out sec->nextsec = -1; //jff 2/26/98 add fields to support locking out
sec->prevsec = -1; // stair retriggering until build completes sec->prevsec = -1; // stair retriggering until build completes

View file

@ -2940,7 +2940,8 @@ void P_UnPredictPlayer ()
// could cause it to change during prediction. // could cause it to change during prediction.
player->camera = savedcamera; player->camera = savedcamera;
act->UnlinkFromWorld(); FLinkContext ctx;
act->UnlinkFromWorld(&ctx);
memcpy(&act->snext, PredictionActorBackup, sizeof(APlayerPawn) - ((BYTE *)&act->snext - (BYTE *)act)); memcpy(&act->snext, PredictionActorBackup, sizeof(APlayerPawn) - ((BYTE *)&act->snext - (BYTE *)act));
// The blockmap ordering needs to remain unchanged, too. // The blockmap ordering needs to remain unchanged, too.
@ -2969,7 +2970,7 @@ void P_UnPredictPlayer ()
} }
// Destroy old refrences // Destroy old refrences
msecnode_t *node = sector_list; msecnode_t *node = ctx.sector_list;
while (node) while (node)
{ {
node->m_thing = NULL; node->m_thing = NULL;
@ -2977,22 +2978,23 @@ void P_UnPredictPlayer ()
} }
// Make the sector_list match the player's touching_sectorlist before it got predicted. // Make the sector_list match the player's touching_sectorlist before it got predicted.
P_DelSeclist(sector_list); P_DelSeclist(ctx.sector_list, &sector_t::touching_thinglist);
sector_list = NULL; ctx.sector_list = NULL;
for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) 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 act->touching_sectorlist = ctx.sector_list; // Attach to thing
sector_list = NULL; // clear for next time ctx.sector_list = NULL; // clear for next time
node = sector_list; // Huh???
node = ctx.sector_list;
while (node) while (node)
{ {
if (node->m_thing == NULL) if (node->m_thing == NULL)
{ {
if (node == sector_list) if (node == ctx.sector_list)
sector_list = node->m_tnext; ctx.sector_list = node->m_tnext;
node = P_DelSecnode(node, &sector_t::touching_thinglist); node = P_DelSecnode(node, &sector_t::touching_thinglist);
} }
else else

View file

@ -1140,8 +1140,9 @@ void P_CreateLinkedPortals()
P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->Pos(), actor->Top(), actor->radius, check); P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->Pos(), actor->Top(), actor->radius, check);
if (check.Size() > 0) if (check.Size() > 0)
{ {
actor->UnlinkFromWorld(); FLinkContext ctx;
actor->LinkToWorld(); actor->UnlinkFromWorld(&ctx);
actor->LinkToWorld(&ctx);
} }
} }
} }

View file

@ -23,6 +23,7 @@
#ifndef __R_DEFS_H__ #ifndef __R_DEFS_H__
#define __R_DEFS_H__ #define __R_DEFS_H__
#include <forward_list>
#include "doomdef.h" #include "doomdef.h"
#include "templates.h" #include "templates.h"
#include "memarena.h" #include "memarena.h"
@ -1048,6 +1049,7 @@ public:
// thinglist is a subset of touching_thinglist // thinglist is a subset of touching_thinglist
struct msecnode_t *touching_thinglist; // phares 3/14/98 struct msecnode_t *touching_thinglist; // phares 3/14/98
struct msecnode_t *render_thinglist; // for cross-portal rendering. struct msecnode_t *render_thinglist; // for cross-portal rendering.
struct msecnode_t *touching_renderthings; // this is used to allow wide things to be rendered not only from their main sector.
double gravity; // [RH] Sector gravity (1.0 is normal) double gravity; // [RH] Sector gravity (1.0 is normal)
FNameNoInit damagetype; // [RH] Means-of-death for applied damage FNameNoInit damagetype; // [RH] Means-of-death for applied damage

View file

@ -769,7 +769,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
// R_ProjectSprite // R_ProjectSprite
// Generates a vissprite for a thing if it might be visible. // Generates a vissprite for a thing if it might be visible.
// //
void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling) void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector)
{ {
double tr_x; double tr_x;
double tr_y; double tr_y;
@ -1141,6 +1141,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
} }
FDynamicColormap *mybasecolormap = basecolormap; FDynamicColormap *mybasecolormap = basecolormap;
if (current_sector->sectornum != thing->Sector->sectornum) // compare sectornums to account for R_FakeFlat copies.
{
// Todo: The actor is from a different sector so we have to retrieve the proper basecolormap for that sector.
}
// Sprites that are added to the scene must fade to black. // Sprites that are added to the scene must fade to black.
if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0) if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
@ -1274,7 +1278,6 @@ static void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID p
// [RH] Save which side of heightsec sprite is on here. // [RH] Save which side of heightsec sprite is on here.
void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
{ {
AActor *thing;
F3DFloor *fakeceiling = NULL; F3DFloor *fakeceiling = NULL;
F3DFloor *fakefloor = NULL; F3DFloor *fakefloor = NULL;
@ -1282,7 +1285,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
// A sector might have been split into several // A sector might have been split into several
// subsectors during BSP building. // subsectors during BSP building.
// Thus we check whether it was already added. // Thus we check whether it was already added.
if (sec->thinglist == NULL || sec->validcount == validcount) if (sec->touching_renderthings == nullptr || sec->validcount == validcount)
return; return;
// Well, now it will be done. // Well, now it will be done.
@ -1291,8 +1294,12 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
spriteshade = LIGHT2SHADE(lightlevel + r_actualextralight); spriteshade = LIGHT2SHADE(lightlevel + r_actualextralight);
// Handle all things in sector. // Handle all things in sector.
for (thing = sec->thinglist; thing; thing = thing->snext) for(auto p = sec->touching_renderthings; p != nullptr; p = p->m_snext)
{ {
auto thing = p->m_thing;
if (thing->validcount == validcount) continue;
thing->validcount = validcount;
FIntCVar *cvar = thing->GetClass()->distancecheck; FIntCVar *cvar = thing->GetClass()->distancecheck;
if (cvar != NULL && *cvar >= 0) if (cvar != NULL && *cvar >= 0)
{ {
@ -1305,7 +1312,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
} }
// find fake level // find fake level
for(auto rover : frontsector->e->XFloor.ffloors) for(auto rover : thing->Sector->e->XFloor.ffloors)
{ {
if(!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue; if(!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue;
if(!(rover->flags & FF_SOLID) || rover->alpha != 255) continue; if(!(rover->flags & FF_SOLID) || rover->alpha != 255) continue;
@ -1321,7 +1328,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
if(rover->bottom.plane->ZatPoint(0., 0.) >= thing->Top()) fakeceiling = rover; if(rover->bottom.plane->ZatPoint(0., 0.) >= thing->Top()) fakeceiling = rover;
} }
} }
R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling); R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling, sec);
fakeceiling = NULL; fakeceiling = NULL;
fakefloor = NULL; fakefloor = NULL;
} }

View file

@ -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. // 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); 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); ModActorFlag(actor, fd, set);
if (linkchange) actor->LinkToWorld(); if (linkchange) actor->LinkToWorld(&ctx);
} }
if (actor->CountsAsKill() && actor->health > 0) ++level.total_monsters; if (actor->CountsAsKill() && actor->health > 0) ++level.total_monsters;
@ -713,6 +714,15 @@ DEFINE_PROPERTY(radius, F, Actor)
defaults->radius = id; defaults->radius = id;
} }
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(renderradius, F, Actor)
{
PROP_DOUBLE_PARM(id, 0);
defaults->renderradius = id;
}
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================

View file

@ -45,6 +45,7 @@ class Actor : Thinker native
native TextureID ceilingpic; native TextureID ceilingpic;
native double Height; native double Height;
native readonly double Radius; native readonly double Radius;
native readonly double RenderRadius;
native double projectilepassheight; native double projectilepassheight;
native int tics; native int tics;
native readonly State CurState; native readonly State CurState;
@ -201,6 +202,7 @@ class Actor : Thinker native
Health DEFAULT_HEALTH; Health DEFAULT_HEALTH;
Reactiontime 8; Reactiontime 8;
Radius 20; Radius 20;
RenderRadius 0;
Height 16; Height 16;
Mass 100; Mass 100;
RenderStyle 'Normal'; RenderStyle 'Normal';

View file

@ -85,6 +85,7 @@ class InvisibleBridge : Actor native
{ {
RenderStyle "None"; RenderStyle "None";
Radius 32; Radius 32;
RenderRadius -1;
Height 4; Height 4;
+SOLID +SOLID
+NOGRAVITY +NOGRAVITY