Skip to content

Commit 80c2276

Browse files
committed
Fixed oversight with telestomp; removed awkward P_HereticTeleport
1 parent a2dda52 commit 80c2276

6 files changed

Lines changed: 70 additions & 107 deletions

File tree

changelogs/changes-since-4.5.4.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Improvements
9090
* ACS SetLineBlocking now also supports BLOCK_PLAYERS.
9191
* Fixed so the Heretic ghost translucency takes precedence over the weaker (by TRANMAP) Boom default translucency.
9292
* Added some readily available APROP implementations to the GetActorProperty and CheckActorProperty ACS functions.
93+
* Fixed so Doom teleportation also works fine with Heretic-like flying players or telestomp projectiles.
9394

9495
Bug fixes
9596
---------

source/a_weaponsheretic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ void A_HticArtiTele(actionargs_t *actionargs)
878878
destAngle = ANG45 * (playerstarts[0].angle / 45);
879879
}
880880

881-
P_HereticTeleport(mo, destX, destY, destAngle, false);
881+
P_Teleport(mo, { destX, destY }, destAngle, false);
882882
S_StartSound(nullptr, sfx_hwpnup);
883883
}
884884

source/acs_func.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2459,7 +2459,7 @@ bool ACS_CF_SetActorPosition(ACS_CF_ARGS)
24592459
S_StartSound(fogmo, GameModeInfo->teleSound);
24602460

24612461
// ... and destination.
2462-
v3fixed_t fogpos = P_GetArrivalTelefogLocation({ x, y, z }, mo->angle);
2462+
v3fixed_t fogpos = P_GetArrivalTelefogLocation(*mo, { x, y, z }, mo->angle);
24632463
fogmo = P_SpawnMobj(fogpos.x, fogpos.y, fogpos.z, E_SafeThingName(GameModeInfo->teleFogType));
24642464
S_StartSound(fogmo, GameModeInfo->teleSound);
24652465
}

source/p_mobj.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,11 @@ inline static void P_transferFriendship(Mobj &target, const Mobj &source)
848848
target.flags = (target.flags & ~MF_FRIEND) | (source.flags & MF_FRIEND);
849849
}
850850

851+
inline static bool P_allowTeleport(const Mobj &thing)
852+
{
853+
return !(thing.flags & MF_MISSILE) || thing.flags3 & MF3_TELESTOMP;
854+
}
855+
851856
#endif
852857

853858
//----------------------------------------------------------------------------

source/p_spec.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,7 +1416,7 @@ struct teleparms_t
14161416
teleangle_e teleangle;
14171417
};
14181418

1419-
bool P_HereticTeleport(Mobj *thing, fixed_t x, fixed_t y, angle_t angle, bool alwaysfrag);
1419+
int P_Teleport(Mobj *thing, v2fixed_t landingpos, angle_t landingangle, bool alwaysfrag);
14201420

14211421
int EV_Teleport(int tag, int side, Mobj *thing, bool alwaysfrag);
14221422

@@ -1676,7 +1676,7 @@ void P_ZeroSectorSpecial(sector_t *);
16761676

16771677
void P_SetLineID(line_t *line, int id);
16781678

1679-
v3fixed_t P_GetArrivalTelefogLocation(v3fixed_t landing, angle_t angle);
1679+
v3fixed_t P_GetArrivalTelefogLocation(const Mobj &thing, v3fixed_t landing, angle_t angle);
16801680

16811681
// haleyjd: parameterized lines
16821682

source/p_telept.cpp

Lines changed: 60 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -63,113 +63,59 @@ static void P_dropToFloor(Mobj *thing, player_t *player)
6363
}
6464
}
6565

