summaryrefslogtreecommitdiff
path: root/src/heretic/p_telept.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/heretic/p_telept.c')
-rw-r--r--src/heretic/p_telept.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/heretic/p_telept.c b/src/heretic/p_telept.c
new file mode 100644
index 00000000..614e2c25
--- /dev/null
+++ b/src/heretic/p_telept.c
@@ -0,0 +1,148 @@
+
+// P_telept.c
+
+#include "DoomDef.h"
+#include "P_local.h"
+#include "soundst.h"
+
+//----------------------------------------------------------------------------
+//
+// FUNC P_Teleport
+//
+//----------------------------------------------------------------------------
+
+boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, angle_t angle)
+{
+ fixed_t oldx;
+ fixed_t oldy;
+ fixed_t oldz;
+ fixed_t aboveFloor;
+ fixed_t fogDelta;
+ player_t *player;
+ unsigned an;
+ mobj_t *fog;
+
+ oldx = thing->x;
+ oldy = thing->y;
+ oldz = thing->z;
+ aboveFloor = thing->z-thing->floorz;
+ if(!P_TeleportMove(thing, x, y))
+ {
+ return(false);
+ }
+ if(thing->player)
+ {
+ player = thing->player;
+ if(player->powers[pw_flight] && aboveFloor)
+ {
+ thing->z = thing->floorz+aboveFloor;
+ if(thing->z+thing->height > thing->ceilingz)
+ {
+ thing->z = thing->ceilingz-thing->height;
+ }
+ player->viewz = thing->z+player->viewheight;
+ }
+ else
+ {
+ thing->z = thing->floorz;
+ player->viewz = thing->z+player->viewheight;
+ player->lookdir = 0;
+ }
+ }
+ else if(thing->flags&MF_MISSILE)
+ {
+ thing->z = thing->floorz+aboveFloor;
+ if(thing->z+thing->height > thing->ceilingz)
+ {
+ thing->z = thing->ceilingz-thing->height;
+ }
+ }
+ else
+ {
+ thing->z = thing->floorz;
+ }
+ // Spawn teleport fog at source and destination
+ fogDelta = thing->flags&MF_MISSILE ? 0 : TELEFOGHEIGHT;
+ fog = P_SpawnMobj(oldx, oldy, oldz+fogDelta, MT_TFOG);
+ S_StartSound(fog, sfx_telept);
+ an = angle>>ANGLETOFINESHIFT;
+ fog = P_SpawnMobj(x+20*finecosine[an],
+ y+20*finesine[an], thing->z+fogDelta, MT_TFOG);
+ S_StartSound(fog, sfx_telept);
+ if(thing->player && !thing->player->powers[pw_weaponlevel2])
+ { // Freeze player for about .5 sec
+ thing->reactiontime = 18;
+ }
+ thing->angle = angle;
+ if(thing->flags2&MF2_FOOTCLIP && P_GetThingFloorType(thing) != FLOOR_SOLID)
+ {
+ thing->flags2 |= MF2_FEETARECLIPPED;
+ }
+ else if(thing->flags2&MF2_FEETARECLIPPED)
+ {
+ thing->flags2 &= ~MF2_FEETARECLIPPED;
+ }
+ if(thing->flags&MF_MISSILE)
+ {
+ angle >>= ANGLETOFINESHIFT;
+ thing->momx = FixedMul(thing->info->speed, finecosine[angle]);
+ thing->momy = FixedMul(thing->info->speed, finesine[angle]);
+ }
+ else
+ {
+ thing->momx = thing->momy = thing->momz = 0;
+ }
+ return(true);
+}
+
+//----------------------------------------------------------------------------
+//
+// FUNC EV_Teleport
+//
+//----------------------------------------------------------------------------
+
+boolean EV_Teleport(line_t *line, int side, mobj_t *thing)
+{
+ int i;
+ int tag;
+ mobj_t *m;
+ thinker_t *thinker;
+ sector_t *sector;
+
+ if(thing->flags2&MF2_NOTELEPORT)
+ {
+ return(false);
+ }
+ if(side == 1)
+ { // Don't teleport when crossing back side
+ return(false);
+ }
+ tag = line->tag;
+ for(i = 0; i < numsectors; i++)
+ {
+ if(sectors[i].tag == tag)
+ {
+ thinker = thinkercap.next;
+ for(thinker = thinkercap.next; thinker != &thinkercap;
+ thinker = thinker->next)
+ {
+ if(thinker->function != P_MobjThinker)
+ { // Not a mobj
+ continue;
+ }
+ m = (mobj_t *)thinker;
+ if(m->type != MT_TELEPORTMAN )
+ { // Not a teleportman
+ continue;
+ }
+ sector = m->subsector->sector;
+ if(sector-sectors != i)
+ { // Wrong sector
+ continue;
+ }
+ return(P_Teleport(thing, m->x, m->y, m->angle));
+ }
+ }
+ }
+ return(false);
+}