Sentinel Procedure [by Mendar]
Snippet Posted Wednesday, August 12th @ 11:36:36 PM, by George Greer in the Specials dept.
Added Jan 16, 1997. Click the link below to read it or download it.

From: Mendar <mudguy@conan.ids.net>
Subject: Sentinel Proc

On Mon, 23 Dec 1996, Daniel Durnin wrote:
> 2> A mob that stops players from going any exits other than the one they
> came from unless the mob gets a certain item from the PC.

Hee hee... this one wasn't so easy as I thought it would be... here is the
spec proc for everyone... I believe it works with 0 problems now... sortof.

Here is a list of quirks about the proc... so be warned...

1. Giving an obj to one mob will result in all mobs of the same vnum
allowing the char to pass in the directions defined... but this proc
is made with the idea that every mob that has this will be the only
one of its own vnum within the world.

2. The timer stuff is put in because if a mob remembers a char giving it
an obj and then dies without the char actually triggering it to let it
go and thus forget about receiving the obj will result in the memory
set aside for remembering it never to be freed. Also, this prevents
players from giving hundreds of objs to mobs with this spec and eating
up gobs of memory :P.

3. You will have to edit this if you don't want the mob to say things
when the player attempts to walk by without giving it the right obj.

4. This proc doesn't recognize giving multiple items in order to let a
player by. You could simulate this by putting several mobs with different
vnums in the room and putting duplicate entries for those mobs... etc..

5. This proc doesn't recognize mobs giving it items. But it does let
mobs go by freely.

6. It is relatively easy to change this so that a player has to give an
obj to one mob, and then run somewhere else before the timer runs out to
be let by another mob. In fact, if both mobs are alike then it will work
if one mob doesn't have the exits defined in its room (the one receving
the item).

7. To make some of the coding easier on my part... I made it so that
the mob junks all the items previously in its inventory every time
it receives a new obj so it doesn't relist the old objs again.

--

#define BTV_NORTH  (1 << 0)
#define BTV_EAST   (1 << 1)
#define BTV_SOUTH  (1 << 2)
#define BTV_WEST   (1 << 3)
#define BTV_UP     (1 << 4)
#define BTV_DOWN   (1 << 5)

#define NUM_OBJ_SENTINELS (1)

struct obj_given_data {
  long whom;
  int where;     /* what room the obj was given in */
  int vnum;      /* vnum of the obj. Do NOT try and use rnums */
  int self_vnum; /* so you can assign this to several mobs,
                    without having attach this to every char  */
  int timer;     /* so players can't tie up memory by giving the mob
                    a zillion items and never walking thru an exit,
                    the timer will keep ticking and eventually forget
                    that a player ever gave the mob anything in the
                    first place */
  struct obj_given_data *next;
};

struct obj_sentinel_recog {
  int vnum;
  int self_vnum;
  int direction;
  char *can_pass; /* What is said if the char can go */
  char *cannot_pass; /* what is said if the char cannot go */
};

struct obj_sentinel_recog osn_list[(NUM_OBJ_SENTINELS-1)] = {

  /* Do yourself a favor and don't leave this entry of info in. I used
     the stock receptionist to test this proc */

  { 10, 3005,
   (BTV_DOWN | BTV_NORTH),
   "You may pass.",
   "Give me a waybread first and you may pass."
   }
};


