ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.c
(Generate patch)

Comparing deliantra/server/common/object.c (file contents):
Revision 1.1.1.1 by root, Fri Feb 3 07:11:38 2006 UTC vs.
Revision 1.1.1.2 by elmex, Wed Feb 22 18:01:22 2006 UTC

1/* 1/*
2 * static char *rcsid_object_c = 2 * static char *rcsid_object_c =
3 * "$Id: object.c,v 1.1.1.1 2006/02/03 07:11:38 root Exp $"; 3 * "$Id: object.c,v 1.1.1.2 2006/02/22 18:01:22 elmex Exp $";
4 */ 4 */
5 5
6/* 6/*
7 CrossFire, A Multiplayer game for X-windows 7 CrossFire, A Multiplayer game for X-windows
8 8
68 0,1,2,3,4,5,6,7,8,1,2,2,2,3,4,4,4,5,6,6,6,7,8,8,8, 68 0,1,2,3,4,5,6,7,8,1,2,2,2,3,4,4,4,5,6,6,6,7,8,8,8,
69 1,2,2,2,2,2,3,4,4,4,4,4,5,6,6,6,6,6,7,8,8,8,8,8}; 69 1,2,2,2,2,2,3,4,4,4,4,4,5,6,6,6,6,6,7,8,8,8,8,8};
70 70
71 71
72/* Returns TRUE if every key_values in wants has a partner with the same value in has. */ 72/* Returns TRUE if every key_values in wants has a partner with the same value in has. */
73static int compare_ob_value_lists_one(object * wants, object * has) { 73static int compare_ob_value_lists_one(const object * wants, const object * has) {
74 key_value * wants_field; 74 key_value * wants_field;
75 75
76 /* n-squared behaviour (see get_ob_key_link()), but I'm hoping both 76 /* n-squared behaviour (see get_ob_key_link()), but I'm hoping both
77 * objects with lists are rare, and lists stay short. If not, use a 77 * objects with lists are rare, and lists stay short. If not, use a
78 * different structure or at least keep the lists sorted... 78 * different structure or at least keep the lists sorted...
102 /* If we get here, every field in wants has a matching field in has. */ 102 /* If we get here, every field in wants has a matching field in has. */
103 return TRUE; 103 return TRUE;
104} 104}
105 105
106/* Returns TRUE if ob1 has the same key_values as ob2. */ 106/* Returns TRUE if ob1 has the same key_values as ob2. */
107static int compare_ob_value_lists(object * ob1, object * ob2) { 107static int compare_ob_value_lists(const object * ob1, const object * ob2) {
108 /* However, there may be fields in has which aren't partnered in wants, 108 /* However, there may be fields in has which aren't partnered in wants,
109 * so we need to run the comparison *twice*. :( 109 * so we need to run the comparison *twice*. :(
110 */ 110 */
111 return compare_ob_value_lists_one(ob1, ob2) && compare_ob_value_lists_one(ob2, ob1); 111 return compare_ob_value_lists_one(ob1, ob2) && compare_ob_value_lists_one(ob2, ob1);
112} 112}
197 (ob1->materialname != ob2->materialname) || 197 (ob1->materialname != ob2->materialname) ||
198 (ob1->lore != ob2->lore) || 198 (ob1->lore != ob2->lore) ||
199 (ob1->subtype != ob2->subtype) || 199 (ob1->subtype != ob2->subtype) ||
200 (ob1->move_type != ob2->move_type) || 200 (ob1->move_type != ob2->move_type) ||
201 (ob1->move_block != ob2->move_block) || 201 (ob1->move_block != ob2->move_block) ||
202 (ob1->move_allow != ob2->move_allow) ||
202 (ob1->move_on != ob2->move_on) || 203 (ob1->move_on != ob2->move_on) ||
203 (ob1->move_off != ob2->move_off) || 204 (ob1->move_off != ob2->move_off) ||
204 (ob1->move_slow != ob2->move_slow) || 205 (ob1->move_slow != ob2->move_slow) ||
205 (ob1->move_slow_penalty != ob2->move_slow_penalty) 206 (ob1->move_slow_penalty != ob2->move_slow_penalty)
206 ) 207 )
384 * get_nearest_part(multi-object, object 2) returns the part of the 385 * get_nearest_part(multi-object, object 2) returns the part of the
385 * multi-object 1 which is closest to the second object. 386 * multi-object 1 which is closest to the second object.
386 * If it's not a multi-object, it is returned. 387 * If it's not a multi-object, it is returned.
387 */ 388 */
388 389
389object *get_nearest_part(object *op,object *pl) { 390object *get_nearest_part(object *op, const object *pl) {
390 object *tmp,*closest; 391 object *tmp,*closest;
391 int last_dist,i; 392 int last_dist,i;
392 if(op->more==NULL) 393 if(op->more==NULL)
393 return op; 394 return op;
394 for(last_dist=distance(op,pl),closest=op,tmp=op->more;tmp!=NULL;tmp=tmp->more) 395 for(last_dist=distance(op,pl),closest=op,tmp=op->more;tmp!=NULL;tmp=tmp->more)
413 * Returns the first object which has a name equal to the argument. 414 * Returns the first object which has a name equal to the argument.
414 * Used only by the patch command, but not all that useful. 415 * Used only by the patch command, but not all that useful.
415 * Enables features like "patch <name-of-other-player> food 999" 416 * Enables features like "patch <name-of-other-player> food 999"
416 */ 417 */
417 418
418object *find_object_name(char *str) { 419object *find_object_name(const char *str) {
419 const char *name=add_string(str); 420 const char *name=add_string(str);
420 object *op; 421 object *op;
421 for(op=objects;op!=NULL;op=op->next) 422 for(op=objects;op!=NULL;op=op->next)
422 if(op->name==name) 423 if(op->name==name)
423 break; 424 break;
1018 if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE)) 1019 if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE))
1019 update_now=1; 1020 update_now=1;
1020 1021
1021 if ((move_on | op->move_on) != move_on) update_now=1; 1022 if ((move_on | op->move_on) != move_on) update_now=1;
1022 if ((move_off | op->move_off) != move_off) update_now=1; 1023 if ((move_off | op->move_off) != move_off) update_now=1;
1024 /* This isn't perfect, but I don't expect a lot of objects to
1025 * to have move_allow right now.
1026 */
1023 if ((move_block | op->move_block) != move_block) update_now=1; 1027 if (((move_block | op->move_block) & ~op->move_allow) != move_block)
1028 update_now=1;
1024 if ((move_slow | op->move_slow) != move_slow) update_now=1; 1029 if ((move_slow | op->move_slow) != move_slow) update_now=1;
1025 } 1030 }
1026 /* if the object is being removed, we can't make intelligent 1031 /* if the object is being removed, we can't make intelligent
1027 * decisions, because remove_ob can't really pass the object 1032 * decisions, because remove_ob can't really pass the object
1028 * that is being removed. 1033 * that is being removed.
1507 if(op->more!=NULL) { 1512 if(op->more!=NULL) {
1508 /* The part may be on a different map. */ 1513 /* The part may be on a different map. */
1509 1514
1510 object *more = op->more; 1515 object *more = op->more;
1511 1516
1517 /* We really need the caller to normalize coordinates - if
1518 * we set the map, that doesn't work if the location is within
1519 * a map and this is straddling an edge. So only if coordinate
1520 * is clear wrong do we normalize it.
1521 */
1522 if (OUT_OF_REAL_MAP(more->map, more->x, more->y)) {
1512 /* Debugging information so you can see the last coordinates this object had */ 1523 /* Debugging information so you can see the last coordinates this object had */
1513 more->ox = more->x; 1524 more->ox = more->x;
1514 more->oy = more->y; 1525 more->oy = more->y;
1515 more->map = get_map_from_coord(m, &more->x, &more->y); 1526 more->map = get_map_from_coord(m, &more->x, &more->y);
1527 } else if (!more->map) {
1528 /* For backwards compatibility - when not dealing with tiled maps,
1529 * more->map should always point to the parent.
1530 */
1531 more->map = m;
1532 }
1516 1533
1517 if (insert_ob_in_map(more, more->map, originator, flag) == NULL) { 1534 if (insert_ob_in_map(more, more->map, originator, flag) == NULL) {
1518 if ( ! op->head) 1535 if ( ! op->head)
1519 LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); 1536 LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n");
1520 return NULL; 1537 return NULL;
1702 1719
1703/* this function inserts an object in the map, but if it 1720/* this function inserts an object in the map, but if it
1704 * finds an object of its own type, it'll remove that one first. 1721 * finds an object of its own type, it'll remove that one first.
1705 * op is the object to insert it under: supplies x and the map. 1722 * op is the object to insert it under: supplies x and the map.
1706 */ 1723 */
1707void replace_insert_ob_in_map(char *arch_string, object *op) { 1724void replace_insert_ob_in_map(const char *arch_string, object *op) {
1708 object *tmp; 1725 object *tmp;
1709 object *tmp1; 1726 object *tmp1;
1710 1727
1711 /* first search for itself and remove any old instances */ 1728 /* first search for itself and remove any old instances */
1712 1729
2080 * present_arch(arch, map, x, y) searches for any objects with 2097 * present_arch(arch, map, x, y) searches for any objects with
2081 * a matching archetype at the given map and coordinates. 2098 * a matching archetype at the given map and coordinates.
2082 * The first matching object is returned, or NULL if none. 2099 * The first matching object is returned, or NULL if none.
2083 */ 2100 */
2084 2101
2085object *present_arch(archetype *at, mapstruct *m, int x, int y) { 2102object *present_arch(const archetype *at, mapstruct *m, int x, int y) {
2086 object *tmp; 2103 object *tmp;
2087 if(m==NULL || out_of_map(m,x,y)) { 2104 if(m==NULL || out_of_map(m,x,y)) {
2088 LOG(llevError,"Present_arch called outside map.\n"); 2105 LOG(llevError,"Present_arch called outside map.\n");
2089 return NULL; 2106 return NULL;
2090 } 2107 }
2116 * present_in_ob(type, object) searches for any objects with 2133 * present_in_ob(type, object) searches for any objects with
2117 * a matching type variable in the inventory of the given object. 2134 * a matching type variable in the inventory of the given object.
2118 * The first matching object is returned, or NULL if none. 2135 * The first matching object is returned, or NULL if none.
2119 */ 2136 */
2120 2137
2121object *present_in_ob(unsigned char type,object *op) { 2138object *present_in_ob(unsigned char type, const object *op) {
2122 object *tmp; 2139 object *tmp;
2123 for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) 2140 for(tmp=op->inv;tmp!=NULL;tmp=tmp->below)
2124 if(tmp->type==type) 2141 if(tmp->type==type)
2125 return tmp; 2142 return tmp;
2126 return NULL; 2143 return NULL;
2139 * the object name, not the archetype name. this is so that the 2156 * the object name, not the archetype name. this is so that the
2140 * spell code can use one object type (force), but change it's name 2157 * spell code can use one object type (force), but change it's name
2141 * to be unique. 2158 * to be unique.
2142 */ 2159 */
2143 2160
2144object *present_in_ob_by_name(int type, char *str,object *op) { 2161object *present_in_ob_by_name(int type, const char *str, const object *op) {
2145 object *tmp; 2162 object *tmp;
2146 2163
2147 for(tmp=op->inv; tmp!=NULL; tmp=tmp->below) { 2164 for(tmp=op->inv; tmp!=NULL; tmp=tmp->below) {
2148 if ((type==-1 || tmp->type==type) && (!strcmp(str, tmp->name))) 2165 if ((type==-1 || tmp->type==type) && (!strcmp(str, tmp->name)))
2149 return tmp; 2166 return tmp;
2155 * present_arch_in_ob(archetype, object) searches for any objects with 2172 * present_arch_in_ob(archetype, object) searches for any objects with
2156 * a matching archetype in the inventory of the given object. 2173 * a matching archetype in the inventory of the given object.
2157 * The first matching object is returned, or NULL if none. 2174 * The first matching object is returned, or NULL if none.
2158 */ 2175 */
2159 2176
2160object *present_arch_in_ob(archetype *at, object *op) { 2177object *present_arch_in_ob(const archetype *at, const object *op) {
2161 object *tmp; 2178 object *tmp;
2162 for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) 2179 for(tmp=op->inv;tmp!=NULL;tmp=tmp->below)
2163 if( tmp->arch == at) 2180 if( tmp->arch == at)
2164 return tmp; 2181 return tmp;
2165 return NULL; 2182 return NULL;
2219 * to know if the space in question will block the object. We can't use 2236 * to know if the space in question will block the object. We can't use
2220 * the archetype because that isn't correct if the monster has been 2237 * the archetype because that isn't correct if the monster has been
2221 * customized, changed states, etc. 2238 * customized, changed states, etc.
2222 */ 2239 */
2223 2240
2224int find_free_spot(object *ob, mapstruct *m,int x,int y,int start,int stop) { 2241int find_free_spot(const object *ob, mapstruct *m,int x,int y,int start,int stop) {
2225 int i,index=0, flag; 2242 int i,index=0, flag;
2226 static int altern[SIZEOFFREE]; 2243 static int altern[SIZEOFFREE];
2227 2244
2228 for(i=start;i<stop;i++) { 2245 for(i=start;i<stop;i++) {
2229 flag = ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i]); 2246 flag = ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i]);
2250 * find_free_spot(), but it will search max number of squares. 2267 * find_free_spot(), but it will search max number of squares.
2251 * But it will return the first available spot, not a random choice. 2268 * But it will return the first available spot, not a random choice.
2252 * Changed 0.93.2: Have it return -1 if there is no free spot available. 2269 * Changed 0.93.2: Have it return -1 if there is no free spot available.
2253 */ 2270 */
2254 2271
2255int find_first_free_spot(object *ob, mapstruct *m,int x,int y) { 2272int find_first_free_spot(const object *ob, mapstruct *m,int x,int y) {
2256 int i; 2273 int i;
2257 for(i=0;i<SIZEOFFREE;i++) { 2274 for(i=0;i<SIZEOFFREE;i++) {
2258 if(!ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i])) 2275 if(!ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i]))
2259 return i; 2276 return i;
2260 } 2277 }
2361/* 2378/*
2362 * distance(object 1, object 2) will return the square of the 2379 * distance(object 1, object 2) will return the square of the
2363 * distance between the two given objects. 2380 * distance between the two given objects.
2364 */ 2381 */
2365 2382
2366int distance(object *ob1,object *ob2) { 2383int distance(const object *ob1, const object *ob2) {
2367 int i; 2384 int i;
2368 i= (ob1->x - ob2->x)*(ob1->x - ob2->x)+ 2385 i= (ob1->x - ob2->x)*(ob1->x - ob2->x)+
2369 (ob1->y - ob2->y)*(ob1->y - ob2->y); 2386 (ob1->y - ob2->y)*(ob1->y - ob2->y);
2370 return i; 2387 return i;
2371} 2388}
2536 * core dumps if they do. 2553 * core dumps if they do.
2537 * 2554 *
2538 * Add a check so we can't pick up invisible objects (0.93.8) 2555 * Add a check so we can't pick up invisible objects (0.93.8)
2539 */ 2556 */
2540 2557
2541int can_pick(object *who,object *item) { 2558int can_pick(const object *who, const object *item) {
2542 return /*QUERY_FLAG(who,FLAG_WIZ)||*/ 2559 return /*QUERY_FLAG(who,FLAG_WIZ)||*/
2543 (item->weight>0&&!QUERY_FLAG(item,FLAG_NO_PICK)&& 2560 (item->weight>0&&!QUERY_FLAG(item,FLAG_NO_PICK)&&
2544 !QUERY_FLAG(item,FLAG_ALIVE)&&!item->invisible && 2561 !QUERY_FLAG(item,FLAG_ALIVE)&&!item->invisible &&
2545 (who->type==PLAYER||item->weight<who->weight/3)); 2562 (who->type==PLAYER||item->weight<who->weight/3));
2546} 2563}
2581 2598
2582 return dst; 2599 return dst;
2583} 2600}
2584 2601
2585/* return true if the object was destroyed, 0 otherwise */ 2602/* return true if the object was destroyed, 0 otherwise */
2586int was_destroyed (object *op, tag_t old_tag) 2603int was_destroyed (const object *op, tag_t old_tag)
2587{ 2604{
2588 /* checking for FLAG_FREED isn't necessary, but makes this function more 2605 /* checking for FLAG_FREED isn't necessary, but makes this function more
2589 * robust */ 2606 * robust */
2590 return op->count != old_tag || QUERY_FLAG (op, FLAG_FREED); 2607 return op->count != old_tag || QUERY_FLAG (op, FLAG_FREED);
2591} 2608}
2595/* load_object on it. I admit it is a highly inefficient way to make things, */ 2612/* load_object on it. I admit it is a highly inefficient way to make things, */
2596/* but it was simple to make and allows reusing the load_object function. */ 2613/* but it was simple to make and allows reusing the load_object function. */
2597/* Remember not to use load_object_str in a time-critical situation. */ 2614/* Remember not to use load_object_str in a time-critical situation. */
2598/* Also remember that multiparts objects are not supported for now. */ 2615/* Also remember that multiparts objects are not supported for now. */
2599 2616
2600object* load_object_str(char *obstr) 2617object* load_object_str(const char *obstr)
2601{ 2618{
2602 object *op; 2619 object *op;
2603 FILE *tempfile; 2620 FILE *tempfile;
2604 char filename[MAX_BUF]; 2621 char filename[MAX_BUF];
2605 sprintf(filename,"%s/cfloadobstr2044",settings.tmpdir); 2622 sprintf(filename,"%s/cfloadobstr2044",settings.tmpdir);
2629 2646
2630/* This returns the first object in who's inventory that 2647/* This returns the first object in who's inventory that
2631 * has the same type and subtype match. 2648 * has the same type and subtype match.
2632 * returns NULL if no match. 2649 * returns NULL if no match.
2633 */ 2650 */
2634object *find_obj_by_type_subtype(object *who, int type, int subtype) 2651object *find_obj_by_type_subtype(const object *who, int type, int subtype)
2635{ 2652{
2636 object *tmp; 2653 object *tmp;
2637 2654
2638 for (tmp=who->inv; tmp; tmp=tmp->below) 2655 for (tmp=who->inv; tmp; tmp=tmp->below)
2639 if (tmp->type == type && tmp->subtype == subtype) return tmp; 2656 if (tmp->type == type && tmp->subtype == subtype) return tmp;
2645 * otherwise return NULL. 2662 * otherwise return NULL.
2646 * 2663 *
2647 * key must be a passed in shared string - otherwise, this won't 2664 * key must be a passed in shared string - otherwise, this won't
2648 * do the desired thing. 2665 * do the desired thing.
2649 */ 2666 */
2650key_value * get_ob_key_link(object * ob, const char * key) { 2667key_value * get_ob_key_link(const object * ob, const char * key) {
2651 key_value * link; 2668 key_value * link;
2652 2669
2653 for (link = ob->key_values; link != NULL; link = link->next) { 2670 for (link = ob->key_values; link != NULL; link = link->next) {
2654 if (link->key == key) { 2671 if (link->key == key) {
2655 return link; 2672 return link;
2664 * 2681 *
2665 * The argument doesn't need to be a shared string. 2682 * The argument doesn't need to be a shared string.
2666 * 2683 *
2667 * The returned string is shared. 2684 * The returned string is shared.
2668 */ 2685 */
2669const char * get_ob_key_value(object * op, const char * const key) { 2686const char * get_ob_key_value(const object * op, const char * const key) {
2670 key_value * link; 2687 key_value * link;
2671 const char * canonical_key; 2688 const char * canonical_key;
2672 2689
2673 canonical_key = find_string(key); 2690 canonical_key = find_string(key);
2674 2691

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines