pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
/****************************************************************************
 ** Dead Corpses system. pDirt
 ** 
 ** Project	: pDirt (Aber IV Daemon)
 ** Module	: corpse.c
 ** Author	: Marty (Peter Eussen)
 ** Date	: 26-29 August 1997
 ** Description	: This module handles the creation of corpses after a mobile
 **		  has died, plus the decaying of the corpses.
 ** Copyright   : This piece of code is part of the pDirt distribution.
 ** Version	: 0.1
 ****************************************************************************/
#define CORPSE_C
#include <stdlib.h>
#include "kernel.h"
#include "tables.h"
#include "cflags.h"
#include "sendsys.h"
#include "clone.h"
#include "mobile.h"
#include "objsys.h"

/** This indicates how long a corpse should remain in the room before fading
 ** away into nothing. Time is in seconds.
 **/
#define DECAYTIME	(60 * 5)

/** The definition of a linked list to store all the corpses. New additions
 ** are added at the back.
 ** I have to use the obj_id() of an object since the cloned object shift
 ** within the object array and therefore an index to the object array isnt
 ** going to work.
 **/
typedef struct _corpselist {
   int	   mob;			/* Which mob did it belong to? */
   long    obj_id;		/* Whats the Object ID of the corpse */
   time_t  decay_at;		/* Decay at what time? */
   struct  _corpselist *next;	/* Who's next? */
} CORPSELIST;

static CORPSELIST *decaylist = NULL;	/* Begin of the list */
static CORPSELIST *lastinlist = NULL;	/* End of the list */

void decay_corpses(void)
{  CORPSELIST *p = decaylist, *q;
   int obj;

   /* Since new ones are added at the back we can traverse the list from front
    * to the back and stop whenever the list is empty or the decay time of the
    * current corpse hasn't been reached yet.
    */
   while (p != NULL && p->decay_at < global_clock)
   {    q = p->next;
        obj = lookup_entry(p->obj_id,&id_table);

        if (obj != NOT_IN_TABLE)	/* Corpse has been removed by someone */
	{
           /* messages */
           sendf(oloc(obj),"You watch as the corpse of %s dissolves into nothing.\n",
		pname(p->mob));
	   destruct_object(obj,NULL);
        }

	/* Update list and free memory */
        if (p == decaylist)
           decaylist = q;
        if (p == lastinlist)
           lastinlist = q;
        free(p);
        p = q;
   }
}

/* Create a corpse for mobile 'mob', who was killed by 'by'. We need the 'by' 
 * to build the message that is shown to everyone in the mud when they pass
 * along it.
 */ 
void add_corpse_for(int mob,int by)
{   CORPSELIST *p;
    int obj,cobj;
    char line[90];

    p = NEW(CORPSELIST,1);
    
    if (p != NULL)
    {
    	p->mob = mob; 
    	cobj = clone_object(base_corpse,-1,NULL);
    	p->obj_id = obj_id(cobj);
    	p->next = NULL;
    	p->decay_at = global_clock + DECAYTIME;

    	if (cobj > 0)
    	{   /* Add corpse to the list */
    	    if (decaylist == NULL)
    	    {   decaylist = p;
    	        lastinlist = p;
    	    }
    	    else
    	    {   lastinlist->next = p;
    	        lastinlist = p;
    	    }
       
    	    /* Put all the inventory in the corpse, except for the weapon */
            /*
    	    for (obj = pfirst_obj(mob); obj != SET_END; obj = pnext_obj(mob))
    	    {   if (obj == pwpn(mob))
    	        {  setoloc(obj,ploc(mob),IN_ROOM);
    	           setpwpn(mob,-1);
    	        }
    	        else
    	           setoloc(obj,cobj, IN_CONTAINER);
    	        
    	    }
	    */
            dumpstuff(mob,ploc(mob));

    	    for (obj = 0; obj < 4; obj++)
    	       if (olongt(cobj,obj) != NULL)
    	       {   free(olongt(cobj,obj));
    	           olongt(cobj,obj) = NULL;
    	       }
	
    	    sprintf(line,"The dead rotting corpse of %s lies here.. slain by %s.",
			pname(mob),pname(by));
    	    olongt(cobj,0) = COPY(line); 
    	    setoloc(cobj,ploc(mob),IN_ROOM); 
    	    destroy_mobile(mob);
            return;
    	}
    }

    /* We get to here if either the malloc of a list entry failed or we weren't
     * able to clone any new corpses.. in which case we better do something so
     * we fall back to the old way... which is dropping the stuff and removing
     * the mobile.
     */
    dumpstuff(mob,ploc(mob));
    destroy_mobile(mob);
    free(p);
}