// // P_Teleport from Heretic, but made to be more generic and Eternity-ready // FIXME: This should be made more generic, so that other stuff can benefit from it // bool P_HereticTeleport(Mobj *thing, fixed_t x, fixed_t y, angle_t angle) { fixed_t oldx, oldy, oldz, aboveFloor, fogDelta; player_t *player; unsigned an; oldx = thing->x; oldy = thing->y; oldz = thing->z; aboveFloor = thing->z - thing->floorz; if(!P_TeleportMove(thing, x, y, false)) return false; if((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->prevviewz = player->viewz = thing->z + player->viewheight; } else { P_dropToFloor(thing, player); player->prevpitch = player->pitch = 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 P_dropToFloor(thing, nullptr); // Spawn teleport fog at source and destination const int fogNum = E_SafeThingName(GameModeInfo->teleFogType); fogDelta = thing->flags & MF_MISSILE ? 0 : GameModeInfo->teleFogHeight; S_StartSound(P_SpawnMobj(oldx, oldy, oldz + fogDelta, fogNum), GameModeInfo->teleSound); an = angle >> ANGLETOFINESHIFT; S_StartSound(P_SpawnMobj(x + 20 * finecosine[an], y + 20 * finesine[an], thing->z + fogDelta, fogNum), GameModeInfo->teleSound); // Freeze player for ~.5s, but only if they don't have tome active if(thing->player && !thing->player->powers[pw_weaponlevel2]) thing->reactiontime = 18; thing->angle = angle; if(thing->flags & MF_MISSILE) { angle >>= ANGLETOFINESHIFT; thing->momx = FixedMul(thing->info->speed, finecosine[angle]); thing->momy = FixedMul(thing->info->speed, finesine[angle]); }
// // ACS_funcSetThingPosition // static void ACS_funcSetThingPosition(ACS_FUNCARG) { int32_t tid = args[0]; fixed_t x = args[1]; fixed_t y = args[2]; fixed_t z = args[3]; bool fog = args[4] ? true : false; Mobj *mo, *fogmo; if((mo = P_FindMobjFromTID(tid, NULL, thread->trigger))) { fixed_t oldx = mo->x; fixed_t oldy = mo->y; fixed_t oldz = mo->z; mo->z = z; if(P_CheckPositionExt(mo, x, y)) { subsector_t *newsubsec; newsubsec = R_PointInSubsector(x, y); // Set new position. P_UnsetThingPosition(mo); mo->floorz = mo->dropoffz = newsubsec->sector->floorheight; mo->ceilingz = newsubsec->sector->ceilingheight; mo->passfloorz = mo->secfloorz = mo->floorz; mo->passceilz = mo->secceilz = mo->ceilingz; mo->x = x; mo->y = y; mo->backupPosition(); P_SetThingPosition(mo); // Handle fog. if(fog) { // Teleport fog at source... fogmo = P_SpawnMobj(oldx, oldy, oldz + GameModeInfo->teleFogHeight, E_SafeThingName(GameModeInfo->teleFogType)); S_StartSound(fogmo, GameModeInfo->teleSound); // ... and destination. fogmo = P_SpawnMobj(x, y, z + GameModeInfo->teleFogHeight, E_SafeThingName(GameModeInfo->teleFogType)); S_StartSound(fogmo, GameModeInfo->teleSound); } *retn++ = 1; } else { mo->z = oldz; *retn++ = 0; } } else *retn++ = 0; }