( ?: Object Timers  )
Snippet Contributed by greerga on Wednesday August 12, @11:19PM, from the Objects dept.
. Click the link below to read it or download it.
                                 OBJECT TIMERS

Standard Diku does not support items crumbling as I had said, but it
does in fact support AFF_ bits set on items. At any rate, I''ve pulled
out my code that does support timers on items, and included
instructions for installing it. I can''t be positive that the lines
that I tell you to look for are correct, since my copies of Circle
have been mangled pretty bad, and I don''t have the patience to get a
new copy at 1200 baud. The new code below was pulled from my copy of
Circle 2.01, and should work fine with 2.2, and probably 3.0.

Step 1: Go into db.c and look for the following lines in
load_objects():

         for (; (j < MAX_OBJ_AFFECT); j++) {
            obj_proto[i].affected[j].location = APPLY_NONE;
            obj_proto[i].affected[j].modifier = 0;
         }

After these, add:

         if (*chk == ''F'') {
            fscanf(obj_f, " %d %d \n", &tmp, &tmp2);
            obj_proto[i].obj_flags.bitvector = tmp;
            obj_proto[i].obj_flags.timer = tmp2;
            fscanf(obj_f, " %s \n", chk);
         }

At this point, you can add flag lines to your object files by going to
the very end of the object (after the Affected values if you have
them) and adding a single line of the form:

   F <bitvector> <timer>

The bitvector corresponds to the AFF_ values in structs.h, and
whenever this item is worn, these AFF_ bits will be set. At this
point, the timer does not work yet. To get it to work:

Step 2: Go into handler.c and look for void update_object(). Change it
to look somewhat like the following code:

void crumble_obj(struct char_data *ch, struct obj_data *obj)
{
   struct obj_data *loop;
   int index;

   if (obj->in_room != NOWHERE) {               /* In a room */
      if (world[obj->in_room].people) {
         act("A quivering horde of maggots consumes $p.",
           TRUE, world[obj->in_room].people, obj, 0, TO_ROOM);
         act("A quivering horde of maggots consumes $p.",
           TRUE, world[obj->in_room].people, obj, 0, TO_CHAR);
         for(loop = obj->contains; loop; loop = obj->contains) {
            obj_from_obj(loop);
            obj_to_room(loop, obj->in_room);
         }
      }
   } else if (!obj->in_obj) {                   /* Worn or inventory */
      act("$p decays in your hands.", FALSE, ch, obj, 0, TO_CHAR);
      for(loop = obj->contains; loop; loop = obj->contains) {
         obj_from_obj(loop);
         obj_to_char(loop, ch);
      }
      if (!obj->carried_by)
         for(index = 0; index < MAX_WEAR; index++)
            if (ch->equipment[index] == obj)
               obj = unequip_char(ch, index);
   } else                                       /* In an object */
      for(loop = obj->contains; loop; loop = obj->contains) {
         obj_from_obj(loop);
         obj_to_obj(loop, obj->in_obj);
      }
   extract_obj(obj);
}

void update_object(struct char_data *ch, struct obj_data *obj, int use)
{

   if (obj->next_content)
      update_object(ch, obj->next_content, use);
   if (obj->contains)
      update_object(ch, obj->contains, use);
   if (obj->obj_flags.timer > 0)
      if ((obj->obj_flags.timer -= use) < 1)
         crumble_obj(ch, obj);
}

Step 3: Go down to update_char_objects() (in the same file) and modify
the calls to update_object() so that they look like

   update_object(ch, ch->equipment[i], 2)

and

   update_object(ch, ch->carrying, 1)

Step 4: Go into limits.c and look for void point_update(). There''s a
set of code that looks like:

      if (!IS_NPC(i)) {
         update_char_objects(i);
         if (GET_LEVEL(i) < LEVEL_GOD)
            check_idling(i);
      }

Change the ifs to match the ones below:

      if (!IS_NPC(i) || IS_AFFECTED(i, AFF_CHARM)) {
         update_char_objects(i);
         if (!IS_NPC(i) && (GET_LEVEL(i) < LEVEL_GOD))
            check_idling(i);
      }

Step 5: Further down in point update there''s a loop that starts with
for(j = object_list; j; j = next_thing) {. Delete everything between
this for() statement and its closing bracket, and insert this as the
loop contents:

      next_thing = j->next; /* Next in object list */

      if (j->in_room == NOWHERE)
         continue;

      if ((GET_ITEM_TYPE(j) != ITEM_CONTAINER) || (!j->obj_flags.value[3]))
         continue;

      if (j->obj_flags.timer > 0)
         if (!(--j->obj_flags.timer))
            crumble_obj(0, j);

And there you go. If the timer is set > 0 in the object file, the
objects will deteriorate by 1 if in a PC''s inventory (or in a PCs
bag), and by 2 if equipped. Since I have experience with running a MUD
with this code, I think I ought to give a warning: Objects with any of
the AFF_ bits can be extremely powerful and should be quite rare. Of
course, you could set a timer on the object and hope it crumbles as
they walk in on the dracolich...



<< Andrey Fidrya: Zone Command: Force | Reply | Flattened >>

 

Related Links
download
Related Articles
More by greerga
Features
This is the new CircleMUD News site. It is based off the Slashdot 0.2 Perl code and will resemble Slashdot.org site for awhile.
Quick Links
The CircleMUD home page Alex's Snippets