// file: dblist.cc // authors: Chris Dickey, Andrew Hynek // purpose: contains the ObjList functions // Copyright (c) 1996 by Chris Dickey, // some parts Copyright (c) 1998 by Andrew Hynek #include <stdio.h> #include "structs.h" #include "awake.h" #include "comm.h" #include "db.h" #include "utils.h" #include "dblist.h" #include "handler.h" // extern vars extern struct room_data *world; // extern funcs extern void print_object_location(int, struct obj_data *, struct char_data *, int); extern int isname(char *str, char *namelist); int objList::PrintList(struct char_data *ch, const char *arg) { register nodeStruct<struct obj_data *> *temp = head, *next; register int num = 0; bool ground = FALSE; ground = !strcmp( arg, "ground" ); while (temp) { next = temp->next; if (!temp->data->name) { if (temp->data->item_number) { sprintf(buf, "Object #%d has no name.", temp->data->item_number); log(buf); } else { log("Object with no name and no number...deleting from list:"); sprintf(buf, "#:%d, R:%d, T:%d, W:%d, E:%d, Wt:%d, C:%d\n" "M:%d, B:%d, Sd:%s, D:%s, Ld:%s\r\n" "0:%d, 1:%d, 2:%d, 3:%d, 4:%d, 5:%d, 6:%d, 7:%d, 8:%d, 9:%d\r\n", temp->data->item_number, temp->data->in_room, GET_OBJ_TYPE(temp->data), GET_OBJ_WEAR(temp->data), GET_OBJ_EXTRA(temp->data), GET_OBJ_WEIGHT(temp->data), GET_OBJ_COST(temp->data), GET_OBJ_MATERIAL(temp->data), GET_OBJ_BARRIER(temp->data), temp->data->short_description, temp->data->description, temp->data->long_description, GET_OBJ_VAL(temp->data, 0), GET_OBJ_VAL(temp->data, 1), GET_OBJ_VAL(temp->data, 2), GET_OBJ_VAL(temp->data, 3), GET_OBJ_VAL(temp->data, 4), GET_OBJ_VAL(temp->data, 5), GET_OBJ_VAL(temp->data, 6), GET_OBJ_VAL(temp->data, 7), GET_OBJ_VAL(temp->data, 8), GET_OBJ_VAL(temp->data, 9)); log(buf); if (temp->data->worn_by) act("$p suddenly disappears.", FALSE, temp->data->worn_by, temp->data, 0, TO_CHAR); else if (temp->data->carried_by) act("$p suddenly disappears.", FALSE, temp->data->carried_by, temp->data, 0, TO_CHAR); else if (temp->data->in_room > 0) { sprintf(buf, "%s suddenly disappears.\r\n", temp->data->short_description); send_to_room(buf, temp->data->in_room); } extract_obj(temp->data); } } else if (CAN_SEE_OBJ(ch, temp->data) && (isname((char *)arg, temp->data->name) || (ground && temp->data->carried_by == NULL && temp->data->in_obj == NULL && temp->data->worn_by == NULL && temp->data->in_room > 0 && (temp->data->in_room < 320||temp->data->in_room>=421)))) print_object_location(++num, temp->data, ch, TRUE); temp = next; } return num; } void objList::Traverse(void (*func)(struct obj_data *)) { for (nodeStruct<struct obj_data *> *temp = head; temp; temp = temp->next) func(temp->data); } // this function searches through the list and returns a pointer to the // object whose object rnum matches num struct obj_data *objList::FindObj(int num) { register nodeStruct<struct obj_data *> *temp; for (temp = head; temp; temp = temp->next) if (num == GET_OBJ_RNUM(temp->data)) return temp->data; return NULL; } // this function searches through the list and returns a pointer to the // object whose name matches 'name' and who is the 'num'th object in the // list struct obj_data *objList::FindObj(struct char_data *ch, char *name, int num) { register struct nodeStruct<struct obj_data *> *temp = head; register int i = 0; while (temp && (i <= num)) { if (isname(name, temp->data->name) && CAN_SEE_OBJ(ch, temp->data) && (++i == num)) return temp->data; temp = temp->next; } return NULL; } // this function updates pointers to this particular prototype--necessary // for OLC so objects on the mud get updated with the correct values void objList::UpdateObjs(const struct obj_data *proto, int rnum) { static struct nodeStruct<struct obj_data *> *temp; static struct obj_data old; for (temp = head; temp; temp = temp->next) { if (temp->data->item_number == rnum) { old = *temp->data; *temp->data = *proto; temp->data->in_room = old.in_room; temp->data->item_number = rnum; temp->data->carried_by = old.carried_by; temp->data->worn_by = old.worn_by; temp->data->worn_on = old.worn_on; temp->data->in_obj = old.in_obj; temp->data->contains = old.contains; temp->data->next_content = old.next_content; temp->data->obj_flags.condition = old.obj_flags.condition; if (temp->data->carried_by) affect_total(temp->data->carried_by); else if (temp->data->worn_by) affect_total(temp->data->worn_by); } } } // this function runs through the list and checks the timers of each // object, extracting them if their timers hit 0 void objList::UpdateCounters(void) { static nodeStruct<struct obj_data *> *temp, *next; for (temp = head; temp; temp = next) { next = temp->next; /* anti-twink measure...no decay until there's no eq in it */ if ( IS_OBJ_STAT(temp->data, ITEM_CORPSE) && GET_OBJ_VAL(temp->data, 4) == 1 && temp->data->contains != NULL ) continue; // only corpses and immloaded items usually have timers if (IS_OBJ_STAT(temp->data, ITEM_CORPSE) || IS_OBJ_STAT(temp->data, ITEM_IMMLOAD)) { if (GET_OBJ_TIMER(temp->data) > 1) { GET_OBJ_TIMER(temp->data)--; } else { if (temp->data->carried_by) act("$p decays in your hands.", FALSE, temp->data->carried_by, temp->data, 0, TO_CHAR); else if (temp->data->worn_by) act("$p decays in your hands.", FALSE, temp->data->worn_by, temp->data, 0, TO_CHAR); else if ((temp->data->in_room != NOWHERE) && (world[temp->data->in_room].people)) { act("$p crumbles into dust.", TRUE, world[temp->data->in_room].people, temp->data, 0, TO_ROOM); act("$p crumbles into dust.", TRUE, world[temp->data->in_room].people, temp->data, 0, TO_CHAR); } // here we make sure to remove all items from the object struct obj_data *next_thing, *temp2; for (temp2 = temp->data->contains; temp2; temp2 = next_thing) { next_thing = temp2->next_content; /*Next in inventory */ if (!(IS_OBJ_STAT(temp->data, ITEM_CORPSE) && !GET_OBJ_VAL(temp->data, 4) && GET_OBJ_TYPE(temp2) != ITEM_MONEY)) { obj_from_obj(temp2); if (temp->data->in_obj) obj_to_obj(temp2, temp->data->in_obj); else if (temp->data->carried_by) obj_to_room(temp2, temp->data->carried_by->in_room); else if (temp->data->worn_by) obj_to_room(temp2, temp->data->worn_by->in_room); else if (temp->data->in_room != NOWHERE) obj_to_room(temp2, temp->data->in_room); else assert(FALSE); } else extract_obj(temp2); } next = temp->next; // just to make sure... extract_obj(temp->data); } } } } // this function updates the objects in the list whose real numbers are // greater than num--necessary for olc--but maybe obsolete once the new // structures come into effect void objList::UpdateNums(int num) { register nodeStruct<struct obj_data *> *temp; // just loop through the list and update for (temp = head; temp; temp = temp->next) if (GET_OBJ_RNUM(temp->data) >= num) GET_OBJ_RNUM(temp->data)++; } /* this function goes through each object, and if it has a spec, calls it */ void objList::CallSpec() { nodeStruct<struct obj_data *> *temp; for (temp = head; temp; temp = temp->next) if (GET_OBJ_SPEC(temp->data) != NULL) GET_OBJ_SPEC(temp->data) (NULL, temp->data, 0, ""); } void objList::RemoveObjs() { nodeStruct<struct obj_data *> *temp = head, *last; while (temp) { last = temp->next; if (from_ip_zone(GET_OBJ_VNUM(temp->data)) || IS_OBJ_STAT(temp->data, ITEM_VOLATILE)) { if (temp->data->carried_by && !IS_NPC(temp->data->carried_by) && GET_LEVEL(temp->data->carried_by) < LVL_LEGEND) { act("$p decays into nothing.", FALSE, temp->data->carried_by, temp->data, 0, TO_CHAR); extract_obj(temp->data); } else if (temp->data->worn_by && !IS_NPC(temp->data->worn_by) && GET_LEVEL(temp->data->worn_by) < LVL_LEGEND) { act("$p decays into nothing.", FALSE, temp->data->carried_by, temp->data, 0, TO_CHAR); extract_obj(temp->data); } } temp = last; } } void objList::RemoveObjNum(int num) { nodeStruct<struct obj_data *> *temp, *next; for (temp = head; temp; temp = next) { next = temp->next; if (GET_OBJ_RNUM(temp->data) == num) { if (temp->data->carried_by) act("$p disintegrates.", FALSE, temp->data->carried_by, temp->data, 0, TO_CHAR); else if (temp->data->worn_by) act("$p disintegrates.", FALSE, temp->data->carried_by, temp->data, 0, TO_CHAR); else if (temp->data->in_room != NOWHERE && world[temp->data->in_room].people) { act("$p disintegrates.", TRUE, world[temp->data->in_room].people, temp->data, 0, TO_ROOM); act("$p disintegrates.", TRUE, world[temp->data->in_room].people, temp->data, 0, TO_CHAR); } extract_obj(temp->data); } } } void objList::RemoveQuestObjs(int id) { nodeStruct<struct obj_data *> *temp, *next; for (temp = head; temp; temp = next) { next = temp->next; if (temp->data->obj_flags.quest_id == id) extract_obj(temp->data); } }