This commit is contained in:
Christoph Oelckers 2016-04-18 00:02:55 +02:00
commit 8f61c1cdd8
17 changed files with 174 additions and 31 deletions

View file

@ -959,11 +959,14 @@ public:
// Triggers SECSPAC_Exit/SECSPAC_Enter and related events if oldsec != current sector // Triggers SECSPAC_Exit/SECSPAC_Enter and related events if oldsec != current sector
void CheckSectorTransition(sector_t *oldsec); void CheckSectorTransition(sector_t *oldsec);
void UpdateRenderSectorList();
void ClearRenderSectorList();
// info for drawing // info for drawing
// NOTE: The first member variable *must* be snext. // NOTE: The first member variable *must* be snext.
AActor *snext, **sprev; // links in sector (if needed) AActor *snext, **sprev; // links in sector (if needed)
DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions. DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
DVector3 OldRenderPos;
DRotator Angles; DRotator Angles;
DVector3 Vel; DVector3 Vel;
@ -1094,6 +1097,8 @@ public:
// a linked list of sectors where this object appears // a linked list of sectors where this object appears
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-portal rendering
TObjPtr<AInventory> Inventory; // [RH] This actor's inventory TObjPtr<AInventory> Inventory; // [RH] This actor's inventory
DWORD InventoryID; // A unique ID to keep track of inventory items DWORD InventoryID; // A unique ID to keep track of inventory items

View file

@ -127,8 +127,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2)
angle = -angle; angle = -angle;
} }
angle += self->Angles.Yaw; angle += self->Angles.Yaw;
mo->Vel.X = ((pr_wraithfx2() << 7) + 1) * angle.Cos(); mo->Vel.X = ((pr_wraithfx2() / 512.) + 1) * angle.Cos();
mo->Vel.Y = ((pr_wraithfx2() << 7) + 1) * angle.Sin(); mo->Vel.Y = ((pr_wraithfx2() / 512.) + 1) * angle.Sin();
mo->Vel.Z = 0; mo->Vel.Z = 0;
mo->target = self; mo->target = self;
mo->Floorclip = 10; mo->Floorclip = 10;

View file

@ -811,15 +811,6 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
unsigned int vertnum; unsigned int vertnum;
int seg2; int seg2;
if (seg->loopnum)
{
Printf (" Split seg %u (%d,%d)-(%d,%d) of sector %td in loop %d\n",
set,
Vertices[seg->v1].x>>16, Vertices[seg->v1].y>>16,
Vertices[seg->v2].x>>16, Vertices[seg->v2].y>>16,
seg->frontsector - sectors, seg->loopnum);
}
frac = InterceptVector (node, *seg); frac = InterceptVector (node, *seg);
newvert.x = Vertices[seg->v1].x; newvert.x = Vertices[seg->v1].x;
newvert.y = Vertices[seg->v1].y; newvert.y = Vertices[seg->v1].y;

View file

@ -350,7 +350,8 @@ void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance,
void P_DelSector_List(); void P_DelSector_List();
void P_DelSeclist(msecnode_t *); // phares 3/16/98 void P_DelSeclist(msecnode_t *); // phares 3/16/98
msecnode_t* P_DelSecnode(msecnode_t *); 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 void P_CreateSecNodeList(AActor*); // phares 3/14/98
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

@ -5555,6 +5555,7 @@ int P_PushUp(AActor *thing, FChangePosition *cpos)
intersect->SetZ(oldz); intersect->SetZ(oldz);
return 2; return 2;
} }
intersect->UpdateRenderSectorList();
} }
thing->CheckPortalTransition(true); thing->CheckPortalTransition(true);
return 0; return 0;
@ -5602,6 +5603,7 @@ int P_PushDown(AActor *thing, FChangePosition *cpos)
intersect->SetZ(oldz); intersect->SetZ(oldz);
return 2; return 2;
} }
intersect->UpdateRenderSectorList();
} }
} }
thing->CheckPortalTransition(true); thing->CheckPortalTransition(true);
@ -5634,6 +5636,7 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos)
{ {
thing->SetZ(thing->floorz); thing->SetZ(thing->floorz);
P_CheckFakeFloorTriggers(thing, oldz); P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
} }
} }
else if ((thing->Z() != oldfloorz && !(thing->flags & MF_NOLIFTDROP))) else if ((thing->Z() != oldfloorz && !(thing->flags & MF_NOLIFTDROP)))
@ -5642,6 +5645,7 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos)
{ {
thing->AddZ(-oldfloorz + thing->floorz); thing->AddZ(-oldfloorz + thing->floorz);
P_CheckFakeFloorTriggers(thing, oldz); P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
} }
} }
if (thing->player && thing->player->mo == thing) if (thing->player && thing->player->mo == thing)
@ -5689,10 +5693,12 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos)
{ {
default: default:
P_CheckFakeFloorTriggers(thing, oldz); P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
break; break;
case 1: case 1:
P_DoCrunch(thing, cpos); P_DoCrunch(thing, cpos);
P_CheckFakeFloorTriggers(thing, oldz); P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
break; break;
case 2: case 2:
P_DoCrunch(thing, cpos); P_DoCrunch(thing, cpos);
@ -5735,6 +5741,7 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
{ {
thing->SetZ(thing->floorz); thing->SetZ(thing->floorz);
} }
thing->UpdateRenderSectorList();
switch (P_PushDown(thing, cpos)) switch (P_PushDown(thing, cpos))
{ {
case 2: case 2:
@ -5744,9 +5751,11 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
thing->SetZ(thing->floorz); thing->SetZ(thing->floorz);
P_DoCrunch(thing, cpos); P_DoCrunch(thing, cpos);
P_CheckFakeFloorTriggers(thing, oldz); P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
break; break;
default: default:
P_CheckFakeFloorTriggers(thing, oldz); P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
break; break;
} }
} }
@ -5782,6 +5791,7 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos)
thing->SetZ(thing->ceilingz - thing->Height); thing->SetZ(thing->ceilingz - thing->Height);
} }
P_CheckFakeFloorTriggers(thing, oldz); P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
} }
else if ((thing->flags2 & MF2_PASSMOBJ) && !isgood && thing->Top() < thing->ceilingz) else if ((thing->flags2 & MF2_PASSMOBJ) && !isgood && thing->Top() < thing->ceilingz)
{ {
@ -5789,6 +5799,7 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos)
if (!P_TestMobjZ(thing, true, &onmobj) && onmobj->Z() <= thing->Z()) if (!P_TestMobjZ(thing, true, &onmobj) && onmobj->Z() <= thing->Z())
{ {
thing->SetZ(MIN(thing->ceilingz - thing->Height, onmobj->Top())); thing->SetZ(MIN(thing->ceilingz - thing->Height, onmobj->Top()));
thing->UpdateRenderSectorList();
} }
} }
if (thing->player && thing->player->mo == thing) if (thing->player && thing->player->mo == thing)
@ -6023,7 +6034,7 @@ void P_PutSecnode(msecnode_t *node)
// //
//============================================================================= //=============================================================================
msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode) msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist)
{ {
msecnode_t *node; msecnode_t *node;
@ -6061,10 +6072,10 @@ msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode)
// Add new node at head of sector thread starting at s->touching_thinglist // Add new node at head of sector thread starting at s->touching_thinglist
node->m_sprev = NULL; // prev node on sector thread node->m_sprev = NULL; // prev node on sector thread
node->m_snext = s->touching_thinglist; // next node on sector thread node->m_snext = sec_thinglist; // next node on sector thread
if (s->touching_thinglist) if (sec_thinglist)
node->m_snext->m_sprev = node; node->m_snext->m_sprev = node;
s->touching_thinglist = node; sec_thinglist = node;
return node; return node;
} }
@ -6078,7 +6089,7 @@ msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode)
// //
//============================================================================= //=============================================================================
msecnode_t *P_DelSecnode(msecnode_t *node) msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead)
{ {
msecnode_t* tp; // prev node on thing thread msecnode_t* tp; // prev node on thing thread
msecnode_t* tn; // next node on thing thread msecnode_t* tn; // next node on thing thread
@ -6105,7 +6116,7 @@ msecnode_t *P_DelSecnode(msecnode_t *node)
if (sp) if (sp)
sp->m_snext = sn; sp->m_snext = sn;
else else
node->m_sector->touching_thinglist = sn; node->m_sector->*listhead = sn;
if (sn) if (sn)
sn->m_sprev = sp; sn->m_sprev = sp;
@ -6145,7 +6156,7 @@ void P_DelSector_List()
void P_DelSeclist(msecnode_t *node) void P_DelSeclist(msecnode_t *node)
{ {
while (node) while (node)
node = P_DelSecnode(node); node = P_DelSecnode(node, &sector_t::touching_thinglist);
} }
//============================================================================= //=============================================================================
@ -6189,7 +6200,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); sector_list = P_AddSecnode(ld->frontsector, thing, sector_list, ld->frontsector->touching_thinglist);
// 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
@ -6199,12 +6210,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); sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->touching_thinglist);
} }
// 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); sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->touching_thinglist);
// 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.
@ -6216,7 +6227,7 @@ 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); node = P_DelSecnode(node, &sector_t::touching_thinglist);
} }
else else
{ {
@ -6225,6 +6236,54 @@ void P_CreateSecNodeList(AActor *thing)
} }
} }
//==========================================================================
//
// Handle the lists used to render actors from other portal areas
//
//==========================================================================
void AActor::UpdateRenderSectorList()
{
static const double SPRITE_SPACE = 64.;
if (Pos() != OldRenderPos)
{
sector_t *sec = Sector;
double lasth = -FLT_MAX;
ClearRenderSectorList();
while (!sec->PortalBlocksMovement(sector_t::ceiling))
{
double planeh = sec->SkyBoxes[sector_t::ceiling]->specialf1;
if (planeh < lasth) break; // broken setup.
if (Top() + SPRITE_SPACE < planeh) break;
lasth = planeh;
DVector2 newpos = Pos() + sec->SkyBoxes[sector_t::ceiling]->Scale;
sec = P_PointInSector(newpos);
render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist);
}
lasth = FLT_MAX;
while (!sec->PortalBlocksMovement(sector_t::floor))
{
double planeh = sec->SkyBoxes[sector_t::floor]->specialf1;
if (planeh > lasth) break; // broken setup.
if (Z() - SPRITE_SPACE > planeh) break;
lasth = planeh;
DVector2 newpos = Pos() + sec->SkyBoxes[sector_t::floor]->Scale;
sec = P_PointInSector(newpos);
render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist);
}
}
}
void AActor::ClearRenderSectorList()
{
msecnode_t *node = render_sectorlist;
while (node)
node = P_DelSecnode(node, &sector_t::render_thinglist);
render_sectorlist = NULL;
}
//========================================================================== //==========================================================================
// //
// //

