> I'v been trying to code item stacking with no luck....
> I tried doing it from scratch, and cut/pasteing it from Merc 2.1 code,
> but that didn't work either... best I could get was a segmentation
> fault whenever you look at yout inventory if something was in it....
> (I managed to get no compiler errors so I don't know what the problem
> is)
By object stacking I'm assuming that you mean that if you have 34 loaves
of bread, you want to see something like this in your inventory list:
a loaf of bread. [34]
or, the Merc way:
(34) a loaf of bread.
At any rate, I coded this on Circle 3bpl7 a ways back. Its a little
messy, but it works quite well....
----------------------------------------------------------------------------
/*
* The following struct & function are used by list_obj_to_char. naj 4/95
* Just stick em' in act.informative.c before show_obj_to_char.
* Sorry there aren't any comments. I wrote this in a big rush way back.
* This would be a cool feature to see in a release of Circle. =) =) =)
*/
struct objlist {
int num, cnt, mark;
struct objlist *n;
};
void mark_elem(struct objlist *head, int num) {
struct objlist *obj;
for(obj=head;obj;obj=obj->n)
if (obj->num == num) {
obj->mark = 1;
return;
}
}
int is_marked_elem(struct objlist *head, int num) {
struct objlist *obj;
for(obj=head;obj;obj=obj->n)
if ( (obj->num == num) && (obj->mark) )
return 1;
return 0;
}
int count_elem(struct objlist *head, int num) {
struct objlist *obj;
for(obj=head;obj;obj=obj->n)
if (obj->num == num)
return (obj->cnt);
return 0;
}
void add_elem(struct objlist *head, int num) {
struct objlist *obj;
for(obj=head;obj;obj=obj->n) {
if ((obj->num) == num) {
obj->cnt++;
return;
}
if (!obj->n) {
obj->n = malloc( sizeof(struct objlist) );
obj->n->num = num;
obj->n->cnt = 1;
obj->n->mark = 0;
obj->n->n = NULL;
return;
}
}
}
void destroy_list(struct objlist *head) {
if (head != NULL) {
destroy_list(head -> n);
free(head);
}
}
/*
* This is a modified show_obj_to_char. Note the int cnt in the prototype.
* You will have to modify anything that calls this. Chances are if it isn't
* list_obj_to_char calling it, you can just use 1 as the value.
*/
void show_obj_to_char(struct obj_data * object, struct char_data * ch,
int mode, int cnt)
{
bool found;
char buf2[20];
*buf = '\0';
if ((mode == 0) && object->description)
strcpy(buf, object->description);
else if (object->short_description && ((mode == 1) ||
(mode == 2) || (mode == 3) || (mode == 4)))
strcpy(buf, object->short_description);
else if (mode == 5) {
if (GET_OBJ_TYPE(object) == ITEM_NOTE) {
if (object->action_description) {
strcpy(buf, "There is something written upon it:\r\n\r\n");
strcat(buf, object->action_description);
page_string(ch->desc, buf, 1);
} else
act("It's blank.", FALSE, ch, 0, 0, TO_CHAR);
return;
} else if (GET_OBJ_TYPE(object) != ITEM_DRINKCON) {
strcpy(buf, "You see nothing special..");
} else /* ITEM_TYPE == ITEM_DRINKCON||FOUNTAIN */
strcpy(buf, "It looks like a drink container.");
}
if (mode != 3) {
found = FALSE;
if (IS_OBJ_STAT(object, ITEM_INVISIBLE)) {
strcat(buf, " (invisible)");
found = TRUE;
}
if (IS_OBJ_STAT(object, ITEM_BLESS) && IS_AFFECTED(ch, AFF_DETECT_ALIGN)) {
strcat(buf, " ..It glows blue!");
found = TRUE;
}
if (IS_OBJ_STAT(object, ITEM_MAGIC) && IS_AFFECTED(ch, AFF_DETECT_MAGIC)) {
strcat(buf, " ..It glows yellow!");
found = TRUE;
}
if (IS_OBJ_STAT(object, ITEM_GLOW)) {
strcat(buf, " ..It has a soft glowing aura!");
found = TRUE;
}
if (IS_OBJ_STAT(object, ITEM_HUM)) {
strcat(buf, " ..It emits a faint humming sound!");
found = TRUE;
}
}
if (cnt > 1) {
sprintf(buf2, " [%d]", cnt);
strcat(buf, buf2);
}
strcat(buf, "\r\n");
page_string(ch->desc, buf, 1);
}
/*
* Lots of changes to list_obj_to_char.
*/
void list_obj_to_char(struct obj_data * list, struct char_data * ch, int mode,
bool show)
{
struct obj_data *i;
bool found;
struct objlist *head;
if (!(head = malloc(sizeof(struct objlist))))
log("NAJERR: list_obj_to_char: cannot create list");
head -> n = NULL;
head -> num = -1;
head -> cnt = -1;
head -> mark = 0;
for (i = list; i; i = i->next_content)
if (CAN_SEE_OBJ(ch, i))
add_elem(head, i->item_number);
found = FALSE;
for (i = list; i; i = i->next_content) {
if (CAN_SEE_OBJ(ch, i)) { /* list all corpses individually for now - naj */
if ( ((GET_OBJ_TYPE(i) == ITEM_CONTAINER && GET_OBJ_VAL(i, 3))) && (i->item_number == NOTHING) )
show_obj_to_char(i, ch, mode, count_elem(head, 1));
else if ( !is_marked_elem(head, i->item_number) ) {
show_obj_to_char(i, ch, mode, count_elem(head, i->item_number) );
mark_elem(head, i->item_number);
found = TRUE;
}
}
}
if (!found && show)
send_to_char(" Nothing.\r\n", ch);
destroy_list(head);
}
/*
* And that's it! I _think_ that's all that I modified to make this work.
* Questions, comments, constructive criticisms to oracle@blkbox.com.
* Enjoy! =)
*/
This archive was generated by hypermail 2b30 : 12/18/00 PST