Kart-Public/src/p_telept.c

193 lines
5.8 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-2016 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,
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
if (thing == players[consoleplayer].mo)
localangle = angle;
if (thing == players[secondarydisplayplayer].mo)
localangle2 = angle;
if (thing == players[thirddisplayplayer].mo)
localangle3 = angle;
if (thing == players[fourthdisplayplayer].mo)
localangle4 = angle;
// move chasecam at new player location
if (splitscreen > 2 && camera4.chase && thing->player == &players[fourthdisplayplayer])
P_ResetCamera(thing->player, &camera4);
else if (splitscreen > 1 && camera3.chase && thing->player == &players[thirddisplayplayer])
P_ResetCamera(thing->player, &camera3);
else 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->starpostnum = starpostnum;
// Reset map starposts for the player's new info.
P_ResetStarposts();
P_ClearStarPost(starpostnum);
P_ResetPlayer(thing->player);
P_SetPlayerMobjState(thing, S_KART_STND1); // SRB2kart - was 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_TeleportMove(thing, x, y, z))
return false;
thing->angle = angle;
if (!dontstopmove)
thing->momx = thing->momy = thing->momz = 0;
else // Change speed to match direction
P_InstaThrust(thing, thing->angle, P_AproxDistance(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;
if (!dontstopmove)
thing->reactiontime = TICRATE/2; // don't move for about half a second
// absolute angle position
if (thing->player == &players[consoleplayer])
localangle = angle;
if (thing->player == &players[secondarydisplayplayer])
localangle2 = angle;
if (thing->player == &players[thirddisplayplayer])
localangle3 = angle;
if (thing->player == &players[fourthdisplayplayer])
localangle4 = angle;
// move chasecam at new player location
if (splitscreen > 2 && camera4.chase && thing->player == &players[fourthdisplayplayer])
P_ResetCamera(thing->player, &camera4);
else if (splitscreen > 1 && camera3.chase && thing->player == &players[thirddisplayplayer])
P_ResetCamera(thing->player, &camera3);
else 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
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].pflags & PF_CARRIED && players[p].mo->tracer == thing)
{
players[p].pflags &= ~PF_CARRIED;
break;
}
thing->player->cmomx = thing->player->cmomy = 0;
thing->player->rmomx = thing->player->rmomy = 0;
thing->player->speed = 0;
P_ResetPlayer(thing->player);
P_SetPlayerMobjState(thing, S_KART_STND1); // SRB2kart - was S_PLAY_STND
}
if (flash)
P_FlashPal(thing->player, PAL_MIXUP, 10);
}
return true;
}