ref: 7110aba73616e4f84b933a0db1ff96c4c22a9d6f
dir: /p_telept.c/
// P_telept.c
// HEADER FILES ------------------------------------------------------------
#include "h2stdinc.h"
#include "doomdef.h"
#include "p_local.h"
#include "soundst.h"
// MACROS ------------------------------------------------------------------
// TYPES -------------------------------------------------------------------
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
// PUBLIC DATA DEFINITIONS -------------------------------------------------
// PRIVATE DATA DEFINITIONS ------------------------------------------------
// CODE --------------------------------------------------------------------
//==========================================================================
//
// 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 int 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;
}