/* * OBJECT.C: * * Routines that deal with objects and items. * * Copyright (C) 1991, 1992, 1993 Brett J. Vickers * */ #include "mstruct.h" #include "mextern.h" #ifdef DMALLOC #include "/usr/local/include/dmalloc.h" #endif /**********************************************************************/ /* add_obj_obj */ /**********************************************************************/ /* This function adds the object pointed to by the first parameter to */ /* the contents of the object pointed to by the second parameter. It */ /* is done alphabetically. */ void add_obj_obj(obj_ptr1, obj_ptr2) object *obj_ptr1; object *obj_ptr2; { otag *op, *temp, *prev; obj_ptr1->parent_obj = obj_ptr2; obj_ptr1->parent_crt = 0; obj_ptr1->parent_rom = 0; op = (otag *)malloc(sizeof(otag)); if(!op) merror("add_obj_obj", FATAL); op->obj = obj_ptr1; op->next_tag = 0; if(!obj_ptr2->first_obj) { obj_ptr2->first_obj = op; return; } temp = obj_ptr2->first_obj; if(strcmp(temp->obj->name, obj_ptr1->name) > 0 || (!strcmp(temp->obj->name, obj_ptr1->name) && temp->obj->adjustment > obj_ptr1->adjustment)) { op->next_tag = temp; obj_ptr2->first_obj = op; return; } while(temp) { if(strcmp(temp->obj->name, obj_ptr1->name) > 0 || (!strcmp(temp->obj->name, obj_ptr1->name) && temp->obj->adjustment > obj_ptr1->adjustment)) break; prev = temp; temp = temp->next_tag; } op->next_tag = prev->next_tag; prev->next_tag = op; } /**********************************************************************/ /* del_obj_obj */ /**********************************************************************/ /* This function removes the object pointed to by the first parameter */ /* from the object pointed to by the second. */ void del_obj_obj(obj_ptr1, obj_ptr2) object *obj_ptr1; object *obj_ptr2; { otag *temp, *prev; obj_ptr1->parent_crt = 0; if(obj_ptr2->first_obj->obj == obj_ptr1) { temp = obj_ptr2->first_obj->next_tag; free(obj_ptr2->first_obj); obj_ptr2->first_obj = temp; return; } prev = obj_ptr2->first_obj; temp = prev->next_tag; while(temp) { if(temp->obj == obj_ptr1) { prev->next_tag = temp->next_tag; free(temp); return; } prev = temp; temp = temp->next_tag; } } /**********************************************************************/ /* find_obj */ /**********************************************************************/ /* This function is used to search through a room's, creature's or */ /* object's inventory in order to look for a particular item. The */ /* first parameter contains a pointer to the creature who is doing the */ /* search. The second is a pointer to the first object tag in the */ /* list to be searched. The third parameter is a string that contains */ /* the name of the object being searched for. The last parameter */ /* contains the version of the string being searched for. */ object *find_obj(ply_ptr, first_ot, str, val) creature *ply_ptr; otag *first_ot; char *str; int val; { otag *op; int match=0, found=0; if(!first_ot) return(0); op = first_ot; while(op) { if(EQUAL(op->obj, str) && (F_ISSET(ply_ptr, PDINVI) ? 1:!F_ISSET(op->obj, OINVIS))) { match++; if(match == val) { found = 1; break; } } op = op->next_tag; } if(found) return(op->obj); else return(0); } /**********************************************************************/ /* list_obj */ /**********************************************************************/ /* This function produces a string which lists all the objects in a */ /* player's, room's or object's inventory. The first parameter holds */ /* a pointer to the string which will be produced. The second is a */ /* pointer to the player who is having the list produced. The last */ /* is a pointer to the first object tag in the list of items that */ /* it being listed. */ int list_obj(str, ply_ptr, first_otag) char *str; creature *ply_ptr; otag *first_otag; { otag *op; int m, n=0, flags=0; if(F_ISSET(ply_ptr, PDINVI)) flags |= INV; if(F_ISSET(ply_ptr, PDMAGI)) flags |= MAG; str[0] = 0; op = first_otag; while(op && strlen(str) < 2048) { if((F_ISSET(ply_ptr, PDINVI) ? 1:!F_ISSET(op->obj, OINVIS)) && !F_ISSET(op->obj, OHIDDN) && !F_ISSET(op->obj, OSCENE)) { m=1; while(op->next_tag) { if(!strcmp(op->next_tag->obj->name, op->obj->name) && (op->next_tag->obj->adjustment == op->obj->adjustment || !F_ISSET(ply_ptr, PDMAGI)) && (F_ISSET(ply_ptr, PDINVI) ? 1:!F_ISSET(op->next_tag->obj, OINVIS)) && !F_ISSET(op->next_tag->obj, OHIDDN) && !F_ISSET(op->next_tag->obj, OSCENE)) { m++; op = op->next_tag; } else break; } strcat(str, obj_str(op->obj, m, flags)); strcat(str, ", "); n++; } op = op->next_tag; } if(n) { str[strlen(str)-2] = 0; return(1); } else return(0); } /**********************************************************************/ /* weight_obj */ /**********************************************************************/ /* This function computes the total amount of weight of an object and */ /* all its contents. */ int weight_obj(obj_ptr) object *obj_ptr; { int n; otag *op; n = obj_ptr->weight; op = obj_ptr->first_obj; while(op) { if(!F_ISSET(op->obj, OWTLES)) n += weight_obj(op->obj); op = op->next_tag; } return(n); } /************************************************************************/ /* rand_enchant */ /************************************************************************/ /* This function randomly enchants an object if its random-enchant flag */ /* is set. */ void rand_enchant(obj_ptr) object *obj_ptr; { char m; m = mrand(1,100); if(m > 98) { F_SET(obj_ptr, OENCHA); obj_ptr->adjustment = 3; obj_ptr->pdice += 3; } else if(m > 90) { F_SET(obj_ptr, OENCHA); obj_ptr->adjustment = 2; obj_ptr->pdice += 2; } else if(m > 50) { F_SET(obj_ptr, OENCHA); obj_ptr->adjustment = 1; obj_ptr->pdice += 1; } obj_ptr->pdice = MAX(obj_ptr->pdice, obj_ptr->adjustment); }