Esempio n. 1
0
//
// 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]);
   }
Esempio n. 2
0
//
// 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;
}