This commit is contained in:
nashmuhandes 2016-05-22 22:02:31 +08:00
commit e9c006d739
9 changed files with 107 additions and 40 deletions

View file

@ -33,8 +33,9 @@ struct FCheckPosition
AActor *stepthing;
// [RH] These are used by PIT_CheckThing and P_XYMovement to apply
// ripping damage once per tic instead of once per move.
bool DoRipping;
TMap<AActor*, bool> LastRipped;
bool DoRipping;
bool portalstep;
int PushTime;

View file

@ -539,15 +539,31 @@ bool P_Move (AActor *actor)
tm.FromPMove = true;
try_ok = true;
for(int i=1; i < steps; i++)
{
try_ok = P_TryMove(actor, DVector2(origx + deltax * i / steps, origy + deltay * i / steps), dropoff, NULL, tm);
if (!try_ok) break;
}
DVector2 start = { origx, origy };
DVector2 move = { deltax, deltay };
DAngle oldangle = actor->Angles.Yaw;
// killough 3/15/98: don't jump over dropoffs:
if (try_ok) try_ok = P_TryMove (actor, DVector2(tryx, tryy), dropoff, NULL, tm);
try_ok = true;
for (int i = 1; i <= steps; i++)
{
DVector2 ptry = start + move * i / steps;
// killough 3/15/98: don't jump over dropoffs:
try_ok = P_TryMove(actor, ptry, dropoff, NULL, tm);
if (!try_ok) break;
// Handle portal transitions just like P_XYMovement.
if (steps > 1 && actor->Pos().XY() != ptry)
{
DAngle anglediff = deltaangle(oldangle, actor->Angles.Yaw);
if (anglediff != 0)
{
move = move.Rotated(anglediff);
oldangle = actor->Angles.Yaw;
}
start = actor->Pos() - move * i / steps;
}
}
// [GrafZahl] Interpolating monster movement as it is done here just looks bad
// so make it switchable

View file

@ -729,6 +729,22 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
// Since a one-sided line does not have an opening there's nothing left to do about it.
return true;
}
// check if the actor can step through the ceiling portal. In this case one-sided lines in the current area should not block
if (!cres.line->frontsector->PortalBlocksMovement(sector_t::ceiling))
{
double portz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling);
if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz)
{
tm.floorz = portz;
tm.floorsector = cres.line->frontsector;
tm.floorpic = cres.line->sidedef[0]->GetTexture(side_t::mid);
tm.floorterrain = 0;
tm.portalstep = true;
return true;
}
}
if (tm.thing->flags2 & MF2_BLASTED)
{
P_DamageMobj(tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee);
@ -1975,6 +1991,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
sector_t* newsec;
tm.floatok = false;
tm.portalstep = false;
oldz = thing->Z();
if (onfloor)
{
@ -2247,6 +2264,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
thing->LinkToWorld();
P_FindFloorCeiling(thing);
portalcrossed = true;
tm.portalstep = false;
}
else if (!portalcrossed)
{
@ -2272,6 +2290,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
P_FindFloorCeiling(thing);
thing->ClearInterpolation();
portalcrossed = true;
tm.portalstep = false;
}
// if this is the current camera we need to store the point where the portal was crossed and the exit
// so that the renderer can properly calculate an interpolated position along the movement path.
@ -2411,6 +2430,20 @@ 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)
{
DVector3 oldpos = thing->Pos();
thing->UnlinkFromWorld();
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();
P_FindFloorCeiling(thing);
}
// [RH] If changing sectors, trigger transitions
thing->CheckSectorTransition(oldsec);
thing->flags6 &= ~MF6_INTRYMOVE;

View file

