I've gotten some questions about my comments on the "timers" on objects,
and looking through the code, I found that my reply was somewhat incorrect.
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. I think the instructions below are pretty
easy to follow, but if anyone has any questions, feel free to send them my way.
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(). Delete
update_object() and replace it with 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_EQUIP; 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 it's 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. The example I used of of an AFF_INVISIBLE
object will dramatically change the style of game, because players will almost
always be running around invisible to avoid mobs or PKs. Of course, you could
set a timer on the object and hope it crumbles as they walk in on the
dracolich. ;-)
-Jeff
This archive was generated by hypermail 2b30 : 12/07/00 PST