Fixed sector floor/ceiling actions not triggering in P_XYMovement

This commit is contained in:
ZZYZX 2018-10-31 21:56:01 +02:00 committed by Christoph Oelckers
parent a388b6c8ab
commit 849d110f10
6 changed files with 57 additions and 31 deletions

View file

@ -1182,6 +1182,8 @@ public:
AActor *BlockingMobj; // Actor that blocked the last move
line_t *BlockingLine; // Line that blocked the last move
sector_t *BlockingCeiling; // Sector that blocked the last move (ceiling plane slope)
sector_t *BlockingFloor; // Sector that blocked the last move (floor plane slope)
int PoisonDamage; // Damage received per tic from poison.
FName PoisonDamageType; // Damage type dealt by poison.

View file

@ -345,7 +345,7 @@ void P_PlayerOnSpecial3DFloor(player_t* player)
// Checks whether the player's feet touch a solid 3D floor in the sector
//
//==========================================================================
bool P_CheckFor3DFloorHit(AActor * mo, double z)
bool P_CheckFor3DFloorHit(AActor * mo, double z, bool trigger)
{
if ((mo->player && (mo->player->cheats & CF_PREDICTING))) return false;
@ -357,7 +357,8 @@ bool P_CheckFor3DFloorHit(AActor * mo, double z)
{
if (fabs(z - rover->top.plane->ZatPoint(mo)) < EQUAL_EPSILON)
{
rover->model->TriggerSectorActions (mo, SECSPAC_HitFloor);
mo->BlockingFloor = rover->model;
if (trigger) rover->model->TriggerSectorActions (mo, SECSPAC_HitFloor);
return true;
}
}
@ -371,7 +372,7 @@ bool P_CheckFor3DFloorHit(AActor * mo, double z)
// Checks whether the player's head touches a solid 3D floor in the sector
//
//==========================================================================
bool P_CheckFor3DCeilingHit(AActor * mo, double z)
bool P_CheckFor3DCeilingHit(AActor * mo, double z, bool trigger)
{
if ((mo->player && (mo->player->cheats & CF_PREDICTING))) return false;
@ -383,7 +384,8 @@ bool P_CheckFor3DCeilingHit(AActor * mo, double z)
{
if(fabs(z - rover->bottom.plane->ZatPoint(mo)) < EQUAL_EPSILON)
{
rover->model->TriggerSectorActions (mo, SECSPAC_HitCeiling);
mo->BlockingCeiling = rover->model;
if (trigger) rover->model->TriggerSectorActions (mo, SECSPAC_HitCeiling);
return true;
}
}

View file

@ -117,8 +117,8 @@ struct lightlist_t
class player_t;
void P_PlayerOnSpecial3DFloor(player_t* player);
bool P_CheckFor3DFloorHit(AActor * mo, double z);
bool P_CheckFor3DCeilingHit(AActor * mo, double z);
bool P_CheckFor3DFloorHit(AActor * mo, double z, bool trigger);
bool P_CheckFor3DCeilingHit(AActor * mo, double z, bool trigger);
void P_Recalculate3DFloors(sector_t *);
void P_RecalculateAttached3DFloors(sector_t * sec);
void P_RecalculateLights(sector_t *sector);

View file

@ -711,7 +711,7 @@ bool P_Move (AActor *actor)
{
actor->floorsector->TriggerSectorActions(actor, SECSPAC_HitFloor);
}
P_CheckFor3DFloorHit(actor, actor->Z());
P_CheckFor3DFloorHit(actor, actor->Z(), true);
}
}
}

View file

