// // TELEPORTATION // BOOL EV_Teleport(int tid, int tag, int side, AActor *thing) { AActor *m; unsigned an; fixed_t oldx; fixed_t oldy; fixed_t oldz; player_t *player; // don't teleport missiles if (thing->flags & MF_MISSILE) return false; // Don't teleport if hit back of line, so you can get out of teleporter. if (side == 1) return false; // [AM] Use modern ZDoom teleport destination selection. m = SelectTeleDest(tid, tag); if (m == NULL) return false; // killough 5/12/98: exclude voodoo dolls: player = thing->player; if (player && player->mo != thing) player = NULL; oldx = thing->x; oldy = thing->y; oldz = thing->z; fixed_t destz = (m->type == MT_TELEPORTMAN) ? P_FloorHeight(m) : m->z; if (!P_TeleportMove (thing, m->x, m->y, destz, false)) return false; // fraggle: this was changed in final doom, // problem between normal doom2 1.9 and final doom // Note that although chex.exe is based on Final Doom, // it does not have this quirk. if (gamemission < pack_tnt || gamemission == chex) thing->z = thing->floorz; if (player) player->viewz = thing->z + thing->player->viewheight; // spawn teleport fog at source and destination if(serverside && !(player && player->spectator)) { S_Sound (new AActor (oldx, oldy, oldz, MT_TFOG), CHAN_VOICE, "misc/teleport", 1, ATTN_NORM); an = m->angle >> ANGLETOFINESHIFT; // emit sound at new spot S_Sound (new AActor (m->x+20*finecosine[an], m->y+20*finesine[an], thing->z, MT_TFOG), CHAN_VOICE, "misc/teleport", 1, ATTN_NORM); }
bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags) { AActor *searcher; double z; DAngle angle = 0.; double s = 0, c = 0; double vx = 0, vy = 0; DAngle badangle = 0.; if (thing == NULL) { // Teleport function called with an invalid actor return false; } bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING)); if (thing->flags2 & MF2_NOTELEPORT) { return false; } if (side != 0) { // Don't teleport if hit back of line, so you can get out of teleporter. return 0; } searcher = SelectTeleDest(tid, tag, predicting); if (searcher == NULL) { return false; } // [RH] Lee Killough's changes for silent teleporters from BOOM if ((flags & (TELF_ROTATEBOOM|TELF_ROTATEBOOMINVERSE)) && line) { // Get the angle between the exit thing and source linedef. // Rotate 90 degrees, so that walking perpendicularly across // teleporter linedef causes thing to exit in the direction // indicated by the exit thing. angle = line->Delta().Angle() - searcher->Angles.Yaw + 90.; if (flags & TELF_ROTATEBOOMINVERSE) angle = -angle; // Sine, cosine of angle adjustment s = angle.Sin(); c = angle.Cos(); // Velocity of thing crossing teleporter linedef vx = thing->Vel.X; vy = thing->Vel.Y; z = searcher->Z(); } else if (searcher->IsKindOf (PClass::FindClass(NAME_TeleportDest2))) { z = searcher->Z(); } else { z = ONFLOORZ; } if ((i_compatflags2 & COMPATF2_BADANGLES) && (thing->player != NULL)) { badangle = 0.01; } if (P_Teleport (thing, DVector3(searcher->Pos(), z), searcher->Angles.Yaw + badangle, flags)) { // [RH] Lee Killough's changes for silent teleporters from BOOM if (line) { if (flags & (TELF_ROTATEBOOM| TELF_ROTATEBOOMINVERSE)) { // Rotate thing according to difference in angles (or not - Boom got the direction wrong here.) thing->Angles.Yaw += angle; // Rotate thing's velocity to come out of exit just like it entered thing->Vel.X = vx*c - vy*s; thing->Vel.Y = vy*c + vx*s; } } if (vx == 0 && vy == 0 && thing->player != NULL && thing->player->mo == thing && !predicting) { thing->player->mo->PlayIdle (); } return true; } return false; }