SPECIAL(obj_sentinel)
{
  ACMD(do_give);
  ACMD(do_say);
  int can_go=FALSE, i, which_sent=NULL, freed=FALSE;
  struct char_data *self;
  struct obj_data *tmp1,*tmp2;
  struct obj_given_data *new_info, *tmp3, *tmp4, *temp;
  char loc_buf[250];

  static struct obj_given_data *obj_give_master;

  self=(struct char_data *) me;

  if(CMD_IS("give"))
    {
      /* first clean out my inv. so the objs given to me are all from
         the same char */
      if(self->carrying)
        {
          for(tmp1=self->carrying; tmp1; tmp1=tmp2)
            {
              tmp2=tmp1->next_content;
              extract_obj(tmp1); /* Obj_from_char is called from within it */
            }
        }
      do_give(ch,argument,cmd,0);

      if(GET_IDNUM(ch)==-1) /* Ignore if mobs give items.. too hard :P */
        return (1);

      if(self->carrying)
        {
          for(tmp1=self->carrying; tmp1; tmp1=tmp1->next_content)
            {
              CREATE(new_info, struct obj_given_data, 1);
              new_info->whom=GET_IDNUM(ch);
              new_info->where=self->in_room;
              new_info->vnum=GET_OBJ_VNUM(tmp1);
              new_info->self_vnum=GET_MOB_VNUM(self);
              new_info->timer=20;
              /*
                My PULSE_MOBILE is 8 sec, yours may be different. To
                figure out how much time this is in RL, multiply the value
                here times PULSE_MOBILE. For me, this would be 160 secs.
                You can also create some nifty effects with this. But that
                is for you to add to this.
                  - mendar
              */
              new_info->next=obj_give_master;
              obj_give_master=new_info;
            }
        }
      return (1);
    }

  if(IS_MOVE(cmd))
    {
      if(IS_NPC(ch))
        {
          return (1); /* let the other mobs go */
        }

      for(tmp3=obj_give_master; tmp3 && (!can_go) ; tmp3=tmp3->next)
        {
          if(((tmp3->whom)==GET_IDNUM(ch))&&
             ((tmp3->self_vnum)==GET_MOB_VNUM(self)))
            {
              for(i=0; (i<NUM_OBJ_SENTINELS) && (!can_go) ; i++)
                {
                  if(osn_list[i].self_vnum==tmp3->self_vnum)
                    {
                      if((tmp3->vnum)==(osn_list[i].vnum))
                        {
                          if(((osn_list[i].direction)&(1 << (cmd-1)) ) > 0 )
                            {
                              can_go=TRUE;
                              which_sent=i;
                            }
                        }
                    }
                }
            }
        }

      if(can_go)
        {
          /* first, we remove one obj from the 'memory' of objs given */
          for(tmp3=obj_give_master; tmp3 && (!freed) ; tmp3=tmp4)
            {
              tmp4=tmp3->next;

              if((tmp3->vnum)==(osn_list[which_sent].vnum))
                {
                  REMOVE_FROM_LIST(tmp3,obj_give_master,next);
                  free(tmp3);
                  freed=TRUE;
                }
            }
          /* now we tell the player they may pass and let them go */
          do_say(self, osn_list[which_sent].can_pass, 0, 0);
          return (0);
        }
      else
        {
          /* now we tell the player they can't go :P */
          do_say(self, osn_list[which_sent].cannot_pass, 0, 0);
          act("$n blocks your way!", FALSE, self, 0, ch, TO_VICT);
          act("$n blocks $N's way!", FALSE, self, 0, ch, TO_NOTVICT);
          return (1);
        }
    }

    if(!FIGHTING(self))
      {
        for(tmp3=obj_give_master; tmp3 ; tmp3=tmp4)
          {
            tmp4=tmp3->next;

            if((tmp3->where)==(self->in_room))
              {
                tmp3->timer--;
                if(tmp3->timer<=0)
                  {
                    REMOVE_FROM_LIST(tmp3,obj_give_master,next);
                    free(tmp3);
                    freed=TRUE;
                  }
              }
          }
      }
  return FALSE;
}


<< send_to_except function [by Raf] | Reply | View as text | Threaded | Show userids on incoming users [by Mudadmin] >>

 


Related Links
  download
Related Articles
More by greerga
 
 

CircleMUD Snippets
 
Note: Not all of these snippets will work perfectly with your version of code, so be prepared to fix one or two bugs that may arise, and please let me know what you needed to do to fix it. Sending a corrected version is always welcome.
Finally, if you wish to use any of the snippets from this page, you are more than welcome, just mention the authors in your credits. If you wish to release any of these snippets to the public on another site, contact me FIRST.
 
 


A much easier way
by Blaize (blaizeofshadow@juno.com) on Wednesday, April 25th @ 12:11:22 PM
http://
If you have dgscripts, this is very easy to do...
just make a mobexit trigger that prevents chars from leaving the room, a entrance trigger that assigns the trigger, and a give trigger that removes it. That easy :P. 4 lines of dgscripts.

Oh well,

^Blaize^
[ Reply to this comment ]