@ -296,6 +296,8 @@ DEFINE_FIELD(AActor, lastbump)
DEFINE_FIELD(AActor, DesignatedTeam)
DEFINE_FIELD(AActor, BlockingMobj)
DEFINE_FIELD(AActor, BlockingLine)
DEFINE_FIELD(AActor, BlockingCeiling)
DEFINE_FIELD(AActor, BlockingFloor)
DEFINE_FIELD(AActor, PoisonDamage)
DEFINE_FIELD(AActor, PoisonDamageType)
DEFINE_FIELD(AActor, PoisonDuration)
@ -478,6 +480,8 @@ void AActor::Serialize(FSerializer &arc)
A("smokecounter", smokecounter)
("blockingmobj", BlockingMobj)
A("blockingline", BlockingLine)
A("blockingceiling", BlockingCeiling)
A("blockingfloor", BlockingFloor)
A("visibletoteam", VisibleToTeam)
A("pushfactor", pushfactor)
A("species", Species)
@ -2552,6 +2556,21 @@ double P_XYMovement (AActor *mo, DVector2 scroll)
AActor *BlockingMobj = mo->BlockingMobj;
line_t *BlockingLine = mo->BlockingLine;
// [ZZ]
if (!BlockingLine && !BlockingMobj) // hit floor or ceiling while XY movement - sector actions
{
int hitpart = -1;
sector_t* hitsector = nullptr;
secplane_t* hitplane = nullptr;
if (tm.ceilingsector && mo->Z() + mo->Height > tm.ceilingsector->ceilingplane.ZatPoint(tm.pos.XY()))
mo->BlockingCeiling = tm.ceilingsector;
if (tm.floorsector && mo->Z() < tm.floorsector->floorplane.ZatPoint(tm.pos.XY()))
mo->BlockingFloor = tm.floorsector;
// the following two only set the appropriate field - to avoid issues caused by running actions right in the middle of XY movement
P_CheckFor3DFloorHit(mo, mo->floorz, false);
P_CheckFor3DCeilingHit(mo, mo->ceilingz, false);
}
if (!(mo->flags & MF_MISSILE) && (mo->BounceFlags & BOUNCE_MBF)
&& (BlockingMobj != NULL ? P_BounceActor(mo, BlockingMobj, false) : P_BounceWall(mo)))
{
@ -2738,25 +2757,15 @@ explode:
}
else onsky = true;
}
if (!mo->BlockingLine && !BlockingMobj) // hit floor or ceiling while XY movement
if (mo->BlockingCeiling) // hit floor or ceiling while XY movement
{
int hitpart = -1;
sector_t* hitsector = nullptr;
// check against floor
if (tm.floorsector && mo->Z() < tm.floorsector->floorplane.ZatPoint(tm.pos.XY()))
{
hitpart = SECPART_Floor;
hitsector = tm.floorsector;
if (hitsector->healthfloor > 0 && P_CheckSectorVulnerable(hitsector, hitpart))
P_DamageSector(hitsector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, hitpart, mo->Pos());
}
if (tm.ceilingsector && mo->Z() + mo->Height > tm.ceilingsector->ceilingplane.ZatPoint(tm.pos.XY()))
{
hitpart = SECPART_Ceiling;
hitsector = tm.ceilingsector;
if (hitsector->healthceiling > 0 && P_CheckSectorVulnerable(hitsector, hitpart))
P_DamageSector(hitsector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, hitpart, mo->Pos());
}
if (mo->BlockingCeiling->healthceiling > 0 && P_CheckSectorVulnerable(mo->BlockingCeiling, SECPART_Ceiling))
P_DamageSector(mo->BlockingCeiling, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Ceiling, mo->Pos());
}
if (mo->BlockingFloor)
{
if (mo->BlockingFloor->healthfloor > 0 && P_CheckSectorVulnerable(mo->BlockingFloor, SECPART_Floor))
P_DamageSector(mo->BlockingFloor, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Floor, mo->Pos());
}
P_ExplodeMissile (mo, mo->BlockingLine, BlockingMobj, onsky);
return Oldfloorz;
@ -3110,13 +3119,14 @@ void P_ZMovement (AActor *mo, double oldfloorz)
mo->Sector->SecActTarget != NULL &&
mo->Sector->floorplane.ZatPoint(mo) == mo->floorz)
{ // [RH] Let the sector do something to the actor
mo->Sector->TriggerSectorActions (mo, SECSPAC_HitFloor);
mo->Sector->TriggerSectorActions(mo, SECSPAC_HitFloor);
}
P_CheckFor3DFloorHit(mo, mo->floorz);
P_CheckFor3DFloorHit(mo, mo->floorz, true);
// [RH] Need to recheck this because the sector action might have
// teleported the actor so it is no longer below the floor.
if (mo->Z() <= mo->floorz)
{
mo->BlockingFloor = mo->Sector;
if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP))
{
mo->SetZ(mo->floorz);
@ -3223,11 +3233,12 @@ void P_ZMovement (AActor *mo, double oldfloorz)
{ // [RH] Let the sector do something to the actor
mo->Sector->TriggerSectorActions (mo, SECSPAC_HitCeiling);
}
P_CheckFor3DCeilingHit(mo, mo->ceilingz);
P_CheckFor3DCeilingHit(mo, mo->ceilingz, true);
// [RH] Need to recheck this because the sector action might have
// teleported the actor so it is no longer above the ceiling.
if (mo->Top() > mo->ceilingz)
{
mo->BlockingCeiling = mo->Sector;
mo->SetZ(mo->ceilingz - mo->Height);
if (mo->BounceFlags & BOUNCE_Ceilings)
{ // ceiling bounce
@ -4505,12 +4516,21 @@ void AActor::Tick ()
}
// Handle X and Y velocities
BlockingMobj = NULL;
BlockingMobj = nullptr;
sector_t* oldBlockingCeiling = BlockingCeiling;
sector_t* oldBlockingFloor = BlockingFloor;
BlockingFloor = nullptr;
BlockingCeiling = nullptr;
double oldfloorz = P_XYMovement (this, cumm);
if (ObjectFlags & OF_EuthanizeMe)
{ // actor was destroyed
return;
}
// [ZZ] trigger hit floor/hit ceiling actions from XY movement
if (BlockingFloor && BlockingFloor != oldBlockingFloor && (!player || !(player->cheats & CF_PREDICTING)) && BlockingFloor->SecActTarget)
BlockingFloor->TriggerSectorActions(this, SECSPAC_HitFloor);
if (BlockingCeiling && BlockingCeiling != oldBlockingCeiling && (!player || !(player->cheats & CF_PREDICTING)) && BlockingCeiling->SecActTarget)
BlockingCeiling->TriggerSectorActions(this, SECSPAC_HitCeiling);
if (Vel.X == 0 && Vel.Y == 0) // Actors at rest
{
if (flags2 & MF2_BLASTED)
@ -4756,11 +4776,11 @@ void AActor::CheckSectorTransition(sector_t *oldsec)
}
if (Z() == floorz)
{
P_CheckFor3DFloorHit(this, Z());
P_CheckFor3DFloorHit(this, Z(), true);
}
if (Top() == ceilingz)
{
P_CheckFor3DCeilingHit(this, Top());
P_CheckFor3DCeilingHit(this, Top(), true);
}
}
}

View file

@ -183,6 +183,8 @@ class Actor : Thinker native
native int DesignatedTeam;
native Actor BlockingMobj;
native Line BlockingLine;
native Sector BlockingCeiling;
native Sector BlockingFloor;
native int PoisonDamage;
native name PoisonDamageType;
native int PoisonDuration;