66-
//
67-
// P_Teleport from Heretic, but made to be more generic and Eternity-ready
68-
// FIXME: This should be made more generic, so that other stuff can benefit from it
69-
//
70-
bool P_HereticTeleport(Mobj *thing, fixed_t x, fixed_t y, angle_t angle, bool alwaysfrag)
71-
{
72-
fixed_t oldx, oldy, oldz, aboveFloor, fogDelta;
73-
player_t *player;
74-
unsigned an;
75-
76-
oldx = thing->x;
77-
oldy = thing->y;
78-
oldz = thing->z;
79-
aboveFloor = thing->z - thing->zref.floor;
80-
if(!P_TeleportMove(thing, x, y, alwaysfrag ? TELEMOVE_FRAG : 0))
81-
return false;
82-
83-
if((player = thing->player))
84-
{
85-
if(player->powers[pw_flight].isActive() && aboveFloor)
86-
{
87-
thing->z = thing->zref.floor + aboveFloor;
88-
if(thing->z + thing->height > thing->zref.ceiling)
89-
thing->z = thing->zref.ceiling - thing->height;
90-
player->prevviewz = player->viewz = thing->z + player->viewheight;
91-
}
92-
else
93-
{
94-
P_dropToFloor(thing, player);
95-
player->prevpitch = player->pitch = 0;
96-
}
97-
}
98-
else if(thing->flags & MF_MISSILE)
99-
{
100-
thing->z = thing->zref.floor + aboveFloor;
101-
if(thing->z + thing->height > thing->zref.ceiling)
102-
thing->z = thing->zref.ceiling - thing->height;
103-
}
104-
else
105-
P_dropToFloor(thing, nullptr);
106-
107-
if(thing->player == players + displayplayer)
108-
P_ResetChasecam();
109-
110-
// Spawn teleport fog at source and destination
111-
const int fogNum = E_SafeThingName(GameModeInfo->teleFogType);
112-
fogDelta = thing->flags & MF_MISSILE ? 0 : GameModeInfo->teleFogHeight;
113-
S_StartSound(P_SpawnMobj(oldx, oldy, oldz + fogDelta, fogNum), GameModeInfo->teleSound);
114-
an = angle >> ANGLETOFINESHIFT;
115-
v2fixed_t pos = P_LinePortalCrossing(x, y, 20 * finecosine[an], 20 * finesine[an]);
116-
S_StartSound(P_SpawnMobj(pos.x, pos.y, thing->z + fogDelta, fogNum), GameModeInfo->teleSound);
117-
118-
// Freeze player for ~.5s, but only if they don't have tome active
119-
if(thing->player && !thing->player->powers[pw_weaponlevel2].isActive())
120-
thing->reactiontime = 18;
121-
thing->angle = angle;
122-
if(thing->flags & MF_MISSILE)
123-
{
124-
angle >>= ANGLETOFINESHIFT;
125-
thing->momx = FixedMul(thing->info->speed, finecosine[angle]);
126-
thing->momy = FixedMul(thing->info->speed, finesine[angle]);
127-
}
128-
else
129-
thing->momx = thing->momy = thing->momz = 0;
130-
131-
// killough 10/98: kill all bobbing momentum too
132-
if(player)
133-
player->momx = player->momy = 0;
134-
135-
thing->backupPosition();
136-
P_AdjustFloorClip(thing);
137-
138-
return true;
139-
}
140-
14166
//
14267
// Gets the telefog coordinates for an arrival telefog, which must be in front of the thing
14368
//
144-
v3fixed_t P_GetArrivalTelefogLocation(v3fixed_t landing, angle_t angle)
69+
v3fixed_t P_GetArrivalTelefogLocation(const Mobj &thing, v3fixed_t landing, angle_t angle)
14570
{
146-
v2fixed_t pos = P_LinePortalCrossing(landing.x, landing.y, 20 * finecosine[angle >> ANGLETOFINESHIFT],
147-
20 * finesine[angle >> ANGLETOFINESHIFT]);
148-
return { pos.x, pos.y, landing.z + GameModeInfo->teleFogHeight };
71+
v2fixed_t pos = P_LinePortalCrossing(landing.x, landing.y, 20 * finecosine[angle >> ANGLETOFINESHIFT],
72+
20 * finesine[angle >> ANGLETOFINESHIFT]);
73+
const fixed_t fogDelta = thing.flags & MF_MISSILE ? 0 : GameModeInfo->teleFogHeight;
74+
return { pos.x, pos.y, landing.z + fogDelta };
14975
}
15076

