// // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005-2014 Simon Howard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // DESCRIPTION: // Teleportation. // #include "d_mode.h" #include "d_player.h" #include "d_think.h" #include "doomstat.h" #include "info.h" #include "m_fixed.h" #include "p_local.h" #include "p_mobj.h" #include "r_defs.h" // State. #include "r_state.h" #include "s_sound.h" // Data. #include "sounds.h" #include "tables.h" // // TELEPORTATION // int EV_Teleport(line_t *line, int side, mobj_t *thing) { int i; int tag; mobj_t *m; mobj_t *fog; unsigned an; thinker_t *thinker; sector_t *sector; fixed_t oldx; fixed_t oldy; fixed_t oldz; // don't teleport missiles if (thing->flags & MF_MISSILE) return 0; // Don't teleport if hit back of line, // so you can get out of teleporter. if (side == 1) return 0; 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) { // not a mobj if (thinker->function.acp1 != (actionf_p1)P_MobjThinker) continue; m = (mobj_t *)thinker; // not a teleportman if (m->type != MT_TELEPORTMAN) continue; sector = m->subsector->sector; // wrong sector if (sector - sectors != i) continue; oldx = thing->x; oldy = thing->y; oldz = thing->z; if (!P_TeleportMove(thing, m->x, m->y)) return 0; // The first Final Doom executable does not set thing->z // when teleporting. This quirk is unique to this // particular version; the later version included in // some versions of the Id Anthology fixed this. if (gameversion != exe_final) thing->z = thing->floorz; if (thing->player) thing->player->viewz = thing->z + thing->player->viewheight; // spawn teleport fog at source and destination fog = P_SpawnMobj(oldx, oldy, oldz, MT_TFOG); S_StartSound(fog, sfx_telept); an = m->angle >> ANGLETOFINESHIFT; fog = P_SpawnMobj(m->x + 20 * finecosine[an], m->y + 20 * finesine[an], thing->z, MT_TFOG); // emit sound, where? S_StartSound(fog, sfx_telept); // don't move for a bit if (thing->player) thing->reactiontime = 18; thing->angle = m->angle; thing->momx = thing->momy = thing->momz = 0; return 1; } } } return 0; }