@ -2118,21 +2118,23 @@ explode:
if (mo->Pos().XY() != ptry)
{
// If the new position does not match the desired position, the player
// must have gone through a teleporter, so stop moving right now if it
// was a regular teleporter. If it was a line-to-line or fogless teleporter,
// the move should continue, but start and move need to change.
// must have gone through a teleporter or portal.
if (mo->Vel.X == 0 && mo->Vel.Y == 0)
{
// Stop moving right now if it was a regular teleporter.
step = steps;
}
else
{
// It was a portal, line-to-line or fogless teleporter, so the move should continue.
// For that we need to adjust the start point, and the movement vector.
DAngle anglediff = deltaangle(oldangle, mo->Angles.Yaw);
if (anglediff != 0)
{
move = move.Rotated(anglediff);
oldangle = mo->Angles.Yaw; // in case more moves are needed this needs to be updated.
oldangle = mo->Angles.Yaw;
}
start = mo->Pos() - move * step / steps;
}
@ -3226,7 +3228,7 @@ DVector3 AActor::GetPortalTransition(double byoffset, sector_t **pSec)
while (!sec->PortalBlocksMovement(sector_t::ceiling))
{
if (testz > sec->GetPortalPlaneZ(sector_t::ceiling))
if (testz >= sec->GetPortalPlaneZ(sector_t::ceiling))
{
pos = PosRelative(sec->GetOppositePortalGroup(sector_t::ceiling));
sec = P_PointInSector(pos);
@ -3238,7 +3240,7 @@ DVector3 AActor::GetPortalTransition(double byoffset, sector_t **pSec)
{
while (!sec->PortalBlocksMovement(sector_t::floor))
{
if (testz <= sec->GetPortalPlaneZ(sector_t::floor))
if (testz < sec->GetPortalPlaneZ(sector_t::floor))
{
pos = PosRelative(sec->GetOppositePortalGroup(sector_t::floor));
sec = P_PointInSector(pos);
@ -3257,7 +3259,7 @@ void AActor::CheckPortalTransition(bool islinked)
bool moved = false;
while (!Sector->PortalBlocksMovement(sector_t::ceiling))
{
if (Z() > Sector->GetPortalPlaneZ(sector_t::ceiling))
if (Z() >= Sector->GetPortalPlaneZ(sector_t::ceiling))
{
DVector3 oldpos = Pos();
if (islinked && !moved) UnlinkFromWorld();

View file

@ -570,6 +570,7 @@ void P_SerializePolyobjs (FArchive &arc)
for(i = 0, po = polyobjs; i < po_NumPolyobjs; i++, po++)
{
arc << po->tag << po->Angle << po->StartSpot.pos << po->interpolation << po->bBlocked << po->bHasPortals;
arc << po->specialdata;
}
}
else
@ -597,6 +598,10 @@ void P_SerializePolyobjs (FArchive &arc)
arc << angle << delta << po->interpolation;
arc << po->bBlocked;
arc << po->bHasPortals;
if (SaveVersion >= 4548)
{
arc << po->specialdata;
}
po->RotatePolyobj (angle, true);
delta -= po->StartSpot.pos;

View file

@ -68,27 +68,6 @@ inline FArchive &operator<< (FArchive &arc, podoortype_t &type)
return arc;
}
class DPolyAction : public DThinker
{
DECLARE_CLASS (DPolyAction, DThinker)
HAS_OBJECT_POINTERS
public:
DPolyAction (int polyNum);
void Serialize (FArchive &arc);
void Destroy();
void Stop();
double GetSpeed() const { return m_Speed; }
void StopInterpolation ();
protected:
DPolyAction ();
int m_PolyObj;
double m_Speed;
double m_Dist;
TObjPtr<DInterpolation> m_Interpolation;
void SetInterpolation ();
};
class DRotatePoly : public DPolyAction
{
@ -302,6 +281,10 @@ void DMovePoly::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << m_Angle << m_Speed;
if (SaveVersion >= 4548)
{
arc << m_Speedv;
}
}
DMovePoly::DMovePoly (int polyNum)

View file

@ -5,7 +5,27 @@
#include "r_defs.h"
#include "m_bbox.h"
class DPolyAction;
class DPolyAction : public DThinker
{
DECLARE_CLASS(DPolyAction, DThinker)
HAS_OBJECT_POINTERS
public:
DPolyAction(int polyNum);
void Serialize(FArchive &arc);
void Destroy();
void Stop();
double GetSpeed() const { return m_Speed; }
void StopInterpolation();
protected:
DPolyAction();
int m_PolyObj;
double m_Speed;
double m_Dist;
TObjPtr<DInterpolation> m_Interpolation;
void SetInterpolation();
};
struct FPolyVertex
{
@ -67,7 +87,7 @@ struct FPolyObj
int seqType;
double Size; // polyobj size (area of POLY_AREAUNIT == size of FRACUNIT)
FPolyNode *subsectorlinks;
DPolyAction *specialdata; // pointer to a thinker, if the poly is moving
TObjPtr<DPolyAction> specialdata; // pointer to a thinker, if the poly is moving
TObjPtr<DInterpolation> interpolation;
FPolyObj();

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 4546
#define SAVEVER 4548
#define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)

View file

@ -1608,6 +1608,13 @@ TArray<FString> I_GetGogPaths()
result.Push(path + "/Plutonia");
}
// Look for Strife: Veteran Edition
gamepath = gogregistrypath + "\\1432899949";
if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path))
{
result.Push(path); // directly in install folder
}
return result;
}