1 | /* |
1 | /* |
2 | * static char *rcsid_object_c = |
2 | * static char *rcsid_object_c = |
3 | * "$Id: object.c,v 1.2 2006/02/07 23:29:55 root Exp $"; |
3 | * "$Id: object.c,v 1.7 2006/06/23 18:30:22 root 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 | |
… | |
… | |
69 | 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 | 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, |
70 | 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 | 1,2,2,2,2,2,3,4,4,4,4,4,5,6,6,6,6,6,7,8,8,8,8,8}; |
71 | |
71 | |
72 | |
72 | |
73 | /* Returns TRUE if every key_values in wants has a partner with the same value in has. */ |
73 | /* Returns TRUE if every key_values in wants has a partner with the same value in has. */ |
74 | static int compare_ob_value_lists_one(object * wants, object * has) { |
74 | static int compare_ob_value_lists_one(const object * wants, const object * has) { |
75 | key_value * wants_field; |
75 | key_value * wants_field; |
76 | |
76 | |
77 | /* n-squared behaviour (see get_ob_key_link()), but I'm hoping both |
77 | /* n-squared behaviour (see get_ob_key_link()), but I'm hoping both |
78 | * objects with lists are rare, and lists stay short. If not, use a |
78 | * objects with lists are rare, and lists stay short. If not, use a |
79 | * different structure or at least keep the lists sorted... |
79 | * different structure or at least keep the lists sorted... |
… | |
… | |
103 | /* If we get here, every field in wants has a matching field in has. */ |
103 | /* If we get here, every field in wants has a matching field in has. */ |
104 | return TRUE; |
104 | return TRUE; |
105 | } |
105 | } |
106 | |
106 | |
107 | /* Returns TRUE if ob1 has the same key_values as ob2. */ |
107 | /* Returns TRUE if ob1 has the same key_values as ob2. */ |
108 | static int compare_ob_value_lists(object * ob1, object * ob2) { |
108 | static int compare_ob_value_lists(const object * ob1, const object * ob2) { |
109 | /* However, there may be fields in has which aren't partnered in wants, |
109 | /* However, there may be fields in has which aren't partnered in wants, |
110 | * so we need to run the comparison *twice*. :( |
110 | * so we need to run the comparison *twice*. :( |
111 | */ |
111 | */ |
112 | return compare_ob_value_lists_one(ob1, ob2) && compare_ob_value_lists_one(ob2, ob1); |
112 | return compare_ob_value_lists_one(ob1, ob2) && compare_ob_value_lists_one(ob2, ob1); |
113 | } |
113 | } |
… | |
… | |
198 | (ob1->materialname != ob2->materialname) || |
198 | (ob1->materialname != ob2->materialname) || |
199 | (ob1->lore != ob2->lore) || |
199 | (ob1->lore != ob2->lore) || |
200 | (ob1->subtype != ob2->subtype) || |
200 | (ob1->subtype != ob2->subtype) || |
201 | (ob1->move_type != ob2->move_type) || |
201 | (ob1->move_type != ob2->move_type) || |
202 | (ob1->move_block != ob2->move_block) || |
202 | (ob1->move_block != ob2->move_block) || |
|
|
203 | (ob1->move_allow != ob2->move_allow) || |
203 | (ob1->move_on != ob2->move_on) || |
204 | (ob1->move_on != ob2->move_on) || |
204 | (ob1->move_off != ob2->move_off) || |
205 | (ob1->move_off != ob2->move_off) || |
205 | (ob1->move_slow != ob2->move_slow) || |
206 | (ob1->move_slow != ob2->move_slow) || |
206 | (ob1->move_slow_penalty != ob2->move_slow_penalty) |
207 | (ob1->move_slow_penalty != ob2->move_slow_penalty) |
207 | ) |
208 | ) |
… | |
… | |
212 | * some items equipped, and we don't want those to merge. |
213 | * some items equipped, and we don't want those to merge. |
213 | */ |
214 | */ |
214 | if (QUERY_FLAG(ob1, FLAG_APPLIED) || QUERY_FLAG(ob2, FLAG_APPLIED)) |
215 | if (QUERY_FLAG(ob1, FLAG_APPLIED) || QUERY_FLAG(ob2, FLAG_APPLIED)) |
215 | return 0; |
216 | return 0; |
216 | |
217 | |
|
|
218 | switch (ob1->type) { |
|
|
219 | case SCROLL: |
|
|
220 | if (ob1->level != ob2->level) return 0; |
|
|
221 | break; |
|
|
222 | |
|
|
223 | } |
217 | if (ob1->key_values != NULL || ob2->key_values != NULL) { |
224 | if (ob1->key_values != NULL || ob2->key_values != NULL) { |
218 | /* At least one of these has key_values. */ |
225 | /* At least one of these has key_values. */ |
219 | if ((ob1->key_values == NULL) != (ob2->key_values == NULL)) { |
226 | if ((ob1->key_values == NULL) != (ob2->key_values == NULL)) { |
220 | /* One has fields, but the other one doesn't. */ |
227 | /* One has fields, but the other one doesn't. */ |
221 | return 0; |
228 | return 0; |
222 | } else { |
|
|
223 | return compare_ob_value_lists(ob1, ob2); |
229 | } else if (!compare_ob_value_lists(ob1, ob2)) { |
|
|
230 | return 0; |
224 | } |
231 | } |
225 | } |
232 | } |
226 | |
233 | |
227 | switch (ob1->type) { |
|
|
228 | case SCROLL: |
|
|
229 | if (ob1->level != ob2->level) return 0; |
|
|
230 | break; |
|
|
231 | |
|
|
232 | } |
|
|
233 | /* Everything passes, must be OK. */ |
234 | /* Everything passes, must be OK. */ |
234 | return 1; |
235 | return 1; |
235 | } |
236 | } |
236 | |
237 | |
237 | /* |
238 | /* |
… | |
… | |
385 | * get_nearest_part(multi-object, object 2) returns the part of the |
386 | * get_nearest_part(multi-object, object 2) returns the part of the |
386 | * multi-object 1 which is closest to the second object. |
387 | * multi-object 1 which is closest to the second object. |
387 | * If it's not a multi-object, it is returned. |
388 | * If it's not a multi-object, it is returned. |
388 | */ |
389 | */ |
389 | |
390 | |
390 | object *get_nearest_part(object *op,object *pl) { |
391 | object *get_nearest_part(object *op, const object *pl) { |
391 | object *tmp,*closest; |
392 | object *tmp,*closest; |
392 | int last_dist,i; |
393 | int last_dist,i; |
393 | if(op->more==NULL) |
394 | if(op->more==NULL) |
394 | return op; |
395 | return op; |
395 | for(last_dist=distance(op,pl),closest=op,tmp=op->more;tmp!=NULL;tmp=tmp->more) |
396 | for(last_dist=distance(op,pl),closest=op,tmp=op->more;tmp!=NULL;tmp=tmp->more) |
… | |
… | |
414 | * Returns the first object which has a name equal to the argument. |
415 | * Returns the first object which has a name equal to the argument. |
415 | * Used only by the patch command, but not all that useful. |
416 | * Used only by the patch command, but not all that useful. |
416 | * Enables features like "patch <name-of-other-player> food 999" |
417 | * Enables features like "patch <name-of-other-player> food 999" |
417 | */ |
418 | */ |
418 | |
419 | |
419 | object *find_object_name(char *str) { |
420 | object *find_object_name(const char *str) { |
420 | const char *name=add_string(str); |
421 | const char *name=add_string(str); |
421 | object *op; |
422 | object *op; |
422 | for(op=objects;op!=NULL;op=op->next) |
423 | for(op=objects;op!=NULL;op=op->next) |
423 | if(op->name==name) |
424 | if(op->name==name) |
424 | break; |
425 | break; |
… | |
… | |
1019 | if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE)) |
1020 | if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE)) |
1020 | update_now=1; |
1021 | update_now=1; |
1021 | |
1022 | |
1022 | if ((move_on | op->move_on) != move_on) update_now=1; |
1023 | if ((move_on | op->move_on) != move_on) update_now=1; |
1023 | if ((move_off | op->move_off) != move_off) update_now=1; |
1024 | if ((move_off | op->move_off) != move_off) update_now=1; |
|
|
1025 | /* This isn't perfect, but I don't expect a lot of objects to |
|
|
1026 | * to have move_allow right now. |
|
|
1027 | */ |
1024 | if ((move_block | op->move_block) != move_block) update_now=1; |
1028 | if (((move_block | op->move_block) & ~op->move_allow) != move_block) |
|
|
1029 | update_now=1; |
1025 | if ((move_slow | op->move_slow) != move_slow) update_now=1; |
1030 | if ((move_slow | op->move_slow) != move_slow) update_now=1; |
1026 | } |
1031 | } |
1027 | /* if the object is being removed, we can't make intelligent |
1032 | /* if the object is being removed, we can't make intelligent |
1028 | * decisions, because remove_ob can't really pass the object |
1033 | * decisions, because remove_ob can't really pass the object |
1029 | * that is being removed. |
1034 | * that is being removed. |
… | |
… | |
1511 | if(op->more!=NULL) { |
1516 | if(op->more!=NULL) { |
1512 | /* The part may be on a different map. */ |
1517 | /* The part may be on a different map. */ |
1513 | |
1518 | |
1514 | object *more = op->more; |
1519 | object *more = op->more; |
1515 | |
1520 | |
|
|
1521 | /* We really need the caller to normalize coordinates - if |
|
|
1522 | * we set the map, that doesn't work if the location is within |
|
|
1523 | * a map and this is straddling an edge. So only if coordinate |
|
|
1524 | * is clear wrong do we normalize it. |
|
|
1525 | */ |
|
|
1526 | if (OUT_OF_REAL_MAP(more->map, more->x, more->y)) { |
1516 | /* Debugging information so you can see the last coordinates this object had */ |
1527 | /* Debugging information so you can see the last coordinates this object had */ |
1517 | more->ox = more->x; |
1528 | more->ox = more->x; |
1518 | more->oy = more->y; |
1529 | more->oy = more->y; |
1519 | more->map = get_map_from_coord(m, &more->x, &more->y); |
1530 | more->map = get_map_from_coord(m, &more->x, &more->y); |
|
|
1531 | } else if (!more->map) { |
|
|
1532 | /* For backwards compatibility - when not dealing with tiled maps, |
|
|
1533 | * more->map should always point to the parent. |
|
|
1534 | */ |
|
|
1535 | more->map = m; |
|
|
1536 | } |
1520 | |
1537 | |
1521 | if (insert_ob_in_map(more, more->map, originator, flag) == NULL) { |
1538 | if (insert_ob_in_map(more, more->map, originator, flag) == NULL) { |
1522 | if ( ! op->head) |
1539 | if ( ! op->head) |
1523 | LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); |
1540 | LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); |
1524 | return NULL; |
1541 | return NULL; |
… | |
… | |
1527 | CLEAR_FLAG(op,FLAG_REMOVED); |
1544 | CLEAR_FLAG(op,FLAG_REMOVED); |
1528 | |
1545 | |
1529 | /* Debugging information so you can see the last coordinates this object had */ |
1546 | /* Debugging information so you can see the last coordinates this object had */ |
1530 | op->ox=op->x; |
1547 | op->ox=op->x; |
1531 | op->oy=op->y; |
1548 | op->oy=op->y; |
|
|
1549 | |
|
|
1550 | /* Ideally, the caller figures this out. However, it complicates a lot |
|
|
1551 | * of areas of callers (eg, anything that uses find_free_spot would now |
|
|
1552 | * need extra work |
|
|
1553 | */ |
|
|
1554 | op->map=get_map_from_coord(m, &op->x, &op->y); |
1532 | x = op->x; |
1555 | x = op->x; |
1533 | y = op->y; |
1556 | y = op->y; |
1534 | op->map=get_map_from_coord(m, &x, &y); |
|
|
1535 | |
1557 | |
1536 | /* this has to be done after we translate the coordinates. |
1558 | /* this has to be done after we translate the coordinates. |
1537 | */ |
1559 | */ |
1538 | if(op->nrof && !(flag & INS_NO_MERGE)) { |
1560 | if(op->nrof && !(flag & INS_NO_MERGE)) { |
1539 | for(tmp=GET_MAP_OB(op->map,x,y);tmp!=NULL;tmp=tmp->above) |
1561 | for(tmp=GET_MAP_OB(op->map,x,y);tmp!=NULL;tmp=tmp->above) |
1540 | if (CAN_MERGE(op,tmp)) { |
1562 | if (CAN_MERGE(op,tmp)) { |
1541 | op->nrof+=tmp->nrof; |
1563 | op->nrof+=tmp->nrof; |
1542 | remove_ob(tmp); |
1564 | remove_ob(tmp); |
1543 | free_object(tmp); |
1565 | free_object(tmp); |
1544 | } |
1566 | } |
1545 | } |
|
|
1546 | |
|
|
1547 | /* Ideally, the caller figures this out. However, it complicates a lot |
|
|
1548 | * of areas of callers (eg, anything that uses find_free_spot would now |
|
|
1549 | * need extra work |
|
|
1550 | */ |
|
|
1551 | if (op->map != m) { |
|
|
1552 | /* coordinates should not change unless map also changes */ |
|
|
1553 | op->x = x; |
|
|
1554 | op->y = y; |
|
|
1555 | } |
1567 | } |
1556 | |
1568 | |
1557 | CLEAR_FLAG(op,FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */ |
1569 | CLEAR_FLAG(op,FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */ |
1558 | CLEAR_FLAG(op, FLAG_INV_LOCKED); |
1570 | CLEAR_FLAG(op, FLAG_INV_LOCKED); |
1559 | if (!QUERY_FLAG(op, FLAG_ALIVE)) |
1571 | if (!QUERY_FLAG(op, FLAG_ALIVE)) |
… | |
… | |
1617 | if (!(flag & INS_ON_TOP) && |
1629 | if (!(flag & INS_ON_TOP) && |
1618 | (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_BLOCKSVIEW) && |
1630 | (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_BLOCKSVIEW) && |
1619 | (op->face && !op->face->visibility)) { |
1631 | (op->face && !op->face->visibility)) { |
1620 | for (last=top; last != floor; last=last->below) |
1632 | for (last=top; last != floor; last=last->below) |
1621 | if (QUERY_FLAG(last, FLAG_BLOCKSVIEW)&&(last->type != EXIT)) break; |
1633 | if (QUERY_FLAG(last, FLAG_BLOCKSVIEW)&&(last->type != EXIT)) break; |
1622 | /* Check to see i we found the object that blocks view, |
1634 | /* Check to see if we found the object that blocks view, |
1623 | * and make sure we have a below pointer for it so that |
1635 | * and make sure we have a below pointer for it so that |
1624 | * we can get inserted below this one, which requires we |
1636 | * we can get inserted below this one, which requires we |
1625 | * set top to the object below us. |
1637 | * set top to the object below us. |
1626 | */ |
1638 | */ |
1627 | if (last && last->below && last != floor) top=last->below; |
1639 | if (last && last->below && last != floor) top=last->below; |
… | |
… | |
1706 | |
1718 | |
1707 | /* this function inserts an object in the map, but if it |
1719 | /* this function inserts an object in the map, but if it |
1708 | * finds an object of its own type, it'll remove that one first. |
1720 | * finds an object of its own type, it'll remove that one first. |
1709 | * op is the object to insert it under: supplies x and the map. |
1721 | * op is the object to insert it under: supplies x and the map. |
1710 | */ |
1722 | */ |
1711 | void replace_insert_ob_in_map(char *arch_string, object *op) { |
1723 | void replace_insert_ob_in_map(const char *arch_string, object *op) { |
1712 | object *tmp; |
1724 | object *tmp; |
1713 | object *tmp1; |
1725 | object *tmp1; |
1714 | |
1726 | |
1715 | /* first search for itself and remove any old instances */ |
1727 | /* first search for itself and remove any old instances */ |
1716 | |
1728 | |
… | |
… | |
2084 | * present_arch(arch, map, x, y) searches for any objects with |
2096 | * present_arch(arch, map, x, y) searches for any objects with |
2085 | * a matching archetype at the given map and coordinates. |
2097 | * a matching archetype at the given map and coordinates. |
2086 | * The first matching object is returned, or NULL if none. |
2098 | * The first matching object is returned, or NULL if none. |
2087 | */ |
2099 | */ |
2088 | |
2100 | |
2089 | object *present_arch(archetype *at, mapstruct *m, int x, int y) { |
2101 | object *present_arch(const archetype *at, mapstruct *m, int x, int y) { |
2090 | object *tmp; |
2102 | object *tmp; |
2091 | if(m==NULL || out_of_map(m,x,y)) { |
2103 | if(m==NULL || out_of_map(m,x,y)) { |
2092 | LOG(llevError,"Present_arch called outside map.\n"); |
2104 | LOG(llevError,"Present_arch called outside map.\n"); |
2093 | return NULL; |
2105 | return NULL; |
2094 | } |
2106 | } |
… | |
… | |
2120 | * present_in_ob(type, object) searches for any objects with |
2132 | * present_in_ob(type, object) searches for any objects with |
2121 | * a matching type variable in the inventory of the given object. |
2133 | * a matching type variable in the inventory of the given object. |
2122 | * The first matching object is returned, or NULL if none. |
2134 | * The first matching object is returned, or NULL if none. |
2123 | */ |
2135 | */ |
2124 | |
2136 | |
2125 | object *present_in_ob(unsigned char type,object *op) { |
2137 | object *present_in_ob(unsigned char type, const object *op) { |
2126 | object *tmp; |
2138 | object *tmp; |
2127 | for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) |
2139 | for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) |
2128 | if(tmp->type==type) |
2140 | if(tmp->type==type) |
2129 | return tmp; |
2141 | return tmp; |
2130 | return NULL; |
2142 | return NULL; |
… | |
… | |
2143 | * the object name, not the archetype name. this is so that the |
2155 | * the object name, not the archetype name. this is so that the |
2144 | * spell code can use one object type (force), but change it's name |
2156 | * spell code can use one object type (force), but change it's name |
2145 | * to be unique. |
2157 | * to be unique. |
2146 | */ |
2158 | */ |
2147 | |
2159 | |
2148 | object *present_in_ob_by_name(int type, char *str,object *op) { |
2160 | object *present_in_ob_by_name(int type, const char *str, const object *op) { |
2149 | object *tmp; |
2161 | object *tmp; |
2150 | |
2162 | |
2151 | for(tmp=op->inv; tmp!=NULL; tmp=tmp->below) { |
2163 | for(tmp=op->inv; tmp!=NULL; tmp=tmp->below) { |
2152 | if ((type==-1 || tmp->type==type) && (!strcmp(str, tmp->name))) |
2164 | if ((type==-1 || tmp->type==type) && (!strcmp(str, tmp->name))) |
2153 | return tmp; |
2165 | return tmp; |
… | |
… | |
2159 | * present_arch_in_ob(archetype, object) searches for any objects with |
2171 | * present_arch_in_ob(archetype, object) searches for any objects with |
2160 | * a matching archetype in the inventory of the given object. |
2172 | * a matching archetype in the inventory of the given object. |
2161 | * The first matching object is returned, or NULL if none. |
2173 | * The first matching object is returned, or NULL if none. |
2162 | */ |
2174 | */ |
2163 | |
2175 | |
2164 | object *present_arch_in_ob(archetype *at, object *op) { |
2176 | object *present_arch_in_ob(const archetype *at, const object *op) { |
2165 | object *tmp; |
2177 | object *tmp; |
2166 | for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) |
2178 | for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) |
2167 | if( tmp->arch == at) |
2179 | if( tmp->arch == at) |
2168 | return tmp; |
2180 | return tmp; |
2169 | return NULL; |
2181 | return NULL; |
… | |
… | |
2223 | * to know if the space in question will block the object. We can't use |
2235 | * to know if the space in question will block the object. We can't use |
2224 | * the archetype because that isn't correct if the monster has been |
2236 | * the archetype because that isn't correct if the monster has been |
2225 | * customized, changed states, etc. |
2237 | * customized, changed states, etc. |
2226 | */ |
2238 | */ |
2227 | |
2239 | |
2228 | int find_free_spot(object *ob, mapstruct *m,int x,int y,int start,int stop) { |
2240 | int find_free_spot(const object *ob, mapstruct *m,int x,int y,int start,int stop) { |
2229 | int i,index=0, flag; |
2241 | int i,index=0, flag; |
2230 | static int altern[SIZEOFFREE]; |
2242 | static int altern[SIZEOFFREE]; |
2231 | |
2243 | |
2232 | for(i=start;i<stop;i++) { |
2244 | for(i=start;i<stop;i++) { |
2233 | flag = ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i]); |
2245 | flag = ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i]); |
… | |
… | |
2254 | * find_free_spot(), but it will search max number of squares. |
2266 | * find_free_spot(), but it will search max number of squares. |
2255 | * But it will return the first available spot, not a random choice. |
2267 | * But it will return the first available spot, not a random choice. |
2256 | * Changed 0.93.2: Have it return -1 if there is no free spot available. |
2268 | * Changed 0.93.2: Have it return -1 if there is no free spot available. |
2257 | */ |
2269 | */ |
2258 | |
2270 | |
2259 | int find_first_free_spot(object *ob, mapstruct *m,int x,int y) { |
2271 | int find_first_free_spot(const object *ob, mapstruct *m,int x,int y) { |
2260 | int i; |
2272 | int i; |
2261 | for(i=0;i<SIZEOFFREE;i++) { |
2273 | for(i=0;i<SIZEOFFREE;i++) { |
2262 | if(!ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i])) |
2274 | if(!ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i])) |
2263 | return i; |
2275 | return i; |
2264 | } |
2276 | } |
… | |
… | |
2365 | /* |
2377 | /* |
2366 | * distance(object 1, object 2) will return the square of the |
2378 | * distance(object 1, object 2) will return the square of the |
2367 | * distance between the two given objects. |
2379 | * distance between the two given objects. |
2368 | */ |
2380 | */ |
2369 | |
2381 | |
2370 | int distance(object *ob1,object *ob2) { |
2382 | int distance(const object *ob1, const object *ob2) { |
2371 | int i; |
2383 | int i; |
2372 | i= (ob1->x - ob2->x)*(ob1->x - ob2->x)+ |
2384 | i= (ob1->x - ob2->x)*(ob1->x - ob2->x)+ |
2373 | (ob1->y - ob2->y)*(ob1->y - ob2->y); |
2385 | (ob1->y - ob2->y)*(ob1->y - ob2->y); |
2374 | return i; |
2386 | return i; |
2375 | } |
2387 | } |
… | |
… | |
2380 | * object, needs to travel toward it. |
2392 | * object, needs to travel toward it. |
2381 | */ |
2393 | */ |
2382 | |
2394 | |
2383 | int find_dir_2(int x, int y) { |
2395 | int find_dir_2(int x, int y) { |
2384 | int q; |
2396 | int q; |
|
|
2397 | |
2385 | if(!y) |
2398 | if(y) |
|
|
2399 | q=x*100/y; |
|
|
2400 | else if (x) |
2386 | q= -300*x; |
2401 | q= -300*x; |
2387 | else |
2402 | else |
2388 | q=x*100/y; |
2403 | return 0; |
|
|
2404 | |
2389 | if(y>0) { |
2405 | if(y>0) { |
2390 | if(q < -242) |
2406 | if(q < -242) |
2391 | return 3 ; |
2407 | return 3 ; |
2392 | if (q < -41) |
2408 | if (q < -41) |
2393 | return 2 ; |
2409 | return 2 ; |
… | |
… | |
2395 | return 1 ; |
2411 | return 1 ; |
2396 | if (q < 242) |
2412 | if (q < 242) |
2397 | return 8 ; |
2413 | return 8 ; |
2398 | return 7 ; |
2414 | return 7 ; |
2399 | } |
2415 | } |
|
|
2416 | |
2400 | if (q < -242) |
2417 | if (q < -242) |
2401 | return 7 ; |
2418 | return 7 ; |
2402 | if (q < -41) |
2419 | if (q < -41) |
2403 | return 6 ; |
2420 | return 6 ; |
2404 | if (q < 41) |
2421 | if (q < 41) |
2405 | return 5 ; |
2422 | return 5 ; |
2406 | if (q < 242) |
2423 | if (q < 242) |
2407 | return 4 ; |
2424 | return 4 ; |
|
|
2425 | |
2408 | return 3 ; |
2426 | return 3 ; |
2409 | } |
2427 | } |
2410 | |
2428 | |
2411 | /* |
2429 | /* |
2412 | * absdir(int): Returns a number between 1 and 8, which represent |
2430 | * absdir(int): Returns a number between 1 and 8, which represent |
… | |
… | |
2540 | * core dumps if they do. |
2558 | * core dumps if they do. |
2541 | * |
2559 | * |
2542 | * Add a check so we can't pick up invisible objects (0.93.8) |
2560 | * Add a check so we can't pick up invisible objects (0.93.8) |
2543 | */ |
2561 | */ |
2544 | |
2562 | |
2545 | int can_pick(object *who,object *item) { |
2563 | int can_pick(const object *who, const object *item) { |
2546 | return /*QUERY_FLAG(who,FLAG_WIZ)||*/ |
2564 | return /*QUERY_FLAG(who,FLAG_WIZ)||*/ |
2547 | (item->weight>0&&!QUERY_FLAG(item,FLAG_NO_PICK)&& |
2565 | (item->weight>0&&!QUERY_FLAG(item,FLAG_NO_PICK)&& |
2548 | !QUERY_FLAG(item,FLAG_ALIVE)&&!item->invisible && |
2566 | !QUERY_FLAG(item,FLAG_ALIVE)&&!item->invisible && |
2549 | (who->type==PLAYER||item->weight<who->weight/3)); |
2567 | (who->type==PLAYER||item->weight<who->weight/3)); |
2550 | } |
2568 | } |
… | |
… | |
2585 | |
2603 | |
2586 | return dst; |
2604 | return dst; |
2587 | } |
2605 | } |
2588 | |
2606 | |
2589 | /* return true if the object was destroyed, 0 otherwise */ |
2607 | /* return true if the object was destroyed, 0 otherwise */ |
2590 | int was_destroyed (object *op, tag_t old_tag) |
2608 | int was_destroyed (const object *op, tag_t old_tag) |
2591 | { |
2609 | { |
2592 | /* checking for FLAG_FREED isn't necessary, but makes this function more |
2610 | /* checking for FLAG_FREED isn't necessary, but makes this function more |
2593 | * robust */ |
2611 | * robust */ |
2594 | return op->count != old_tag || QUERY_FLAG (op, FLAG_FREED); |
2612 | return op->count != old_tag || QUERY_FLAG (op, FLAG_FREED); |
2595 | } |
2613 | } |
… | |
… | |
2599 | /* load_object on it. I admit it is a highly inefficient way to make things, */ |
2617 | /* load_object on it. I admit it is a highly inefficient way to make things, */ |
2600 | /* but it was simple to make and allows reusing the load_object function. */ |
2618 | /* but it was simple to make and allows reusing the load_object function. */ |
2601 | /* Remember not to use load_object_str in a time-critical situation. */ |
2619 | /* Remember not to use load_object_str in a time-critical situation. */ |
2602 | /* Also remember that multiparts objects are not supported for now. */ |
2620 | /* Also remember that multiparts objects are not supported for now. */ |
2603 | |
2621 | |
2604 | object* load_object_str(char *obstr) |
2622 | object* load_object_str(const char *obstr) |
2605 | { |
2623 | { |
2606 | object *op; |
2624 | object *op; |
2607 | FILE *tempfile; |
2625 | FILE *tempfile; |
2608 | char filename[MAX_BUF]; |
2626 | char filename[MAX_BUF]; |
2609 | sprintf(filename,"%s/cfloadobstr2044",settings.tmpdir); |
2627 | sprintf(filename,"%s/cfloadobstr2044",settings.tmpdir); |
… | |
… | |
2633 | |
2651 | |
2634 | /* This returns the first object in who's inventory that |
2652 | /* This returns the first object in who's inventory that |
2635 | * has the same type and subtype match. |
2653 | * has the same type and subtype match. |
2636 | * returns NULL if no match. |
2654 | * returns NULL if no match. |
2637 | */ |
2655 | */ |
2638 | object *find_obj_by_type_subtype(object *who, int type, int subtype) |
2656 | object *find_obj_by_type_subtype(const object *who, int type, int subtype) |
2639 | { |
2657 | { |
2640 | object *tmp; |
2658 | object *tmp; |
2641 | |
2659 | |
2642 | for (tmp=who->inv; tmp; tmp=tmp->below) |
2660 | for (tmp=who->inv; tmp; tmp=tmp->below) |
2643 | if (tmp->type == type && tmp->subtype == subtype) return tmp; |
2661 | if (tmp->type == type && tmp->subtype == subtype) return tmp; |
… | |
… | |
2649 | * otherwise return NULL. |
2667 | * otherwise return NULL. |
2650 | * |
2668 | * |
2651 | * key must be a passed in shared string - otherwise, this won't |
2669 | * key must be a passed in shared string - otherwise, this won't |
2652 | * do the desired thing. |
2670 | * do the desired thing. |
2653 | */ |
2671 | */ |
2654 | key_value * get_ob_key_link(object * ob, const char * key) { |
2672 | key_value * get_ob_key_link(const object * ob, const char * key) { |
2655 | key_value * link; |
2673 | key_value * link; |
2656 | |
2674 | |
2657 | for (link = ob->key_values; link != NULL; link = link->next) { |
2675 | for (link = ob->key_values; link != NULL; link = link->next) { |
2658 | if (link->key == key) { |
2676 | if (link->key == key) { |
2659 | return link; |
2677 | return link; |
… | |
… | |
2668 | * |
2686 | * |
2669 | * The argument doesn't need to be a shared string. |
2687 | * The argument doesn't need to be a shared string. |
2670 | * |
2688 | * |
2671 | * The returned string is shared. |
2689 | * The returned string is shared. |
2672 | */ |
2690 | */ |
2673 | const char * get_ob_key_value(object * op, const char * const key) { |
2691 | const char * get_ob_key_value(const object * op, const char * const key) { |
2674 | key_value * link; |
2692 | key_value * link; |
2675 | const char * canonical_key; |
2693 | const char * canonical_key; |
2676 | |
2694 | |
2677 | canonical_key = find_string(key); |
2695 | canonical_key = find_string(key); |
2678 | |
2696 | |
… | |
… | |
2708 | * Returns TRUE on success. |
2726 | * Returns TRUE on success. |
2709 | */ |
2727 | */ |
2710 | int set_ob_key_value_s(object * op, const char * canonical_key, const char * value, int add_key) { |
2728 | int set_ob_key_value_s(object * op, const char * canonical_key, const char * value, int add_key) { |
2711 | key_value * field = NULL, *last=NULL; |
2729 | key_value * field = NULL, *last=NULL; |
2712 | |
2730 | |
2713 | LOG(llevDebug, "set_ob_value_s: '%s' '%s' %d\n", canonical_key, value, add_key); |
|
|
2714 | |
|
|
2715 | for (field=op->key_values; field != NULL; field=field->next) { |
2731 | for (field=op->key_values; field != NULL; field=field->next) { |
2716 | if (field->key != canonical_key) { |
2732 | if (field->key != canonical_key) { |
2717 | last = field; |
2733 | last = field; |
2718 | continue; |
2734 | continue; |
2719 | } |
2735 | } |