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
void CheckSectorTransition(sector_t *oldsec);
void UpdateRenderSectorList();
void ClearRenderSectorList();
// info for drawing
// NOTE: The first member variable *must* be snext.
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 OldRenderPos;
DRotator Angles;
DVector3 Vel;
@ -1094,6 +1097,8 @@ public:
// a linked list of sectors where this object appears
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
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 += self->Angles.Yaw;
mo->Vel.X = ((pr_wraithfx2() << 7) + 1) * angle.Cos();
mo->Vel.Y = ((pr_wraithfx2() << 7) + 1) * angle.Sin();
mo->Vel.X = ((pr_wraithfx2() / 512.) + 1) * angle.Cos();
mo->Vel.Y = ((pr_wraithfx2() / 512.) + 1) * angle.Sin();
mo->Vel.Z = 0;
mo->target = self;
mo->Floorclip = 10;

View File

@ -811,15 +811,6 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
unsigned int vertnum;
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);
newvert.x = Vertices[seg->v1].x;
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_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
double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98
double P_GetFriction(const AActor *mo, double *frictionfactor);

View File

@ -5555,6 +5555,7 @@ int P_PushUp(AActor *thing, FChangePosition *cpos)
intersect->SetZ(oldz);
return 2;
}
intersect->UpdateRenderSectorList();
}
thing->CheckPortalTransition(true);
return 0;
@ -5602,6 +5603,7 @@ int P_PushDown(AActor *thing, FChangePosition *cpos)
intersect->SetZ(oldz);
return 2;
}
intersect->UpdateRenderSectorList();
}
}
thing->CheckPortalTransition(true);
@ -5634,6 +5636,7 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos)
{
thing->SetZ(thing->floorz);
P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
}
}
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);
P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
}
}
if (thing->player && thing->player->mo == thing)
@ -5689,10 +5693,12 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos)
{
default:
P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
break;
case 1:
P_DoCrunch(thing, cpos);
P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
break;
case 2:
P_DoCrunch(thing, cpos);
@ -5735,6 +5741,7 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
{
thing->SetZ(thing->floorz);
}
thing->UpdateRenderSectorList();
switch (P_PushDown(thing, cpos))
{
case 2:
@ -5744,9 +5751,11 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
thing->SetZ(thing->floorz);
P_DoCrunch(thing, cpos);
P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
break;
default:
P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
break;
}
}
@ -5782,6 +5791,7 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos)
thing->SetZ(thing->ceilingz - thing->Height);
}
P_CheckFakeFloorTriggers(thing, oldz);
thing->UpdateRenderSectorList();
}
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())
{
thing->SetZ(MIN(thing->ceilingz - thing->Height, onmobj->Top()));
thing->UpdateRenderSectorList();
}
}
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;
@ -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
node->m_sprev = NULL; // prev node on sector thread
node->m_snext = s->touching_thinglist; // next node on sector thread
if (s->touching_thinglist)
node->m_snext = sec_thinglist; // next node on sector thread
if (sec_thinglist)
node->m_snext->m_sprev = node;
s->touching_thinglist = node;
sec_thinglist = 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* tn; // next node on thing thread
@ -6105,7 +6116,7 @@ msecnode_t *P_DelSecnode(msecnode_t *node)
if (sp)
sp->m_snext = sn;
else
node->m_sector->touching_thinglist = sn;
node->m_sector->*listhead = sn;
if (sn)
sn->m_sprev = sp;
@ -6145,7 +6156,7 @@ void P_DelSector_List()
void P_DelSeclist(msecnode_t *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
// 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
// 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.
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.
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
// m_thing is still NULL.
@ -6216,7 +6227,7 @@ void P_CreateSecNodeList(AActor *thing)
{
if (node == sector_list)
sector_list = node->m_tnext;
node = P_DelSecnode(node);
node = P_DelSecnode(node, &sector_t::touching_thinglist);
}
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())
return; // freed itself
// cycle through states, calling action functions at transitions
UpdateRenderSectorList();
if (tics != -1)
{
// [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->OldRenderPos = { FLT_MAX, FLT_MAX, FLT_MAX };
actor->picnum.SetInvalid();
actor->health = actor->SpawnHealth();
@ -4322,12 +4326,15 @@ void AActor::Deactivate (AActor *activator)
}
}
//
// P_RemoveMobj
//
void AActor::Destroy ()
{
ClearRenderSectorList();
// [RH] Destroy any inventory this actor is carrying
DestroyAllInventory ();

View File

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

View File

@ -1510,6 +1510,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
tagManager.AddSectorTag(i, LittleShort(ms->tag));
ss->thinglist = NULL;
ss->touching_thinglist = NULL; // phares 3/14/98
ss->render_thinglist = NULL;
ss->seqType = defSeqType;
ss->SeqName = NAME_None;
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->thinglist = NULL;
sec->touching_thinglist = NULL; // phares 3/14/98
sec->render_thinglist = NULL;
sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1;
sec->nextsec = -1; //jff 2/26/98 add fields to support locking out
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 ()
{
player_t *player = &players[consoleplayer];
@ -2922,7 +2920,7 @@ void P_UnPredictPlayer ()
sector_list = NULL;
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
sector_list = NULL; // clear for next time
@ -2934,7 +2932,7 @@ void P_UnPredictPlayer ()
{
if (node == sector_list)
sector_list = node->m_tnext;
node = P_DelSecnode(node);
node = P_DelSecnode(node, &sector_t::touching_thinglist);
}
else
{

View File

@ -425,6 +425,11 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle,
{ // poly is already in motion
break;
}
if (poly->bHasPortals == 2)
{
// cannot do rotations on linked polyportals.
break;
}
pe = new DRotatePoly(poly->tag);
poly->specialdata = pe;
poly->bBlocked = false;
@ -476,6 +481,7 @@ void DMovePoly::Tick ()
m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1);
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_Speedv = m_Target - poly->StartSpot.pos;
}
poly->UpdateLinks();
}
}
}
@ -649,6 +656,7 @@ void DPolyDoor::Tick ()
Destroy ();
}
}
poly->UpdateLinks();
}
else
{
@ -735,6 +743,12 @@ bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int
{ // poly is already moving
break;
}
if (poly->bHasPortals == 2 && type == PODOOR_SWING)
{
// cannot do rotations on linked polyportals.
break;
}
pd = new DPolyDoor(poly->tag, type);
poly->specialdata = pd;
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 ()
{
for(unsigned i=0;i<Linedefs.Size(); i++)
@ -1172,6 +1216,15 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
{
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
// 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.
@ -1496,6 +1549,8 @@ static void SpawnPolyobj (int index, int tag, int type)
{
continue;
}
po->bBlocked = false;
po->bHasPortals = 0;
side_t *sd = &sides[i];
@ -1563,6 +1618,12 @@ static void SpawnPolyobj (int index, int tag, int type)
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;
po->Linedefs.Push(l);

View File

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

View File

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

View File

@ -64,6 +64,14 @@ struct FDisplacementTable
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;

View File

@ -1102,6 +1102,7 @@ public:
// list of mobjs that are at least partially in the sector
// thinglist is a subset of touching_thinglist
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)
FNameNoInit damagetype; // [RH] Means-of-death for applied damage

View File

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

View File

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