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

Comparing deliantra/server/common/map.c (file contents):
Revision 1.1 by root, Fri Feb 3 07:11:37 2006 UTC vs.
Revision 1.2 by root, Wed Feb 8 03:46:15 2006 UTC

1/* 1/*
2 * static char *rcsid_map_c = 2 * static char *rcsid_map_c =
3 * "$Id: map.c,v 1.1 2006/02/03 07:11:37 root Exp $"; 3 * "$Id: map.c,v 1.2 2006/02/08 03:46:15 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
2008 return (get_map_from_coord(m->tile_map[2], x, y)); 2008 return (get_map_from_coord(m->tile_map[2], x, y));
2009 } 2009 }
2010 return NULL; /* Shouldn't get here */ 2010 return NULL; /* Shouldn't get here */
2011} 2011}
2012 2012
2013// return wether map2 is adjacent to map1 and store their distance
2014// in dx/dy if yes.
2015static int adjacent_map (mapstruct *map1, mapstruct *map2, int *dx, int *dy)
2016{
2017 if (!map1 || !map2)
2018 return 0;
2019
2020 else if (map1 == map2)
2021 *dx = *dy = 0;
2022
2023 else if (map1->tile_map[0] == map2) // up
2024 (*dx = 0), (*dy = -MAP_HEIGHT (map2));
2025 else if (map1->tile_map[1] == map2) // right
2026 (*dx = MAP_WIDTH (map2)), (*dy = 0);
2027 else if (map1->tile_map[2] == map2) // down
2028 (*dx = 0), (*dy = MAP_HEIGHT (map2));
2029 else if (map1->tile_map[3] == map2) // left
2030 (*dx = -MAP_WIDTH (map2)), (*dy = 0);
2031
2032 else if (map1->tile_map[0] && map1->tile_map[0]->tile_map[1] == map2) // up right
2033 (*dx = MAP_WIDTH (map2)), (*dy = -MAP_HEIGHT (map1->tile_map[0]));
2034 else if (map1->tile_map[0] && map1->tile_map[0]->tile_map[3] == map2) // up left
2035 (*dx = -MAP_WIDTH (map2)), (*dy = -MAP_HEIGHT (map1->tile_map[0]));
2036 else if (map1->tile_map[1] && map1->tile_map[1]->tile_map[0] == map2) // right up
2037 (*dx = MAP_HEIGHT (map1->tile_map[1])), (*dy = -MAP_WIDTH (map2));
2038 else if (map1->tile_map[1] && map1->tile_map[1]->tile_map[2] == map2) // right down
2039 (*dx = MAP_HEIGHT (map1->tile_map[1])), (*dy = MAP_WIDTH (map2));
2040 else if (map1->tile_map[2] && map1->tile_map[2]->tile_map[1] == map2) // down right
2041 (*dx = MAP_WIDTH (map2)), (*dy = MAP_HEIGHT (map1->tile_map[2]));
2042 else if (map1->tile_map[2] && map1->tile_map[2]->tile_map[3] == map2) // down left
2043 (*dx = -MAP_WIDTH (map2)), (*dy = MAP_HEIGHT (map1->tile_map[2]));
2044 else if (map1->tile_map[3] && map1->tile_map[3]->tile_map[0] == map2) // left up
2045 (*dx = -MAP_HEIGHT (map1->tile_map[3])), (*dy = -MAP_WIDTH (map2));
2046 else if (map1->tile_map[3] && map1->tile_map[3]->tile_map[2] == map2) // left down
2047 (*dx = MAP_HEIGHT (map1->tile_map[3])), (*dy = MAP_WIDTH (map2));
2048
2049 else // not "adjacent" enough
2050 return 0;
2051
2052 return 1;
2053}
2054
2013/* From map.c 2055/* From map.c
2014 * This is used by get_player to determine where the other 2056 * This is used by get_player to determine where the other
2015 * creature is. get_rangevector takes into account map tiling, 2057 * creature is. get_rangevector takes into account map tiling,
2016 * so you just can not look the the map coordinates and get the 2058 * so you just can not look the the map coordinates and get the
2017 * righte value. distance_x/y are distance away, which 2059 * righte value. distance_x/y are distance away, which
2031 * closest body part of 'op1' 2073 * closest body part of 'op1'
2032 */ 2074 */
2033 2075
2034void get_rangevector(object *op1, object *op2, rv_vector *retval, int flags) 2076void get_rangevector(object *op1, object *op2, rv_vector *retval, int flags)
2035{ 2077{
2078 if (!adjacent_map (op1->map, op2->map, &(retval->distance_x), &(retval->distance_y)))
2079 {
2080 // be conservative and fill in _some_ data
2081 retval->distance = 100000;
2082 retval->distance_x = 32767;
2083 retval->distance_y = 32767;
2084 retval->direction = 0;
2085 retval->part = 0;
2086 }
2087 else
2088 {
2036 object *best; 2089 object *best;
2037 2090
2038 if (op1->map->tile_map[0] == op2->map) {
2039 retval->distance_x = op2->x - op1->x; 2091 retval->distance_x += op2->x - op1->x;
2040 retval->distance_y = -(op1->y +(MAP_HEIGHT(op2->map)- op2->y));
2041
2042 }
2043 else if (op1->map->tile_map[1] == op2->map) {
2044 retval->distance_y = op2->y - op1->y; 2092 retval->distance_y += op2->y - op1->y;
2045 retval->distance_x = (MAP_WIDTH(op1->map) - op1->x) + op2->x;
2046 }
2047 else if (op1->map->tile_map[2] == op2->map) {
2048 retval->distance_x = op2->x - op1->x;
2049 retval->distance_y = (MAP_HEIGHT(op1->map) - op1->y) +op2->y;
2050 2093
2051 }
2052 else if (op1->map->tile_map[3] == op2->map) {
2053 retval->distance_y = op2->y - op1->y;
2054 retval->distance_x = -(op1->x +(MAP_WIDTH(op2->map)- op2->x));
2055 }
2056 else if (op1->map == op2->map) {
2057 retval->distance_x = op2->x - op1->x;
2058 retval->distance_y = op2->y - op1->y;
2059
2060 }
2061 best = op1; 2094 best = op1;
2062 /* If this is multipart, find the closest part now */ 2095 /* If this is multipart, find the closest part now */
2063 if (!(flags & 0x1) && op1->more) { 2096 if (!(flags & 0x1) && op1->more) {
2064 object *tmp; 2097 object *tmp;
2065 int best_distance = retval->distance_x * retval->distance_x + 2098 int best_distance = retval->distance_x * retval->distance_x +
2066 retval->distance_y * retval->distance_y, tmpi; 2099 retval->distance_y * retval->distance_y, tmpi;
2067 2100
2068 /* we just tkae the offset of the piece to head to figure 2101 /* we just tkae the offset of the piece to head to figure
2069 * distance instead of doing all that work above again 2102 * distance instead of doing all that work above again
2070 * since the distance fields we set above are positive in the 2103 * since the distance fields we set above are positive in the
2071 * same axis as is used for multipart objects, the simply arithemetic 2104 * same axis as is used for multipart objects, the simply arithemetic
2072 * below works. 2105 * below works.
2073 */ 2106 */
2074 for (tmp=op1->more; tmp; tmp=tmp->more) { 2107 for (tmp=op1->more; tmp; tmp=tmp->more) {
2075 tmpi = (op1->x - tmp->x + retval->distance_x) * (op1->x - tmp->x + retval->distance_x) + 2108 tmpi = (op1->x - tmp->x + retval->distance_x) * (op1->x - tmp->x + retval->distance_x) +
2076 (op1->y - tmp->y + retval->distance_y) * (op1->y - tmp->y + retval->distance_y); 2109 (op1->y - tmp->y + retval->distance_y) * (op1->y - tmp->y + retval->distance_y);
2077 if (tmpi < best_distance) { 2110 if (tmpi < best_distance) {
2078 best_distance = tmpi; 2111 best_distance = tmpi;
2079 best = tmp; 2112 best = tmp;
2080 } 2113 }
2081 } 2114 }
2082 if (best != op1) { 2115 if (best != op1) {
2083 retval->distance_x += op1->x - best->x; 2116 retval->distance_x += op1->x - best->x;
2084 retval->distance_y += op1->y - best->y; 2117 retval->distance_y += op1->y - best->y;
2085 } 2118 }
2086 } 2119 }
2087 retval->part = best; 2120 retval->part = best;
2088 retval->distance = isqrt(retval->distance_x*retval->distance_x + retval->distance_y*retval->distance_y); 2121 retval->distance = isqrt(retval->distance_x*retval->distance_x + retval->distance_y*retval->distance_y);
2089 retval->direction = find_dir_2(-retval->distance_x, -retval->distance_y); 2122 retval->direction = find_dir_2(-retval->distance_x, -retval->distance_y);
2123 }
2090} 2124}
2091 2125
2092/* this is basically the same as get_rangevector above, but instead of 2126/* this is basically the same as get_rangevector above, but instead of
2093 * the first parameter being an object, it instead is the map 2127 * the first parameter being an object, it instead is the map
2094 * and x,y coordinates - this is used for path to player - 2128 * and x,y coordinates - this is used for path to player -
2100 * field of the rv_vector is set to NULL. 2134 * field of the rv_vector is set to NULL.
2101 */ 2135 */
2102 2136
2103void get_rangevector_from_mapcoord(mapstruct *m, int x, int y, object *op2, rv_vector *retval,int flags) 2137void get_rangevector_from_mapcoord(mapstruct *m, int x, int y, object *op2, rv_vector *retval,int flags)
2104{ 2138{
2105 if (m->tile_map[0] == op2->map) { 2139 if (!adjacent_map (m, op2->map, &(retval->distance_x), &(retval->distance_y)))
2140 {
2141 // be conservative and fill in _some_ data
2142 retval->distance = 100000;
2143 retval->distance_x = 32767;
2144 retval->distance_y = 32767;
2145 retval->direction = 0;
2146 retval->part = 0;
2147 }
2148 else
2149 {
2106 retval->distance_x = op2->x - x; 2150 retval->distance_x += op2->x - x;
2107 retval->distance_y = -(y +(MAP_HEIGHT(op2->map)- op2->y));
2108
2109 }
2110 else if (m->tile_map[1] == op2->map) {
2111 retval->distance_y = op2->y - y; 2151 retval->distance_y += op2->y - y;
2112 retval->distance_x = (MAP_WIDTH(m) - x) + op2->x;
2113 }
2114 else if (m->tile_map[2] == op2->map) {
2115 retval->distance_x = op2->x - x;
2116 retval->distance_y = (MAP_HEIGHT(m) - y) +op2->y;
2117 2152
2118 }
2119 else if (m->tile_map[3] == op2->map) {
2120 retval->distance_y = op2->y - y;
2121 retval->distance_x = -(x +(MAP_WIDTH(op2->map)- op2->y));
2122 }
2123 else if (m == op2->map) {
2124 retval->distance_x = op2->x - x;
2125 retval->distance_y = op2->y - y;
2126
2127 }
2128 retval->part = NULL; 2153 retval->part = NULL;
2129 retval->distance = isqrt(retval->distance_x*retval->distance_x + retval->distance_y*retval->distance_y); 2154 retval->distance = isqrt(retval->distance_x*retval->distance_x + retval->distance_y*retval->distance_y);
2130 retval->direction = find_dir_2(-retval->distance_x, -retval->distance_y); 2155 retval->direction = find_dir_2(-retval->distance_x, -retval->distance_y);
2156 }
2131} 2157}
2132 2158
2133/* Returns true of op1 and op2 are effectively on the same map 2159/* Returns true of op1 and op2 are effectively on the same map
2134 * (as related to map tiling). Note that this looks for a path from 2160 * (as related to map tiling). Note that this looks for a path from
2135 * op1 to op2, so if the tiled maps are assymetric and op2 has a path 2161 * op1 to op2, so if the tiled maps are assymetric and op2 has a path
2138 * and efficient. This could probably be a macro. 2164 * and efficient. This could probably be a macro.
2139 * MSW 2001-08-05 2165 * MSW 2001-08-05
2140 */ 2166 */
2141int on_same_map(object *op1, object *op2) 2167int on_same_map(object *op1, object *op2)
2142{ 2168{
2143 mapstruct *tmp; 2169 int dx, dy;
2144 2170
2145 /* If the object isn't on a map, can't be on the same map, now can it? 2171 return adjacent_map (op1->map, op2->map, &dx, &dy);
2146 * this check also prevents crashes below.
2147 */
2148 if (op1->map == NULL || op2->map == NULL) return FALSE;
2149
2150 /* on same map? */
2151 if (op1->map == op2->map) return TRUE;
2152
2153 /* on adjacent map? */
2154 if (op1->map->tile_map[0] == op2->map) return TRUE;
2155 if (op1->map->tile_map[1] == op2->map) return TRUE;
2156 if (op1->map->tile_map[2] == op2->map) return TRUE;
2157 if (op1->map->tile_map[3] == op2->map) return TRUE;
2158
2159 /* on diagonally adjacent map? */
2160 tmp = op1->map->tile_map[0];
2161 if (tmp != NULL) {
2162 if (tmp->tile_map[1] == op2->map || tmp->tile_map[3] == op2->map) return TRUE;
2163 }
2164
2165 tmp = op1->map->tile_map[1];
2166 if (tmp != NULL) {
2167 if (tmp->tile_map[0] == op2->map || tmp->tile_map[2] == op2->map) return TRUE;
2168 }
2169
2170 tmp = op1->map->tile_map[2];
2171 if (tmp != NULL) {
2172 if (tmp->tile_map[1] == op2->map || tmp->tile_map[3] == op2->map) return TRUE;
2173 }
2174
2175 tmp = op1->map->tile_map[3];
2176 if (tmp != NULL) {
2177 if (tmp->tile_map[0] == op2->map || tmp->tile_map[2] == op2->map) return TRUE;
2178 }
2179
2180 return FALSE;
2181} 2172}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines