Undertaker Module


Original authors: Cyrus & Robcon (Rage of Carnage 2)
Ported to SmaugWiz by Zanthoris

Installation Instructions
-------------------------

1. In act_flags.h find the following line:

	ACT_R3,

   and change to:

	ACT_UNDERTAKER,		// Retreives corpses

   also in act_flags.h find the following section:

const char*	MobActNames [ACT_MAX] = {
	"npc", "sentinel", "scavenger", "r3", "r4", "aggressive", "stayarea",
	"wimpy", "pet", "train", "practice", "immortal", "deadly", "polyself",
	"meta_aggr", "guardian", "running", "nowander", "mountable", "mounted",
	"scholar", "secretive", "polymorphed", "mobinvis", "noassist",
	"autonomous", "pacifist", "noattack", "annoying", "r29", "prototype"
};

   and change to:

const char*	MobActNames [ACT_MAX] = {
	"npc", "sentinel", "scavenger", "undertaker", "r4", "aggressive", "stayarea",
	"wimpy", "pet", "train", "practice", "immortal", "deadly", "polyself",
	"meta_aggr", "guardian", "running", "nowander", "mountable", "mounted",
	"scholar", "secretive", "polymorphed", "mobinvis", "noassist",
	"autonomous", "pacifist", "noattack", "annoying", "r29", "prototype"
};

2.  In smaug.h add the following line in the proper place:

    /* In unmodified source right after this line: DECLARE_DO_FUN(do_cook);  */

    DECLARE_DO_FUN(do_corpse);

3. In skills.cpp add in the proper place and in alphabetical order:
      
   /* In unmodified source right after this line: 
      if (!str_cmp( name, "do_cook"))              return do_cook;  */

   if (!str_cmp( name, "do_corpse"))              return do_corpse;
    
   Also in skills.cpp add in the proper place and in alphabetical order:

   /* In unmodified source right after this line: 
   if (skill == do_cook)          return "do_cook"; */

   if (skill == do_corpse)          return "do_corpse";

4. Add these 2 functions  to player.cpp:

CCharacter *find_undertaker(CCharacter *ch )
{
  CCharacter *undertaker = NULL;
  
for (undertaker = ch->GetInRoom ()->first_person; undertaker; undertaker=undertaker->GetNextInRoom())
    if(undertaker->IsNpc() && undertaker->IsAction(ACT_UNDERTAKER))
      break;

  return undertaker;
}
void do_corpse(CCharacter *ch, char *argument )
{
    /* Undertaker Module by Cyrus & Robcon on unknown date */
    /* Ported to SmaugWiz by Zanthoris on 11/08/2000 */   
    char buf[MAX_STRING_LENGTH];
    char arg[MAX_INPUT_LENGTH];
    CObjData *obj, *outer_obj;
    CCharacter *mob;
    bool found = FALSE;
    int cost = 0;
	CParseinfo	Inf;

    /* Avoids the potential for filling the room with hundreds of mob corpses */
    if(ch->IsNpc())
    {
	ch->SendText("Mobs cannot retreive corpses.\n\r");
	return;
    }

    /* Search for an act_undertaker */
    if (!(mob = find_undertaker(ch)))
    {
        ch->SendText( "There's no undertaker here!\n\r");
        return;
    }

    argument = one_argument( argument, arg );

    if ( arg[0] == '\0' )
    {
        act(AT_PLAIN,"$N says 'So you are recently deceased, eh?'",ch,NULL,mob,TO_CHAR);
        ch->SendText("I can retrieve your corpse for 50gp/level\n\r");
        ch->SendText("Type corpse retrieve for the service.\n\r");
        return;
    }

    if (!str_cmp(arg,"retrieve"))
        cost  = 50 * ch->GetLevel();
    else
    {
        act(AT_PLAIN,"$N says ' Type 'corpse' for help on what I do.'",
            ch,NULL,mob,TO_CHAR);
        return;
    }

    if (cost > ch->GetGold())
    {
        act(AT_PLAIN,"$N says 'Bah, you cannot afford my services!'",ch,NULL,mob,TO_CHAR);
        return;
    }

    strcpy( buf, "corpse of " );
    strcat( buf, ch->GetName());
    while (obj = Inf.ParseAreaLists (AllAreasList))
    {
        if ( !nifty_is_name( buf, obj->GetName()))
              continue;

	  /* This will prevent NPC corpses from being retreived if the person has a mob's name */
	  if ( obj->item_type == ITEM_CORPSE_NPC )
		continue;

        found = TRUE;
        
        /* Could be carried by act_scavengers, or other idiots so ... */
        outer_obj = obj;
        while ( outer_obj->in_obj )
              outer_obj = outer_obj->in_obj;

        separate_obj( outer_obj );
        obj_from_room( outer_obj );
        obj_to_room( outer_obj, ch->GetInRoom());
		int curr_gold = ch->GetGold();
        ch->SetGold(curr_gold - cost);
        act(AT_PLAIN,"$N empties a bodybag at your feet.",ch,NULL,mob,TO_CHAR);
        act(AT_PLAIN,"$n dumps off $T.",mob,NULL,buf,TO_ROOM);
    }

    /* Could've been extracted, so do this */
    if ( !found )
        act(AT_PLAIN,"$N says 'You don't seem to have a corpse.  There's nothing more I can do.'",ch,NULL,mob,TO_CHAR);

    return;
}

5. Make clean, then recompile.

7. Create a corpse command and set it to level one, or just put the following
in your commands.dat file:

#COMMAND
Name        corpse~
Code        do_corpse
Position    100
Level       1
Log         0
End

                                *****

Now that the coding is done, fire up your mud, and set up your undertaker mob.  
Just add the undertaker flag to the mob(s) that you want to act as an undertaker.

Example:
mset Bubba flags undertaker

As long as there is a mob in the room with the undertaker flag, all you need to
do to get your corpse back is type 'corpse retrieve' and have enough gold to
afford the service.  You can also just type 'corpse' to get some information on the
service and how to use it.  That's all there is to it!

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

This snippet was written for and tested on SmaugWiz version 2.01, I cannot guarantee that
it will work in previous versions without some modification (though I expect it will).  If
you have problems with this snippet let me know!

-=Zanthoris=-

zanthoris@hotmail.com
telnet:\\zanthoris.dhs.org:4000
http:\\zanthoris.home.dhs.org