View file

@ -3752,6 +3752,9 @@ void AActor::Tick ()
if (!CheckNoDelay()) if (!CheckNoDelay())
return; // freed itself return; // freed itself
// cycle through states, calling action functions at transitions // cycle through states, calling action functions at transitions
UpdateRenderSectorList();
if (tics != -1) if (tics != -1)
{ {
// [RH] Use tics <= 0 instead of == 0 so that spawnstates // [RH] Use tics <= 0 instead of == 0 so that spawnstates
@ -4011,6 +4014,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a
} }
actor->SetXYZ(pos); actor->SetXYZ(pos);
actor->OldRenderPos = { FLT_MAX, FLT_MAX, FLT_MAX };
actor->picnum.SetInvalid(); actor->picnum.SetInvalid();
actor->health = actor->SpawnHealth(); actor->health = actor->SpawnHealth();
@ -4322,12 +4326,15 @@ void AActor::Deactivate (AActor *activator)
} }
} }
// //
// P_RemoveMobj // P_RemoveMobj
// //
void AActor::Destroy () void AActor::Destroy ()
{ {
ClearRenderSectorList();
// [RH] Destroy any inventory this actor is carrying // [RH] Destroy any inventory this actor is carrying
DestroyAllInventory (); DestroyAllInventory ();

View file

@ -544,7 +544,7 @@ void P_SerializePolyobjs (FArchive &arc)
arc << seg << po_NumPolyobjs; arc << seg << po_NumPolyobjs;
for(i = 0, po = polyobjs; i < po_NumPolyobjs; i++, po++) for(i = 0, po = polyobjs; i < po_NumPolyobjs; i++, po++)
{ {
arc << po->tag << po->Angle << po->StartSpot.pos << po->interpolation << po->bBlocked; arc << po->tag << po->Angle << po->StartSpot.pos << po->interpolation << po->bBlocked << po->bHasPortals;
} }
} }
else else
@ -578,6 +578,14 @@ void P_SerializePolyobjs (FArchive &arc)
{ {
po->bBlocked = false; po->bBlocked = false;
} }
if (SaveVersion >= 4538)
{
arc << po->bHasPortals;
}
else
{
po->bHasPortals = 0;
}
po->RotatePolyobj (angle, true); po->RotatePolyobj (angle, true);
delta -= po->StartSpot.pos; delta -= po->StartSpot.pos;

View file

