version 1.122 | | version 1.123 |
---|
| | |
/* | | /* |
* static char *rcsid_object_c = | | * static char *rcsid_object_c = |
* "$Id: object.c,v 1.122 2006/02/09 00:48:36 akirschbaum Exp $"; | | * "$Id: object.c,v 1.123 2006/03/18 15:05:31 ryo_saeba Exp $"; |
*/ | | */ |
| | |
/* | | /* |
| | |
1,2,2,2,2,2,3,4,4,4,4,4,5,6,6,6,6,6,7,8,8,8,8,8}; | | 1,2,2,2,2,2,3,4,4,4,4,4,5,6,6,6,6,6,7,8,8,8,8,8}; |
| | |
| | |
/* Returns TRUE if every key_values in wants has a partner with the same value in has. */ | | /** Returns TRUE if every key_values in wants has a partner with the same value in has. */ |
static int compare_ob_value_lists_one(const object * wants, const object * has) { | | static int compare_ob_value_lists_one(const object * wants, const object * has) { |
key_value * wants_field; | | key_value * wants_field; |
| | |
| | |
return TRUE; | | return TRUE; |
} | | } |
| | |
/* Returns TRUE if ob1 has the same key_values as ob2. */ | | /** Returns TRUE if ob1 has the same key_values as ob2. */ |
static int compare_ob_value_lists(const object * ob1, const object * ob2) { | | static int compare_ob_value_lists(const object * ob1, const object * ob2) { |
/* However, there may be fields in has which aren't partnered in wants, | | /* However, there may be fields in has which aren't partnered in wants, |
* so we need to run the comparison *twice*. :( | | * so we need to run the comparison *twice*. :( |
| | |
return compare_ob_value_lists_one(ob1, ob2) && compare_ob_value_lists_one(ob2, ob1); | | return compare_ob_value_lists_one(ob1, ob2) && compare_ob_value_lists_one(ob2, ob1); |
} | | } |
| | |
/* Function examines the 2 objects given to it, and returns true if | | /** Examines the 2 objects given to it, and returns true if |
* they can be merged together. | | * they can be merged together. |
* | | * |
* Note that this function appears a lot longer than the macro it | | * Note that this function appears a lot longer than the macro it |
* replaces - this is mostly for clarity - a decent compiler should hopefully | | * replaces - this is mostly for clarity - a decent compiler should hopefully |
* reduce this to the same efficiency. | | * reduce this to the same efficiency. |
* | | * |
* Check nrof variable *before* calling CAN_MERGE() | | * Check nrof variable *before* calling can_merge() |
* | | * |
* Improvements made with merge: Better checking on potion, and also | | * Improvements made with merge: Better checking on potion, and also |
* check weight | | * check weight |
*/ | | */ |
| | |
int CAN_MERGE(object *ob1, object *ob2) { | | int can_merge(object *ob1, object *ob2) { |
| | |
/* A couple quicksanity checks */ | | /* A couple quicksanity checks */ |
if ((ob1 == ob2) || (ob1->type != ob2->type)) return 0; | | if ((ob1 == ob2) || (ob1->type != ob2->type)) return 0; |
| | |
if ((ob1->inv && !ob2->inv) || (ob2->inv && !ob1->inv)) return 0; | | if ((ob1->inv && !ob2->inv) || (ob2->inv && !ob1->inv)) return 0; |
| | |
/* Now check to see if the two inventory objects could merge */ | | /* Now check to see if the two inventory objects could merge */ |
if (!CAN_MERGE(ob1->inv, ob2->inv)) return 0; | | if (!can_merge(ob1->inv, ob2->inv)) return 0; |
| | |
/* inventory ok - still need to check rest of this object to see | | /* inventory ok - still need to check rest of this object to see |
* if it is valid. | | * if it is valid. |
| | |
return 1; | | return 1; |
} | | } |
| | |
/* | | /** |
* sum_weight() is a recursive function which calculates the weight | | * sum_weight() is a recursive function which calculates the weight |
* an object is carrying. It goes through in figures out how much | | * an object is carrying. It goes through in figures out how much |
* containers are carrying, and sums it up. | | * containers are carrying, and sums it up. |
| | |
return op; | | return op; |
} | | } |
| | |
/* | | /** |
* Eneq(@csd.uu.se): Since we can have items buried in a character we need | | * Eneq(@csd.uu.se): Since we can have items buried in a character we need |
* a better check. We basically keeping traversing up until we can't | | * a better check. We basically keeping traversing up until we can't |
* or find a player. | | * or find a player. |
| | |
return op; | | return op; |
} | | } |
| | |
/* | | /** |
* Used by: Crossedit: dump. Server DM commands: dumpbelow, dump. | | * Used by: Crossedit: dump. Server DM commands: dumpbelow, dump. |
* Some error messages. | | * Some error messages. |
* The result of the dump is stored in the static global errmsg array. | | * The result of the dump is stored in the static global errmsg array. |
| | |
} | | } |
} | | } |
| | |
/* | | /** |
* Dumps an object. Returns output in the static global errmsg array. | | * Dumps an object. Returns output in the static global errmsg array. |
*/ | | */ |
| | |
| | |
dump_object2(op); | | dump_object2(op); |
} | | } |
| | |
/* GROS - Dumps an object. Return the result into a string */ | | /** GROS - Dumps an object. Return the result into a string */ |
/* Note that no checking is done for the validity of the target string, so */ | | /* Note that no checking is done for the validity of the target string, so */ |
/* you need to be sure that you allocated enough space for it. */ | | /* you need to be sure that you allocated enough space for it. */ |
void dump_me(object *op, char *outstr) | | void dump_me(object *op, char *outstr) |
| | |
} | | } |
} | | } |
| | |
/* | | /** |
* This is really verbose...Can be triggered by the P key while in DM mode. | | * This is really verbose...Can be triggered by the P key while in DM mode. |
* All objects are dumped to stderr (or alternate logfile, if in server-mode) | | * All objects are dumped to stderr (or alternate logfile, if in server-mode) |
*/ | | */ |
| | |
} | | } |
} | | } |
| | |
/* | | /** |
* get_nearest_part(multi-object, object 2) returns the part of the | | * get_nearest_part(multi-object, object 2) returns the part of the |
* multi-object 1 which is closest to the second object. | | * multi-object 1 which is closest to the second object. |
* If it's not a multi-object, it is returned. | | * If it's not a multi-object, it is returned. |
| | |
return closest; | | return closest; |
} | | } |
| | |
/* | | /** |
* Returns the object which has the count-variable equal to the argument. | | * Returns the object which has the count-variable equal to the argument. |
*/ | | */ |
| | |
| | |
return op; | | return op; |
} | | } |
| | |
/* | | /** |
* Returns the first object which has a name equal to the argument. | | * Returns the first object which has a name equal to the argument. |
* Used only by the patch command, but not all that useful. | | * Used only by the patch command, but not all that useful. |
* Enables features like "patch <name-of-other-player> food 999" | | * Enables features like "patch <name-of-other-player> food 999" |
| | |
nrofallocobjects, nroffreeobjects,STARTMAX); | | nrofallocobjects, nroffreeobjects,STARTMAX); |
} | | } |
| | |
/* | | /** |
* Returns the object which this object marks as being the owner. | | * Returns the object which this object marks as being the owner. |
* A id-scheme is used to avoid pointing to objects which have been | | * A id-scheme is used to avoid pointing to objects which have been |
* freed and are now reused. If this is detected, the owner is | | * freed and are now reused. If this is detected, the owner is |
| | |
| | |
| | |
| | |
/* | | /** |
* Sets the owner and sets the skill and exp pointers to owner's current | | * Sets the owner and sets the skill and exp pointers to owner's current |
* skill and experience objects. | | * skill and experience objects. |
*/ | | */ |
| | |
| | |
} | | } |
| | |
/* Set the owner to clone's current owner and set the skill and experience | | /** |
| | * Set the owner to clone's current owner and set the skill and experience |
* objects to clone's objects (typically those objects that where the owner's | | * objects to clone's objects (typically those objects that where the owner's |
* current skill and experience objects at the time when clone's owner was | | * current skill and experience objects at the time when clone's owner was |
* set - not the owner's current skill and experience objects). | | * set - not the owner's current skill and experience objects). |
| | |
| | |
} | | } |
| | |
/* | | /** |
* Resets vital variables in an object | | * Resets vital variables in an object |
*/ | | */ |
| | |
| | |
clear_object(op); | | clear_object(op); |
} | | } |
| | |
/* Zero the key_values on op, decrementing the shared-string | | /** |
| | * Zero the key_values on op, decrementing the shared-string |
* refcounts and freeing the links. | | * refcounts and freeing the links. |
*/ | | */ |
static void free_key_values(object * op) { | | static void free_key_values(object * op) { |
| | |
} | | } |
| | |
| | |
/* | | /** |
* clear_object() frees everything allocated by an object, and also | | * clear_object() frees everything allocated by an object, and also |
* clears all variables and flags to default settings. | | * clears all variables and flags to default settings. |
*/ | | */ |
| | |
| | |
} | | } |
| | |
/* | | /** |
* copy object first frees everything allocated by the second object, | | * copy object first frees everything allocated by the second object, |
* and then copies the contends of the first object into the second | | * and then copies the contends of the first object into the second |
* object, allocating what needs to be allocated. Basically, any | | * object, allocating what needs to be allocated. Basically, any |
| | |
update_ob_speed(op); | | update_ob_speed(op); |
} | | } |
| | |
/* | | /** |
* expand_objects() allocates more objects for the list of unused objects. | | * expand_objects() allocates more objects for the list of unused objects. |
* It is called from get_object() if the unused list is empty. | | * It is called from get_object() if the unused list is empty. |
*/ | | */ |
| | |
nroffreeobjects += OBJ_EXPAND; | | nroffreeobjects += OBJ_EXPAND; |
} | | } |
| | |
/* | | /** |
* get_object() grabs an object from the list of unused objects, makes | | * get_object() grabs an object from the list of unused objects, makes |
* sure it is initialised, and returns it. | | * sure it is initialised, and returns it. |
* If there are no free objects, expand_objects() is called to get more. | | * If there are no free objects, expand_objects() is called to get more. |
| | |
return op; | | return op; |
} | | } |
| | |
/* | | /** |
* If an object with the IS_TURNABLE() flag needs to be turned due | | * If an object with the IS_TURNABLE() flag needs to be turned due |
* to the closest player being on the other side, this function can | | * to the closest player being on the other side, this function can |
* be called to update the face variable, _and_ how it looks on the map. | | * be called to update the face variable, _and_ how it looks on the map. |
| | |
update_object(op,UP_OBJ_FACE); | | update_object(op,UP_OBJ_FACE); |
} | | } |
| | |
/* | | /** |
* Updates the speed of an object. If the speed changes from 0 to another | | * Updates the speed of an object. If the speed changes from 0 to another |
* value, or vice versa, then add/remove the object from the active list. | | * value, or vice versa, then add/remove the object from the active list. |
* This function needs to be called whenever the speed of an object changes. | | * This function needs to be called whenever the speed of an object changes. |
| | |
} | | } |
} | | } |
| | |
/* This function removes object 'op' from the list of active | | /** |
| | * This function removes object 'op' from the list of active |
* objects. | | * objects. |
* This should only be used for style maps or other such | | * This should only be used for style maps or other such |
* reference maps where you don't want an object that isn't | | * reference maps where you don't want an object that isn't |
| | |
op->active_prev = NULL; | | op->active_prev = NULL; |
} | | } |
| | |
/* | | /** |
* update_object() updates the array which represents the map. | | * update_object() updates the array which represents the map. |
* It takes into account invisible objects (and represent squares covered | | * It takes into account invisible objects (and represent squares covered |
* by invisible objects by whatever is below them (unless it's another | | * by invisible objects by whatever is below them (unless it's another |
| | |
} | | } |
| | |
| | |
/* | | /** |
* free_object() frees everything allocated by an object, removes | | * free_object() frees everything allocated by an object, removes |
* it from the list of used objects, and puts it on the list of | | * it from the list of used objects, and puts it on the list of |
* free objects. The IS_FREED() flag is set in the object. | | * free objects. The IS_FREED() flag is set in the object. |
| | |
#endif | | #endif |
} | | } |
| | |
/* | | /** |
* count_free() returns the number of objects on the list of free objects. | | * count_free() returns the number of objects on the list of free objects. |
*/ | | */ |
| | |
| | |
return i; | | return i; |
} | | } |
| | |
/* | | /** |
* count_used() returns the number of objects on the list of used objects. | | * count_used() returns the number of objects on the list of used objects. |
*/ | | */ |
| | |
| | |
return i; | | return i; |
} | | } |
| | |
/* | | /** |
* count_active() returns the number of objects on the list of active objects. | | * count_active() returns the number of objects on the list of active objects. |
*/ | | */ |
| | |
| | |
return i; | | return i; |
} | | } |
| | |
/* | | /** |
* sub_weight() recursively (outwards) subtracts a number from the | | * sub_weight() recursively (outwards) subtracts a number from the |
* weight of an object (and what is carried by it's environment(s)). | | * weight of an object (and what is carried by it's environment(s)). |
*/ | | */ |
| | |
} | | } |
} | | } |
| | |
/* remove_ob(op): | | /** |
* This function removes the object op from the linked list of objects | | * This function removes the object op from the linked list of objects |
* which it is currently tied to. When this function is done, the | | * which it is currently tied to. When this function is done, the |
* object will have no environment. If the object previously had an | | * object will have no environment. If the object previously had an |
| | |
| | |
} | | } |
| | |
/* | | /** |
* merge_ob(op,top): | | |
* | | |
* This function goes through all objects below and including top, and | | * This function goes through all objects below and including top, and |
* merges op to the first matching object. | | * merges op to the first matching object. |
* If top is NULL, it is calculated. | | * If top is NULL, it is calculated. |
| | |
for(;top!=NULL;top=top->below) { | | for(;top!=NULL;top=top->below) { |
if(top==op) | | if(top==op) |
continue; | | continue; |
if (CAN_MERGE(op,top)) | | if (can_merge(op,top)) |
{ | | { |
top->nrof+=op->nrof; | | top->nrof+=op->nrof; |
/* CLEAR_FLAG(top,FLAG_STARTEQUIP);*/ | | /* CLEAR_FLAG(top,FLAG_STARTEQUIP);*/ |
| | |
return NULL; | | return NULL; |
} | | } |
| | |
/* | | /** |
* same as insert_ob_in_map except it handle separate coordinates and do a clean | | * same as insert_ob_in_map except it handle separate coordinates and do a clean |
* job preparing multi-part monsters | | * job preparing multi-part monsters |
*/ | | */ |
| | |
return insert_ob_in_map (op, m, originator, flag); | | return insert_ob_in_map (op, m, originator, flag); |
} | | } |
| | |
/* | | /** |
* insert_ob_in_map (op, map, originator, flag): | | |
* This function inserts the object in the two-way linked list | | * This function inserts the object in the two-way linked list |
* which represents what is on a map. | | * which represents what is on a map. |
* The second argument specifies the map, and the x and y variables | | * The second argument specifies the map, and the x and y variables |
| | |
*/ | | */ |
if(op->nrof && !(flag & INS_NO_MERGE)) { | | if(op->nrof && !(flag & INS_NO_MERGE)) { |
for(tmp=GET_MAP_OB(op->map,x,y);tmp!=NULL;tmp=tmp->above) | | for(tmp=GET_MAP_OB(op->map,x,y);tmp!=NULL;tmp=tmp->above) |
if (CAN_MERGE(op,tmp)) { | | if (can_merge(op,tmp)) { |
op->nrof+=tmp->nrof; | | op->nrof+=tmp->nrof; |
remove_ob(tmp); | | remove_ob(tmp); |
free_object(tmp); | | free_object(tmp); |
| | |
return op; | | return op; |
} | | } |
| | |
/* this function inserts an object in the map, but if it | | /** |
| | * this function inserts an object in the map, but if it |
* finds an object of its own type, it'll remove that one first. | | * finds an object of its own type, it'll remove that one first. |
* op is the object to insert it under: supplies x and the map. | | * op is the object to insert it under: supplies x and the map. |
*/ | | */ |
| | |
insert_ob_in_map(tmp1,op->map,op,0); | | insert_ob_in_map(tmp1,op->map,op,0); |
} | | } |
| | |
/* | | /** |
* get_split_ob(ob,nr) splits up ob into two parts. The part which | | * get_split_ob(ob,nr) splits up ob into two parts. The part which |
* is returned contains nr objects, and the remaining parts contains | | * is returned contains nr objects, and the remaining parts contains |
* the rest (or is removed and freed if that number is 0). | | * the rest (or is removed and freed if that number is 0). |
| | |
return newob; | | return newob; |
} | | } |
| | |
/* | | /** |
* decrease_ob_nr(object, number) decreases a specified number from | | * decrease_ob_nr(object, number) decreases a specified number from |
* the amount of an object. If the amount reaches 0, the object | | * the amount of an object. If the amount reaches 0, the object |
* is subsequently removed and freed. | | * is subsequently removed and freed. |
| | |
} | | } |
} | | } |
| | |
/* | | /** |
* add_weight(object, weight) adds the specified weight to an object, | | * add_weight(object, weight) adds the specified weight to an object, |
* and also updates how much the environment(s) is/are carrying. | | * and also updates how much the environment(s) is/are carrying. |
*/ | | */ |
| | |
} | | } |
} | | } |
| | |
/* | | /** |
* insert_ob_in_ob(op,environment): | | * insert_ob_in_ob(op,environment): |
* This function inserts the object op in the linked list | | * This function inserts the object op in the linked list |
* inside the object environment. | | * inside the object environment. |
| | |
CLEAR_FLAG(op, FLAG_REMOVED); | | CLEAR_FLAG(op, FLAG_REMOVED); |
if(op->nrof) { | | if(op->nrof) { |
for(tmp=where->inv;tmp!=NULL;tmp=tmp->below) | | for(tmp=where->inv;tmp!=NULL;tmp=tmp->below) |
if ( CAN_MERGE(tmp,op) ) { | | if ( can_merge(tmp,op) ) { |
/* return the original object and remove inserted object | | /* return the original object and remove inserted object |
(client needs the original object) */ | | (client needs the original object) */ |
tmp->nrof += op->nrof; | | tmp->nrof += op->nrof; |
| | |
return op; | | return op; |
} | | } |
| | |
/* | | /** |
* Checks if any objects has a move_type that matches objects | | * Checks if any objects has a move_type that matches objects |
* that effect this object on this space. Call apply() to process | | * that effect this object on this space. Call apply() to process |
* these events. | | * these events. |
| | |
return 0; | | return 0; |
} | | } |
| | |
/* | | /** |
* present_arch(arch, map, x, y) searches for any objects with | | * present_arch(arch, map, x, y) searches for any objects with |
* a matching archetype at the given map and coordinates. | | * a matching archetype at the given map and coordinates. |
* The first matching object is returned, or NULL if none. | | * The first matching object is returned, or NULL if none. |
| | |
return NULL; | | return NULL; |
} | | } |
| | |
/* | | /** |
* present(type, map, x, y) searches for any objects with | | * present(type, map, x, y) searches for any objects with |
* a matching type variable at the given map and coordinates. | | * a matching type variable at the given map and coordinates. |
* The first matching object is returned, or NULL if none. | | * The first matching object is returned, or NULL if none. |
| | |
return NULL; | | return NULL; |
} | | } |
| | |
/* | | /** |
* present_in_ob(type, object) searches for any objects with | | * present_in_ob(type, object) searches for any objects with |
* a matching type variable in the inventory of the given object. | | * a matching type variable in the inventory of the given object. |
* The first matching object is returned, or NULL if none. | | * The first matching object is returned, or NULL if none. |
| | |
return NULL; | | return NULL; |
} | | } |
| | |
/* | | /** |
* present_in_ob (type, str, object) searches for any objects with | | * present_in_ob (type, str, object) searches for any objects with |
* a matching type & name variable in the inventory of the given object. | | * a matching type & name variable in the inventory of the given object. |
* The first matching object is returned, or NULL if none. | | * The first matching object is returned, or NULL if none. |
| | |
return NULL; | | return NULL; |
} | | } |
| | |
/* | | /** |
* present_arch_in_ob(archetype, object) searches for any objects with | | * present_arch_in_ob(archetype, object) searches for any objects with |
* a matching archetype in the inventory of the given object. | | * a matching archetype in the inventory of the given object. |
* The first matching object is returned, or NULL if none. | | * The first matching object is returned, or NULL if none. |
| | |
return NULL; | | return NULL; |
} | | } |
| | |
/* | | /** |
* activate recursively a flag on an object inventory | | * activate recursively a flag on an object inventory |
*/ | | */ |
void flag_inv(object*op, int flag){ | | void flag_inv(object*op, int flag){ |
| | |
SET_FLAG(tmp, flag); | | SET_FLAG(tmp, flag); |
flag_inv(tmp,flag); | | flag_inv(tmp,flag); |
} | | } |
}/* | | } |
| | |
| | /** |
* desactivate recursively a flag on an object inventory | | * desactivate recursively a flag on an object inventory |
*/ | | */ |
void unflag_inv(object*op, int flag){ | | void unflag_inv(object*op, int flag){ |
| | |
} | | } |
} | | } |
| | |
/* | | /** |
* set_cheat(object) sets the cheat flag (WAS_WIZ) in the object and in | | * set_cheat(object) sets the cheat flag (WAS_WIZ) in the object and in |
* all it's inventory (recursively). | | * all it's inventory (recursively). |
* If checksums are used, a player will get set_cheat called for | | * If checksums are used, a player will get set_cheat called for |
| | |
flag_inv(op, FLAG_WAS_WIZ); | | flag_inv(op, FLAG_WAS_WIZ); |
} | | } |
| | |
/* | | /** |
* find_free_spot(object, map, x, y, start, stop) will search for | | * find_free_spot(object, map, x, y, start, stop) will search for |
* a spot at the given map and coordinates which will be able to contain | | * a spot at the given map and coordinates which will be able to contain |
* the given object. start and stop specifies how many squares | | * the given object. start and stop specifies how many squares |
| | |
return altern[RANDOM()%index]; | | return altern[RANDOM()%index]; |
} | | } |
| | |
/* | | /** |
* find_first_free_spot(archetype, mapstruct, x, y) works like | | * find_first_free_spot(archetype, mapstruct, x, y) works like |
* find_free_spot(), but it will search max number of squares. | | * find_free_spot(), but it will search max number of squares. |
* But it will return the first available spot, not a random choice. | | * It will return the first available spot, not a random choice. |
* Changed 0.93.2: Have it return -1 if there is no free spot available. | | * Changed 0.93.2: Have it return -1 if there is no free spot available. |
*/ | | */ |
| | |
| | |
return -1; | | return -1; |
} | | } |
| | |
/* | | /** |
* The function permute(arr, begin, end) randomly reorders the array | | * The function permute(arr, begin, end) randomly reorders the array |
* arr[begin..end-1]. | | * arr[begin..end-1]. |
*/ | | */ |
| | |
} | | } |
} | | } |
| | |
/* new function to make monster searching more efficient, and effective! | | /** |
| | * new function to make monster searching more efficient, and effective! |
* This basically returns a randomized array (in the passed pointer) of | | * This basically returns a randomized array (in the passed pointer) of |
* the spaces to find monsters. In this way, it won't always look for | | * the spaces to find monsters. In this way, it won't always look for |
* monsters to the north first. However, the size of the array passed | | * monsters to the north first. However, the size of the array passed |
| | |
permute(search_arr, SIZEOFFREE2+1, SIZEOFFREE); | | permute(search_arr, SIZEOFFREE2+1, SIZEOFFREE); |
} | | } |
| | |
/* | | /** |
* find_dir(map, x, y, exclude) will search some close squares in the | | * find_dir(map, x, y, exclude) will search some close squares in the |
* given map at the given coordinates for live objects. | | * given map at the given coordinates for live objects. |
* It will not considered the object given as exclude among possible | | * It will not considered the object given as exclude among possible |
| | |
return 0; | | return 0; |
} | | } |
| | |
/* | | /** |
* distance(object 1, object 2) will return the square of the | | * distance(object 1, object 2) will return the square of the |
* distance between the two given objects. | | * distance between the two given objects. |
*/ | | */ |
| | |
return i; | | return i; |
} | | } |
| | |
/* | | /** |
* find_dir_2(delta-x,delta-y) will return a direction in which | | * find_dir_2(delta-x,delta-y) will return a direction in which |
* an object which has subtracted the x and y coordinates of another | | * an object which has subtracted the x and y coordinates of another |
* object, needs to travel toward it. | | * object, needs to travel toward it. |
| | |
return 3 ; | | return 3 ; |
} | | } |
| | |
/* | | /** |
* absdir(int): Returns a number between 1 and 8, which represent | | * absdir(int): Returns a number between 1 and 8, which represent |
* the "absolute" direction of a number (it actually takes care of | | * the "absolute" direction of a number (it actually takes care of |
* "overflow" in previous calculations of a direction). | | * "overflow" in previous calculations of a direction). |
| | |
return d; | | return d; |
} | | } |
| | |
/* | | /** |
* dirdiff(dir1, dir2) returns how many 45-degrees differences there is | | * dirdiff(dir1, dir2) returns how many 45-degrees differences there is |
* between two directions (which are expected to be absolute (see absdir()) | | * between two directions (which are expected to be absolute (see absdir()) |
*/ | | */ |
| | |
return d; | | return d; |
} | | } |
| | |
/* peterm: | | /** |
| | * peterm: |
* do LOS stuff for ball lightning. Go after the closest VISIBLE monster. | | * do LOS stuff for ball lightning. Go after the closest VISIBLE monster. |
* Basically, this is a table of directions, and what directions | | * Basically, this is a table of directions, and what directions |
* one could go to go back to us. Eg, entry 15 below is 4, 14, 16. | | * one could go to go back to us. Eg, entry 15 below is 4, 14, 16. |
| | |
{23,24,-1}, /* 47 */ | | {23,24,-1}, /* 47 */ |
{24,9,-1}}; /* 48 */ | | {24,9,-1}}; /* 48 */ |
| | |
/* Recursive routine to step back and see if we can | | /** |
| | * Recursive routine to step back and see if we can |
* find a path to that monster that we found. If not, | | * find a path to that monster that we found. If not, |
* we don't bother going toward it. Returns 1 if we | | * we don't bother going toward it. Returns 1 if we |
* can see a direct way to get it | | * can see a direct way to get it |
| | |
| | |
| | |
| | |
/* | | /** |
* can_pick(picker, item): finds out if an object is possible to be | | * can_pick(picker, item): finds out if an object is possible to be |
* picked up by the picker. Returnes 1 if it can be | | * picked up by the picker. Returnes 1 if it can be |
* picked up, otherwise 0. | | * picked up, otherwise 0. |
| | |
} | | } |
| | |
| | |
/* | | /** |
* create clone from object to another | | * create clone from object to another |
*/ | | */ |
object *object_create_clone (object *asrc) { | | object *object_create_clone (object *asrc) { |
| | |
return dst; | | return dst; |
} | | } |
| | |
/* return true if the object was destroyed, 0 otherwise */ | | /** return true if the object was destroyed, 0 otherwise */ |
int was_destroyed (const object *op, tag_t old_tag) | | int was_destroyed (const object *op, tag_t old_tag) |
{ | | { |
/* checking for FLAG_FREED isn't necessary, but makes this function more | | /* checking for FLAG_FREED isn't necessary, but makes this function more |
| | |
return op->count != old_tag || QUERY_FLAG (op, FLAG_FREED); | | return op->count != old_tag || QUERY_FLAG (op, FLAG_FREED); |
} | | } |
| | |
/* GROS - Creates an object using a string representing its content. */ | | /** |
/* Basically, we save the content of the string to a temp file, then call */ | | * This returns the first object in who's inventory that |
/* load_object on it. I admit it is a highly inefficient way to make things, */ | | |
/* but it was simple to make and allows reusing the load_object function. */ | | |
/* Remember not to use load_object_str in a time-critical situation. */ | | |
/* Also remember that multiparts objects are not supported for now. */ | | |
| | |
object* load_object_str(const char *obstr) | | |
{ | | |
object *op; | | |
FILE *tempfile; | | |
char filename[MAX_BUF]; | | |
sprintf(filename,"%s/cfloadobstr2044",settings.tmpdir); | | |
tempfile=fopen(filename,"w"); | | |
if (tempfile == NULL) | | |
{ | | |
LOG(llevError,"Error - Unable to access load object temp file\n"); | | |
return NULL; | | |
}; | | |
fprintf(tempfile,obstr); | | |
fclose(tempfile); | | |
| | |
op=get_object(); | | |
| | |
tempfile=fopen(filename,"r"); | | |
if (tempfile == NULL) | | |
{ | | |
LOG(llevError,"Error - Unable to read object temp file\n"); | | |
return NULL; | | |
}; | | |
load_object(tempfile,op,LO_NEWFILE,0); | | |
LOG(llevDebug," load str completed, object=%s\n",op->name); | | |
CLEAR_FLAG(op,FLAG_REMOVED); | | |
fclose(tempfile); | | |
return op; | | |
} | | |
| | |
/* This returns the first object in who's inventory that | | |
* has the same type and subtype match. | | * has the same type and subtype match. |
* returns NULL if no match. | | * returns NULL if no match. |
*/ | | */ |
| | |
return NULL; | | return NULL; |
} | | } |
| | |
/* If ob has a field named key, return the link from the list, | | /** |
| | * If ob has a field named key, return the link from the list, |
* otherwise return NULL. | | * otherwise return NULL. |
* | | * |
* key must be a passed in shared string - otherwise, this won't | | * key must be a passed in shared string - otherwise, this won't |
| | |
return NULL; | | return NULL; |
} | | } |
| | |
/* | | /** |
* Returns the value of op has an extra_field for key, or NULL. | | * Returns the value of op has an extra_field for key, or NULL. |
* | | * |
* The argument doesn't need to be a shared string. | | * The argument doesn't need to be a shared string. |
| | |
} | | } |
| | |
| | |
/* | | /** |
* Updates the canonical_key in op to value. | | * Updates the canonical_key in op to value. |
* | | * |
* canonical_key is a shared string (value doesn't have to be). | | * canonical_key is a shared string (value doesn't have to be). |
| | |
return TRUE; | | return TRUE; |
} | | } |
| | |
/* | | /** |
* Updates the key in op to value. | | * Updates the key in op to value. |
* | | * |
* If add_key is FALSE, this will only update existing keys, | | * If add_key is FALSE, this will only update existing keys, |