15177
//
15278
// ioanch 20160330
15379
// General teleportation routine. Needed because it's reused by Hexen's teleport
15480
//
155-
static int P_Teleport(Mobj *thing, const Mobj *landing, bool alwaysfrag)
81+
int P_Teleport(Mobj *thing, v2fixed_t landingpos, angle_t landingangle, bool alwaysfrag)
15682
{
157-
if(GameModeInfo->type == Game_Heretic)
158-
return P_HereticTeleport(thing, landing->x, landing->y, landing->angle, alwaysfrag);
159-
160-
fixed_t oldx = thing->x, oldy = thing->y, oldz = thing->z;
161-
player_t *player = thing->player;
83+
fixed_t oldx = thing->x, oldy = thing->y, oldz = thing->z;
84+
player_t *player = thing->player;
85+
const fixed_t aboveFloor = thing->z - thing->zref.floor;
16286

16387
// killough 5/12/98: exclude voodoo dolls:
164-
if(player && player->mo != thing)
88+
if(player && player->mo != thing && !vanilla_heretic)
16589
player = nullptr;
16690

167-
if(!P_TeleportMove(thing, landing->x, landing->y, alwaysfrag ? TELEMOVE_FRAG : 0)) // killough 8/9/98
91+
if(!P_TeleportMove(thing, landingpos.x, landingpos.y, alwaysfrag ? TELEMOVE_FRAG : 0)) // killough 8/9/98
16892
return 0;
16993

170-
P_dropToFloor(thing, player);
94+
auto preserveHeight = [thing, aboveFloor]() {
95+
thing->z = thing->zref.floor + aboveFloor;
96+
if(thing->z + thing->height > thing->zref.ceiling)
97+
thing->z = thing->zref.ceiling - thing->height;
98+
};
99+
if(player)
100+
{
101+
if(player->powers[pw_flight].isActive() && aboveFloor)
102+
{
103+
preserveHeight();
104+
player->prevviewz = player->viewz = thing->z + player->viewheight;
105+
}
106+
else
107+
{
108+
P_dropToFloor(thing, player);
109+
if(GameModeInfo->type == Game_Heretic)
110+
player->prevpitch = player->pitch = 0;
111+
}
112+
}
113+
else if(thing->flags & MF_MISSILE)
114+
preserveHeight();
115+
else
116+
P_dropToFloor(thing, nullptr);
171117

172-
thing->angle = landing->angle;
118+
thing->angle = landingangle;
173119

174120
// sf: reset the chasecam at its new position.
175121
// this needs to be done before startsound so we hear
@@ -178,13 +124,14 @@ static int P_Teleport(Mobj *thing, const Mobj *landing, bool alwaysfrag)
178124
P_ResetChasecam();
179125

180126
// spawn teleport fog and emit sound at source
181-
S_StartSound(
182-
P_SpawnMobj(oldx, oldy, oldz + GameModeInfo->teleFogHeight, E_SafeThingName(GameModeInfo->teleFogType)),
183-
GameModeInfo->teleSound);
127+
const fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : GameModeInfo->teleFogHeight;
128+
S_StartSound(P_SpawnMobj(oldx, oldy, oldz + fogDelta, E_SafeThingName(GameModeInfo->teleFogType)),
129+
GameModeInfo->teleSound);
184130

185131
// spawn teleport fog and emit sound at destination
186132
// ioanch 20160229: portal aware
187-
v3fixed_t landingFogPos = P_GetArrivalTelefogLocation({ landing->x, landing->y, thing->z }, landing->angle);
133+
v3fixed_t landingFogPos =
134+
P_GetArrivalTelefogLocation(*thing, { landingpos.x, landingpos.y, thing->z }, landingangle);
188135
S_StartSound(
189136
P_SpawnMobj(landingFogPos.x, landingFogPos.y, landingFogPos.z, E_SafeThingName(GameModeInfo->teleFogType)),
190137
GameModeInfo->teleSound);
@@ -193,11 +140,21 @@ static int P_Teleport(Mobj *thing, const Mobj *landing, bool alwaysfrag)
193140
P_AdjustFloorClip(thing);
194141

195142
// don't move for a bit // killough 10/98
196-
if(thing->player)
143+
// Freeze player for ~.5s, but only if they don't have tome active
144+
if(thing->player && !thing->player->powers[pw_weaponlevel2].isActive())
197145
thing->reactiontime = 18;
198146

199-
// kill all momentum
200-
thing->momx = thing->momy = thing->momz = 0;
147+
if(thing->flags & MF_MISSILE)
148+
{
149+
int fineangle = landingangle >> ANGLETOFINESHIFT;
150+
thing->momx = FixedMul(thing->info->speed, finecosine[fineangle]);
151+
thing->momy = FixedMul(thing->info->speed, finesine[fineangle]);
152+
}
153+
else
154+
{
155+
// kill all momentum
156+
thing->momx = thing->momy = thing->momz = 0;
157+
}
201158

202159
// killough 10/98: kill all bobbing momentum too
203160
if(player)
@@ -317,7 +274,7 @@ int EV_Teleport(int tag, int side, Mobj *thing, bool alwaysfrag)
317274
// don't teleport missiles
318275
// Don't teleport if hit back of line,
319276
// so you can get out of teleporter.
320-
if(!thing || side || (thing->flags & MF_MISSILE && !(thing->flags3 & MF3_TELESTOMP)))
277+
if(!thing || side || !P_allowTeleport(*thing))
321278
return 0;
322279

323280
// killough 1/31/98: improve performance by using
@@ -332,7 +289,7 @@ int EV_Teleport(int tag, int side, Mobj *thing, bool alwaysfrag)
332289

333290
if(m->type == E_ThingNumForDEHNum(MT_TELEPORTMAN) && m->subsector->sector - sectors == i)
334291
{
335-
return P_Teleport(thing, m, alwaysfrag);
292+
return P_Teleport(thing, { m->x, m->y }, m->angle, alwaysfrag);
336293
}
337294
}
338295
}
@@ -367,14 +324,14 @@ int EV_ParamTeleport(int tid, int tag, int side, Mobj *thing, bool alwaysfrag)
367324
// don't teleport missiles
368325
// Don't teleport if hit back of line,
369326
// so you can get out of teleporter.
370-
if(!thing || side || thing->flags & MF_MISSILE)
327+
if(!thing || side || !P_allowTeleport(*thing))
371328
return 0;
372329