@ -1510,6 +1510,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
tagManager.AddSectorTag(i, LittleShort(ms->tag)); tagManager.AddSectorTag(i, LittleShort(ms->tag));
ss->thinglist = NULL; ss->thinglist = NULL;
ss->touching_thinglist = NULL; // phares 3/14/98 ss->touching_thinglist = NULL; // phares 3/14/98
ss->render_thinglist = NULL;
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

@ -1291,6 +1291,7 @@ public:
sec->SetAlpha(sector_t::ceiling, 1.); sec->SetAlpha(sector_t::ceiling, 1.);
sec->thinglist = NULL; sec->thinglist = NULL;
sec->touching_thinglist = NULL; // phares 3/14/98 sec->touching_thinglist = NULL; // phares 3/14/98
sec->render_thinglist = NULL;
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

@ -2860,8 +2860,6 @@ void P_PredictPlayer (player_t *player)
} }
} }
extern msecnode_t *P_AddSecnode (sector_t *s, AActor *thing, msecnode_t *nextnode);
void P_UnPredictPlayer () void P_UnPredictPlayer ()
{ {
player_t *player = &players[consoleplayer]; player_t *player = &players[consoleplayer];
@ -2922,7 +2920,7 @@ void P_UnPredictPlayer ()
sector_list = NULL; sector_list = NULL;
for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;)
{ {
sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list); sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list, PredictionTouchingSectorsBackup[i]->touching_thinglist);
} }
act->touching_sectorlist = sector_list; // Attach to thing act->touching_sectorlist = sector_list; // Attach to thing
sector_list = NULL; // clear for next time sector_list = NULL; // clear for next time
@ -2934,7 +2932,7 @@ void P_UnPredictPlayer ()
{ {
if (node == sector_list) if (node == sector_list)
sector_list = node->m_tnext; sector_list = node->m_tnext;
node = P_DelSecnode(node); node = P_DelSecnode(node, &sector_t::touching_thinglist);
} }
else else
{ {

View file

@ -425,6 +425,11 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle,
{ // poly is already in motion { // poly is already in motion
break; break;
} }
if (poly->bHasPortals == 2)
{
// cannot do rotations on linked polyportals.
break;
}
pe = new DRotatePoly(poly->tag); pe = new DRotatePoly(poly->tag);
poly->specialdata = pe; poly->specialdata = pe;
poly->bBlocked = false; poly->bBlocked = false;
@ -476,6 +481,7 @@ void DMovePoly::Tick ()
m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1); m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1);
m_Speedv = m_Angle.ToVector(m_Speed); m_Speedv = m_Angle.ToVector(m_Speed);
} }
poly->UpdateLinks();
} }
} }
} }
@ -555,6 +561,7 @@ void DMovePolyTo::Tick ()
m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1); m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1);
m_Speedv = m_Target - poly->StartSpot.pos; m_Speedv = m_Target - poly->StartSpot.pos;
} }
poly->UpdateLinks();
} }
} }
} }
@ -649,6 +656,7 @@ void DPolyDoor::Tick ()
Destroy (); Destroy ();
} }
} }
poly->UpdateLinks();
} }
else else
{ {
@ -735,6 +743,12 @@ bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int
{ // poly is already moving { // poly is already moving
break; break;
} }
if (poly->bHasPortals == 2 && type == PODOOR_SWING)
{
// cannot do rotations on linked polyportals.
break;
}
pd = new DPolyDoor(poly->tag, type); pd = new DPolyDoor(poly->tag, type);
poly->specialdata = pd; poly->specialdata = pd;
if (type == PODOOR_SLIDE) if (type == PODOOR_SLIDE)
@ -899,6 +913,36 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side)
// //
//========================================================================== //==========================================================================
void FPolyObj::UpdateLinks()
{
if (bHasPortals == 2)
{
TMap<int, bool> processed;
for (unsigned i = 0; i < Linedefs.Size(); i++)
{
if (Linedefs[i]->isLinePortal())
{
FLinePortal *port = Linedefs[i]->getPortal();
if (port->mType == PORTT_LINKED)
{
DVector2 old = port->mDisplacement;
port->mDisplacement = port->mDestination->v2->fPos() - port->mOrigin->v1->fPos();
FLinePortal *port2 = port->mDestination->getPortal();
if (port2) port2->mDisplacement = -port->mDisplacement;
int destgroup = port->mDestination->frontsector->PortalGroup;
bool *done = processed.CheckKey(destgroup);
if (!done || !*done)
{
processed[destgroup] = true;
DVector2 delta = port->mDisplacement - old;
Displacements.MoveGroup(destgroup, delta);
}
}
}
}
}
}
void FPolyObj::UpdateBBox () void FPolyObj::UpdateBBox ()
{ {
for(unsigned i=0;i<Linedefs.Size(); i++) for(unsigned i=0;i<Linedefs.Size(); i++)
@ -1172,6 +1216,15 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
{ {
continue; continue;
} }
if (ld->isLinePortal())
{
// Fixme: this still needs to figure out if the polyobject move made the player cross the portal line.
if (P_TryMove(mobj, mobj->Pos(), false))
{
continue;
}
}
// We have a two-sided linedef so we should only check one side // We have a two-sided linedef so we should only check one side
// so that the thrust from both sides doesn't cancel each other out. // so that the thrust from both sides doesn't cancel each other out.
// Best use the one facing the player and ignore the back side. // Best use the one facing the player and ignore the back side.
@ -1496,6 +1549,8 @@ static void SpawnPolyobj (int index, int tag, int type)
{ {
continue; continue;
} }
po->bBlocked = false;
po->bHasPortals = 0;
side_t *sd = &sides[i]; side_t *sd = &sides[i];
@ -1563,6 +1618,12 @@ static void SpawnPolyobj (int index, int tag, int type)
if (l->validcount != validcount) if (l->validcount != validcount)
{ {
FLinePortal *port = l->getPortal();
if (port && (port->mDefFlags & PORTF_PASSABLE))
{
int type = port->mType == PORTT_LINKED ? 2 : 1;
if (po->bHasPortals < type) po->bHasPortals = (BYTE)type;
}
l->validcount = validcount; l->validcount = validcount;
po->Linedefs.Push(l); po->Linedefs.Push(l);

View file

@ -63,6 +63,7 @@ struct FPolyObj
int crush; // should the polyobj attempt to crush mobjs? int crush; // should the polyobj attempt to crush mobjs?
bool bHurtOnTouch; // should the polyobj hurt anything it touches? bool bHurtOnTouch; // should the polyobj hurt anything it touches?
bool bBlocked; bool bBlocked;
BYTE bHasPortals; // 1 for any portal, 2 for a linked portal (2 must block rotations.)
int seqType; int seqType;
double Size; // polyobj size (area of POLY_AREAUNIT == size of FRACUNIT) double Size; // polyobj size (area of POLY_AREAUNIT == size of FRACUNIT)
FPolyNode *subsectorlinks; FPolyNode *subsectorlinks;
@ -82,6 +83,7 @@ struct FPolyObj
void CreateSubsectorLinks(); void CreateSubsectorLinks();
void ClearSubsectorLinks(); void ClearSubsectorLinks();
void CalcCenter(); void CalcCenter();
void UpdateLinks();
static void ClearAllSubsectorLinks(); static void ClearAllSubsectorLinks();
private: private:

View file

@ -384,8 +384,7 @@ void P_UpdatePortal(FLinePortal *port)
} }
else else
{ {
port->mDisplacement.X = port->mDestination->v2->fX() - port->mOrigin->v1->fX(); port->mDisplacement = port->mDestination->v2->fPos() - port->mOrigin->v1->fPos();
port->mDisplacement.Y = port->mDestination->v2->fY() - port->mOrigin->v1->fY();
} }
} }
} }

View file

@ -64,6 +64,14 @@ struct FDisplacementTable
return data[x + size*y].pos; return data[x + size*y].pos;
} }
void MoveGroup(int grp, DVector2 delta)
{
for (int i = 1; i < size; i++)
{
data[grp + size*i].pos -= delta;
data[i + grp*size].pos += delta;
}
}
}; };
extern FDisplacementTable Displacements; extern FDisplacementTable Displacements;

View file

@ -1102,6 +1102,7 @@ public:
// list of mobjs that are at least partially in the sector // list of mobjs that are at least partially in the sector
// 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.
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

@ -949,6 +949,7 @@ void R_SetupFrame (AActor *actor)
{ {
iview->otic = nowtic; iview->otic = nowtic;
iview->Old = iview->New; iview->Old = iview->New;
r_NoInterpolate = true;
} }
} }
else else

View file

@ -76,7 +76,7 @@ const char *GetVersionString();
// Use 4500 as the base git save version, since it's higher than the // Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got. // SVN revision ever got.
#define SAVEVER 4537 #define SAVEVER 4538
#define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)