/*******************************************/ /* Author: James Horn jimh@DoItNow.com */ /* Date: 11/01/98 */ /* Revised: 01/26/99 */ /* By : Xual */ /* Version: stock circle30bpl14 */ /* Purpose: Auto equipping players */ /* Source: auto_equip.txt */ /* Credit: Not Required */ /*******************************************/ First I would like to say thanks to all the coders and administrators who have contributed CircleMud. I have implemented much of your work into my Mud and I have learned much about programming in c thanks to each of you. In return I am contributing some of my code. I hope it is of use to some- one out there. So far I have not encountered any problems with it. I am compiling using gcc in a Cygnus Cygwin32 Beta 19 UNIX environment on a MSWindows95 machine. Special Thanks to Jeremy Elson, George Greer & Alex Fletcher. Some characters I have played, Gluk, Merth - (Sojourn, before split into Toril/Duris) Graum - (Duris while it lasted) IMPORTANT: Due to changes in the obj_data structure, the player object files will need to be deleted or modified on your mud before implemention of this code. As always, remember to make a backup of your files before making any modifications. You are liable for any changes you make to your mud, not me. In structs.h: ------------------------------------------------------------------------- ======== STEP #1 ======== IN: struct obj_data { AFTER: struct obj_data *next; /* For the object list */ INSERT: sh_int containerNum; /* for auto_equip */ sh_int where_it_goes; /* for auto_equip */ ======== STEP #2 ======== IN: struct obj_file_elem { AFTER: struct obj_affected_type affected[MAX_OBJ_AFFECT]; INSERT: sh_int eq_Bitvector; sh_int where_it_goes; sh_int containerNum; In handler.h: ------------------------------------------------------------------------- ======== STEP #1 ======== AFTER: struct obj_data *unequip_char(struct char_data *ch, int pos); INSERT: struct obj_data *unequip_char_for_rent(struct char_data *ch, int pos); In handler.c: ------------------------------------------------------------------------- ======== STEP #1 ======== struct obj_data *unequip_char_for_rent(struct char_data * ch, int pos) { int j; struct obj_data *obj; if ((pos < 0 || pos >= NUM_WEARS) || GET_EQ(ch, pos) == NULL) { core_dump(); return NULL; } obj = GET_EQ(ch, pos); /** Updated Jan 26/99 -- Xual **/ if (IS_OBJ_STAT(obj, ITEM_NORENT) || GET_OBJ_RENT(obj) < 0)) obj->worn_by = NULL; if (GET_OBJ_TYPE(obj) == ITEM_ARMOR) GET_AC(ch) += apply_ac(ch, pos); if (ch->in_room != NOWHERE) { if (pos == WEAR_LIGHT && GET_OBJ_TYPE(obj) == ITEM_LIGHT) if (GET_OBJ_VAL(obj, 2)) /* if light is ON */ world[ch->in_room].light--; } else log("SYSERR: ch->in_room = NOWHERE when unequipping char %s.", GET_NAME(ch)); GET_EQ(ch, pos) = NULL; for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, obj->affected[j].location, obj->affected[j].modifier, obj->obj_flags.bitvector, FALSE); affect_total(ch); return (obj); } In objsave.c: ------------------------------------------------------------------------- ======== STEP #1 ======== #define IS_WORN 1<<1 #define IN_CONTAINER 1<<2 ======== STEP #2 ======== UNDER: /* local functions */ SEARCH FOR: int Crash_save(struct obj_data * obj, FILE * fp); REPLACE WITH: int Crash_save(struct obj_data * obj, FILE * fp, sh_int containerNum); ======== STEP #3 ======== IN FUNCTION: Obj_from_store AFTER: GET_OBJ_TIMER(obj) = object.timer; INSERT: /***********************************************************************/ /* The next 3 object.variables are stored in the object's structure */ /* because the data will be used later for putting objects into the */ /* containers they belong in and wearing items where they are supposed */ /* to be worn. */ /***********************************************************************/ obj->obj_flags.bitvector = object.bitvector; obj->containerNum = object.containerNum; obj->where_it_goes = object.where_it_goes; ======== STEP #4 ======== IN FUNCTION: Obj_to_store AFTER: object.timer = GET_OBJ_TIMER(obj); ADD: object.bitvector = obj->obj_flags.bitvector; /**************************************/ /* Objects go in inventory by default */ /**************************************/ object.eq_Bitvector = 0; object.where_it_goes = -1; /**************************************/ /* Get Object's worn location */ /**************************************/ if (obj->worn_by) { SET_BIT(object.eq_Bitvector, IS_WORN); object.where_it_goes = obj->worn_on; } /**************************************/ /* Get Container's number */ /**************************************/ if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) { object.containerNum = obj->containerNum; } /**************************************/ /* Get Containee's Container number */ /**************************************/ if (obj->in_obj) { SET_BIT(object.eq_Bitvector, IN_CONTAINER); object.where_it_goes = obj->in_obj->containerNum; } obj->worn_by = NULL; obj->worn_on = -1; ======== STEP #5 ======== IN FUNCTION: Crash_load AFTER: int cost, orig_rent_code, num_objs = 0; INSERT: struct obj_data *obj, *hold_obj[max_obj_save]; sh_int hold_obj_bitvector[max_obj_save]; int obj_ctr = 0, hold_ctr, num_container; SEARCH FOR: if (!feof(fl)) { ++num_objs; obj_to_char(Obj_from_store(object), ch); } REPLACE WITH: if (!feof(fl)) { /*******************************/ /* LOAD OBJECTS INTO INVENTORY */ /*******************************/ obj_to_char(Obj_from_store(object), ch); /*****************************************************************/ /* LOAD OBJECTS INTO ARRAY */ /*===============================================================*/ /* Purpose: */ /* I am storing all of the players objects into an array because */ /* all objects that belong in a container will be loaded before */ /* the container is loaded. */ /*****************************************************************/ hold_obj[num_objs] = ch->carrying; hold_obj_bitvector[num_objs] = object.eq_Bitvector; /**************************************************************/ /* Count the number of objects retrieved from the object file */ /**************************************************************/ num_objs++; } } /*****************************************************************/ /* FIND CONTAINERS IN THE ARRAY */ /*===============================================================*/ /* Purpose: */ /* At this point everything from the player object file has been */ /* stored into an array. Now we go through the array and check */ /* for containers. */ /*****************************************************************/ for (obj_ctr = 0; obj_ctr < num_objs; obj_ctr++) { if (GET_OBJ_TYPE(hold_obj[obj_ctr]) == ITEM_CONTAINER) { /**************************************************************/ /* A container has been found, assign the array element to */ /* num_container. */ /**************************************************************/ num_container = obj_ctr; /***************************************************************/ /* Now take another pass through the array looking for objects */ /* that are flagged as IN_CONTAINER and have a ->where_it_goes */ /* that matches the ->containerNum of the above container. */ /* Notice that we only need to check array element 0 through */ /* num_container rather than 0 through num_objs because all of */ /* a container's object are loaded before the container. So it */ /* is not neccesary to loop through every item in the array. */ /***************************************************************/ for (hold_ctr = 0; hold_ctr < num_container; hold_ctr++) { if (IS_SET(hold_obj_bitvector[hold_ctr], IN_CONTAINER) && hold_obj[hold_ctr]->where_it_goes == hold_obj[obj_ctr]->containerNum) { obj = hold_obj[hold_ctr]; obj_from_char(obj); obj_to_obj(hold_obj[hold_ctr], hold_obj[obj_ctr]); } } } } /*******************************************************************/ /* Equip worn objects in the array: */ /*=================================================================*/ /* We're going through the array again looking for objects */ /* flagged IS_WORN and wearing them on the body part indicated */ /* by obj->where_it_goes. I did not do this above because I wanted */ /* to fill up wearable containers before wearing them. */ /*******************************************************************/ for (obj_ctr = 0; obj_ctr < num_objs; obj_ctr++) { if (IS_SET(hold_obj_bitvector[obj_ctr], IS_WORN)) { obj = hold_obj[obj_ctr]; obj_from_char(obj); equip_char(ch, obj, obj->where_it_goes); } } ======== STEP #6 ======== IN FUNCTION: Crash_save SEARCH FOR: int Crash_save(struct obj_data * obj, FILE * fp) REPLACE WITH: int Crash_save(struct obj_data * obj, FILE * fp, sh_int containerNum) AFTER: if (obj) { INSERT: obj->containerNum = -1; obj->where_it_goes = -1; if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER && obj->contains) { containerNum++; obj->containerNum = containerNum; } ======== STEP #7 ======== IN FUNCTION: Crash_crashsave SEARCH FOR: if (!Crash_save(ch->carrying, fp)) { REPLACE WITH: if (!Crash_save(ch->carrying, fp, 0)) { SEARCH FOR: if (!Crash_save(GET_EQ(ch, j), fp)) { REPLACE WITH: if (!Crash_save(GET_EQ(ch, j), fp, 0)) { ======== STEP #8 ======== IN FUNCTION: Crash_idlesave SEARCH FOR: obj_to_char(equip_char(ch, j), ch); REPLACE WITH: obj_to_char(unequip_char_for_rent(ch, j), ch); SEARCH FOR: if (!Crash_save(ch->carrying, fp)) { REPLACE WITH: if (!Crash_save(ch->carrying, fp, 0)) { ======== STEP #9 ======== IN FUNCTION: Crash_rentsave SEARCH FOR: obj_to_char(equip_char(ch, j), ch); REPLACE WITH: obj_to_char(unequip_char_for_rent(ch, j), ch); SEARCH FOR: if (!Crash_save(ch->carrying, fp)) { REPLACE WITH: if (!Crash_save(ch->carrying, fp, 0)) { ======== STEP #10 ======== IN FUNCTION: Crash_cryosave REPLACE: obj_to_char(equip_char(ch, j), ch); WITH: obj_to_char(unequip_char_for_rent(ch, j), ch); SEARCH FOR: if (!Crash_save(ch->carrying, fp)) { REPLACE WITH: if (!Crash_save(ch->carrying, fp, 0)) {