373330
if(tid)
374331
{
375332
const Mobj *mobj = P_pickRandomLanding(tid, tag);
376333
if(mobj)
377-
return P_Teleport(thing, mobj, alwaysfrag);
334+
return P_Teleport(thing, { mobj->x, mobj->y }, mobj->angle, alwaysfrag);
378335
return 0;
379336
}
380337

@@ -397,7 +354,7 @@ int EV_SilentTeleport(const line_t *line, int tag, int side, Mobj *thing, telepa
397354
// Don't teleport if hit back of line,
398355
// so you can get out of teleporter.
399356

400-
if(!thing || side || thing->flags & MF_MISSILE)
357+
if(!thing || side || !P_allowTeleport(*thing))
401358
return 0;
402359

403360
for(i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0;)
@@ -421,7 +378,7 @@ int EV_SilentTeleport(const line_t *line, int tag, int side, Mobj *thing, telepa
421378
//
422379
int EV_ParamSilentTeleport(int tid, const line_t *line, int tag, int side, Mobj *thing, teleparms_t parms)
423380
{
424-
if(!thing || side || thing->flags & MF_MISSILE)
381+
if(!thing || side || !P_allowTeleport(*thing))
425382
return 0;
426383

427384
if(tid)
@@ -451,7 +408,7 @@ int EV_SilentLineTeleport(const line_t *line, int lineid, int side, Mobj *thing,
451408
line_t *l;
452409

453410
// ioanch 20160424: protect against null line or thing pointer
454-
if(side || !thing || thing->flags & MF_MISSILE || !line)
411+
if(side || !thing || !P_allowTeleport(*thing) || !line)
455412
return 0;
456413

457414
for(i = -1; (i = P_FindLineFromTag(lineid, i)) >= 0;)

0 commit comments

Comments
 (0)