149 lines
3.2 KiB
C++
149 lines
3.2 KiB
C++
|
|
||
|
// 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);
|
||
|
}
|