Beispiel #1
0
//
// D_StartTitle
//
void D_StartTitle (void)
{
    gameaction = ga_nothing;
    demosequence = -1;
// *** PID BEGIN ***
// Print status message.
    fprintf(stderr, "***** start title: *****\n");

// Get rid of possible pid mobjs before starting any demos (this only
// matters here if this routine is called because of EndGame from a
// level where there were pid monsters).
// Left-over pid mobjs were being cleared in the level setup for
// the demo, and that was screwing up the demo timing.
    cleanup_pid_list(NULL);
// *** PID END ***

    D_AdvanceDemo ();
}
Beispiel #2
0
void P_Ticker (void)
{
    int		i;
    
    // run the tic
    if (paused)
	return;
		
    // pause if in menu and at least one tic has been run
    if ( !netgame
	 && menuactive
	 && !demoplayback
	 && players[consoleplayer].viewz != 1)
    {
	return;
    }
    
		
    for (i=0 ; i<MAXPLAYERS ; i++)
	if (playeringame[i])
	    P_PlayerThink (&players[i]);
			
    P_RunThinkers ();
    P_UpdateSpecials ();
    P_RespawnSpecials ();

// *** PID BEGIN ***
    if ( (leveltime != 0) && ( (leveltime & 255) == 0) ){
      // Print status message.
      fprintf(stderr, "***** game ticker: *****\n");

      // Check for new processes / validate old ones.
      // Mark them all for deletion unless they validate next time.
      pr_check();
      cleanup_pid_list(NULL);
    } 
// *** PID END ***

    // for par times
    leveltime++;	
}
Beispiel #3
0
// add_to_pid_list
//   The routine add_to_pid_list() does a lot.  It walks the
// pid mobj linked list to check an actual process versus the
// Doom monster status.  It is sorted in ascending pid order.
//   If this process is not in the list, a monster is spawned
// before linking it into the list.  Unset the delete flag to
// ensure the process is not deleted from the list during cleanup.
//   If this process is already in the list, unset the flag that says
// "delete me from the list during next list cleanup" and update
// the pid monster's name.  If the process is in the list and Doom
// killed it since the last list cleanup, resurrect the monster like
// the archvile does (because the process didn't really die).
// If we can't resurrect it in that case, remove the body and spawn
// a new monster.
void add_to_pid_list(int pid, const char *name, int demon) {

   mobj_t	*new_mobj = NULL;
   int		name_length = 0;
   boolean	position_ok = false;

// If the list isn't empty and the new pid is larger than the largest
// pid currently in the list, spawn the mobj and link it as the tail
// of the list if we placed it on the map without a collision.
   if ( pid_list_tail && pid > pid_list_tail->m_pid ) {
      if ( (new_mobj = add_new_process(pid, name, demon)) != NULL ) {
         new_mobj->ppid = pid_list_tail;
         new_mobj->npid = NULL;
         pid_list_tail->npid = new_mobj;
         pid_list_tail = new_mobj;
         new_mobj->m_del_from_pid_list = false;
      }
// If the list isn't empty and the new pid is smaller than the smallest
// pid currently in the list, spawn the mobj and link it as the head
// of the list if we placed it on the map without a collision.
   } else if ( pid_list_head && pid < pid_list_head->m_pid ) {
      if ( (new_mobj = add_new_process(pid, name, demon)) != NULL ) {
         new_mobj->ppid = NULL;
         new_mobj->npid = pid_list_head;
         pid_list_head->ppid = new_mobj;
         pid_list_head = new_mobj;
         new_mobj->m_del_from_pid_list = false;
      }
// If the read-in pid is not larger or smaller than the extremes of
// the list, walk down the list until the current pointer is at the
// mobj with the pid ahead of the read-in pid.
   } else {
      pid_list_pos = pid_list_head;
      while ( pid_list_pos != NULL && pid > pid_list_pos->m_pid ) {

// NOTE:
// If we were guaranteed that the pid's were coming in ascending order
// from ps, we could do the deletion of unused nodes here and the code
// would be much more efficient.  However, we sort ps output by the
// process start time.  This could lead to smaller pid's coming first
// when the pid counter wraps from the max back to smaller numbers.
         pid_list_pos = pid_list_pos->npid;

      }  // end while

// Now, check why we stopped the walk down the list.
// First, check to see if this is an empty list.  If it isn't empty,
// check whether the mobj's pid is equal or if it's larger than the
// read-in pid.
// If the list is completely empty, spawn the mobj and make it the
// only member of the list.
      if ( pid_list_pos != NULL ) {  // if list isn't empty
         if ( pid == pid_list_pos->m_pid ) {
            // if the read-in pid is same as mobj's pid, set the
            // delete flag to false so the mobj is not unlinked
            // from the list during cleanup.
            pid_list_pos->m_del_from_pid_list = false;

            // copy the incoming pid's name over the mobj's name
            // in case an exec() was called by the process.
            // ie. mingetty --> bash
// TODO: Make name change conditional?  Or is memcpy() fast enough
//       that we can do it every time?
            name_length = strlen( name );
            if ( name_length <= 7 ) {
               memcpy(pid_list_pos->m_pname, name, 8);
            }
            else {
               memcpy(pid_list_pos->m_pname, name + name_length - 7, 8);
            }

            // if the process is still running on the machine, but
            // the mobj has been killed in Doom (ie. the process
            // trapped the kill signal or the user didn't have permission
            // to kill the process), do an archvile-like resurrection
            // on the mobj.  if we can't do the resurrection, remove the
            // body and re-spawn the mobj normally.

            // much of the following code is taken from the routines
            // PIT_VileCheck() and A_VileChase() in p_enemy.c

            if ( !(pid_list_pos->m_draw_pid_info) ) {  // if Doom thinks
                                                       // the process is
                                                       // dead

               // ability to resurrect monster (from PIT_VileCheck).
               pid_list_pos->momx = pid_list_pos->momy = 0;
               pid_list_pos->height <<= 2;
               position_ok = P_CheckPosition(pid_list_pos,
                                             pid_list_pos->x,
                                             pid_list_pos->y);
               pid_list_pos->height >>= 2;

               // if any of these conditions, we CAN'T resurrect
               if ( !(pid_list_pos->flags & MF_CORPSE)  || 
                     (pid_list_pos->tics != -1)  ||
                     (pid_list_pos->info->raisestate == S_NULL) ||
                    !(position_ok)  ) {  // can't raise it: delete and respawn

                  // print status msg
                  fprintf(stderr, "   process %d [%s] monster delete/respawn\n",
                                 pid_list_pos->m_pid,
                                 pid_list_pos->m_pname);

                  // In this case, we need to respawn the monster
                  // since we can't resurrect it.  We delete the mobj
                  // from the pid linked list so it will re-spawn on
                  // the next call to add_to_pid_list().
                  pid_list_pos->m_del_from_pid_list = true;

                  // trick cleanup_pid_list() into thinking it needs
                  // to remove this body
                  pid_list_pos->m_draw_pid_info = true;

                  // remove this mobj from pid list (and remove body)
                  cleanup_pid_list(pid_list_pos);

                  // try to respawn monster
                  add_to_pid_list(pid, name, demon);

               } else {  // we can raise the monster's body

                  // print status msg
                  fprintf(stderr, "   process %d [%s] monster resurrect\n",
                                 pid_list_pos->m_pid,
                                 pid_list_pos->m_pname);

                  // most of this is from A_VileChase()
                  P_SetMobjState(pid_list_pos, pid_list_pos->info->raisestate);
                  pid_list_pos->height <<= 2;
                  pid_list_pos->flags = pid_list_pos->info->flags;
                  pid_list_pos->health = pid_list_pos->info->spawnhealth;
                  pid_list_pos->target = NULL;

                  // draw the pid info again
                  pid_list_pos->m_draw_pid_info = true;

                  // need to unset the flag (again) to not count this
                  // monster in end-of-level kill % -- it was reset when
                  // the mobj flags were copied from the info record above
                  pid_list_pos->flags &= ~MF_COUNTKILL;

               }

            }  // end 'if the monster's dead but not the process.'

         } else {  // the read-in pid is smaller than the currently
                   // pointed to mobj.  spawn a new mobj and link it
                   // into the list if it is placed without a collision.
            if ( (new_mobj = add_new_process(pid, name, demon)) != NULL ) {