mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
180 lines
5 KiB
C
180 lines
5 KiB
C
// SONIC ROBO BLAST 2
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
|
//
|
|
// This program is free software distributed under the
|
|
// terms of the GNU General Public License, version 2.
|
|
// See the 'LICENSE' file for more details.
|
|
//-----------------------------------------------------------------------------
|
|
/// \file p_telept.c
|
|
/// \brief Teleportation
|
|
|
|
#include "doomdef.h"
|
|
#include "g_game.h"
|
|
#include "p_local.h"
|
|
#include "r_state.h"
|
|
#include "s_sound.h"
|
|
#include "r_main.h"
|
|
|
|
/** \brief The P_MixUp function
|
|
|
|
\param thing mobj_t to mix up
|
|
\param x new x pos
|
|
\param y new y pos
|
|
\param z new y pos
|
|
\param angle new angle to look at
|
|
|
|
\return void
|
|
|
|
|
|
*/
|
|
void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
|
INT16 starpostx, INT16 starposty, INT16 starpostz,
|
|
INT32 starpostnum, tic_t starposttime, angle_t starpostangle,
|
|
fixed_t starpostscale, angle_t drawangle, INT32 flags2)
|
|
{
|
|
const INT32 takeflags2 = MF2_TWOD|MF2_OBJECTFLIP;
|
|
|
|
// the move is ok,
|
|
// so link the thing into its new position
|
|
P_UnsetThingPosition(thing);
|
|
|
|
// Remove touching_sectorlist from mobj.
|
|
if (sector_list)
|
|
{
|
|
P_DelSeclist(sector_list);
|
|
sector_list = NULL;
|
|
}
|
|
|
|
thing->x = x;
|
|
thing->y = y;
|
|
thing->z = z;
|
|
|
|
if (thing->player)
|
|
{
|
|
if (thing->eflags & MFE_VERTICALFLIP)
|
|
thing->player->viewz = thing->z + thing->height - thing->player->viewheight;
|
|
else
|
|
thing->player->viewz = thing->z + thing->player->viewheight;
|
|
|
|
if (!thing->tracer)
|
|
thing->reactiontime = TICRATE/2; // don't move for about half a second
|
|
|
|
// absolute angle position
|
|
P_SetPlayerAngle(thing->player, angle);
|
|
|
|
// move chasecam at new player location
|
|
if (splitscreen && camera2.chase
|
|
&& thing->player == &players[secondarydisplayplayer])
|
|
{
|
|
P_ResetCamera(thing->player, &camera2);
|
|
}
|
|
else if (camera.chase && thing->player == &players[displayplayer])
|
|
P_ResetCamera(thing->player, &camera);
|
|
|
|
// don't run in place after a teleport
|
|
thing->player->cmomx = thing->player->cmomy = 0;
|
|
thing->player->rmomx = thing->player->rmomy = 0;
|
|
if (!thing->tracer)
|
|
thing->player->speed = 0;
|
|
|
|
// Starpost information
|
|
thing->player->starpostx = starpostx;
|
|
thing->player->starposty = starposty;
|
|
thing->player->starpostz = starpostz;
|
|
thing->player->starposttime = starposttime;
|
|
thing->player->starpostangle = starpostangle;
|
|
thing->player->starpostscale = starpostscale;
|
|
thing->player->starpostnum = starpostnum;
|
|
|
|
thing->player->drawangle = drawangle;
|
|
|
|
// Reset map starposts for the player's new info.
|
|
P_ResetStarposts();
|
|
P_ClearStarPost(starpostnum);
|
|
|
|
P_ResetPlayer(thing->player);
|
|
P_SetMobjState(thing, S_PLAY_STND);
|
|
|
|
P_FlashPal(thing->player, PAL_MIXUP, 10);
|
|
}
|
|
|
|
thing->angle = angle;
|
|
|
|
thing->momx = thing->momy = thing->momz = 0;
|
|
|
|
thing->flags2 = (thing->flags2 & ~takeflags2) | (flags2 & takeflags2);
|
|
}
|
|
|
|
/** \brief The P_Teleport function
|
|
|
|
\param thing mobj_t to teleport
|
|
\param x new x pos
|
|
\param y new y pos
|
|
\param z new y pos
|
|
\param angle new angle to look at
|
|
|
|
\return if true, the thing "teleported"
|
|
|
|
|
|
*/
|
|
boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, boolean flash, boolean dontstopmove)
|
|
{
|
|
if (!P_SetOrigin(thing, x, y, z))
|
|
return false;
|
|
|
|
if (!dontstopmove)
|
|
thing->momx = thing->momy = thing->momz = 0;
|
|
else // Change speed to match direction
|
|
P_InstaThrust(thing, angle, FixedHypot(thing->momx, thing->momy));
|
|
|
|
if (thing->player)
|
|
{
|
|
if (thing->eflags & MFE_VERTICALFLIP)
|
|
thing->player->viewz = thing->z + thing->height - thing->player->viewheight;
|
|
else
|
|
thing->player->viewz = thing->z + thing->player->viewheight;
|
|
|
|
// don't run in place after a teleport
|
|
if (!dontstopmove)
|
|
{
|
|
INT32 p;
|
|
// Search for any players you might be carrying, so you can get them off before they end up being taken with you!
|
|
for (p = 0; p < MAXPLAYERS; p++)
|
|
if (playeringame[p] && players[p].mo && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == thing)
|
|
{
|
|
players[p].powers[pw_carry] = CR_NONE;
|
|
P_SetTarget(&players[p].mo->tracer, NULL);
|
|
break;
|
|
}
|
|
thing->player->cmomx = thing->player->cmomy = 0;
|
|
thing->player->rmomx = thing->player->rmomy = 0;
|
|
thing->player->speed = 0;
|
|
P_ResetPlayer(thing->player);
|
|
P_SetMobjState(thing, S_PLAY_STND);
|
|
|
|
thing->reactiontime = TICRATE/2; // don't move for about half a second
|
|
thing->player->drawangle = angle;
|
|
}
|
|
else
|
|
thing->player->drawangle += (angle - thing->angle);
|
|
|
|
// absolute angle position
|
|
P_SetPlayerAngle(thing->player, angle);
|
|
|
|
// move chasecam at new player location
|
|
if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer])
|
|
P_ResetCamera(thing->player, &camera2);
|
|
else if (camera.chase && thing->player == &players[displayplayer])
|
|
P_ResetCamera(thing->player, &camera);
|
|
|
|
if (flash)
|
|
P_FlashPal(thing->player, PAL_MIXUP, 10);
|
|
}
|
|
|
|
thing->angle = angle;
|
|
|
|
return true;
|
|
}
|