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

Comparing deliantra/server/common/los.C (file contents):
Revision 1.2 by root, Tue Aug 29 08:01:35 2006 UTC vs.
Revision 1.14 by root, Mon Dec 25 14:54:44 2006 UTC

1/*
2 * static char *rcsid_los_c =
3 * "$Id: los.C,v 1.2 2006/08/29 08:01:35 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 22*/
28 23
29/* Nov 95 - inserted USE_LIGHTING code stuff in here - b.t. */ 24/* Nov 95 - inserted USE_LIGHTING code stuff in here - b.t. */
30 25
31#include <global.h> 26#include <global.h>
40 * .4 or less lets you see through walls. .5 is about right. 35 * .4 or less lets you see through walls. .5 is about right.
41 */ 36 */
42 37
43#define SPACE_BLOCK 0.5 38#define SPACE_BLOCK 0.5
44 39
45typedef struct blstr { 40typedef struct blstr
41{
46 int x[4],y[4]; 42 int x[4], y[4];
47 int index; 43 int index;
48} blocks; 44} blocks;
49 45
50blocks block[MAP_CLIENT_X][MAP_CLIENT_Y]; 46blocks block[MAP_CLIENT_X][MAP_CLIENT_Y];
51 47
52static void expand_lighted_sight(object *op); 48static void expand_lighted_sight (object *op);
53 49
54/* 50/*
55 * Used to initialise the array used by the LOS routines. 51 * Used to initialise the array used by the LOS routines.
56 * What this sets if that x,y blocks the view of bx,by 52 * What this sets if that x,y blocks the view of bx,by
57 * This then sets up a relation - for example, something 53 * This then sets up a relation - for example, something
59 * etc. So when we check 5,4 and find it block, we have 55 * etc. So when we check 5,4 and find it block, we have
60 * the data to know that 5,3 and 5,2 and 5,1 should also 56 * the data to know that 5,3 and 5,2 and 5,1 should also
61 * be blocked. 57 * be blocked.
62 */ 58 */
63 59
60static void
64static void set_block(int x, int y, int bx, int by) { 61set_block (int x, int y, int bx, int by)
62{
65 int index=block[x][y].index,i; 63 int index = block[x][y].index, i;
66 64
67 /* Due to flipping, we may get duplicates - better safe than sorry. 65 /* Due to flipping, we may get duplicates - better safe than sorry.
68 */ 66 */
69 for (i=0; i<index; i++) { 67 for (i = 0; i < index; i++)
68 {
70 if (block[x][y].x[i] == bx && block[x][y].y[i] == by) return; 69 if (block[x][y].x[i] == bx && block[x][y].y[i] == by)
70 return;
71 } 71 }
72 72
73 block[x][y].x[index]=bx; 73 block[x][y].x[index] = bx;
74 block[x][y].y[index]=by; 74 block[x][y].y[index] = by;
75 block[x][y].index++; 75 block[x][y].index++;
76#ifdef LOS_DEBUG 76#ifdef LOS_DEBUG
77 LOG(llevDebug, "setblock: added %d %d -> %d %d (%d)\n", x, y, bx, by, 77 LOG (llevDebug, "setblock: added %d %d -> %d %d (%d)\n", x, y, bx, by, block[x][y].index);
78 block[x][y].index);
79#endif 78#endif
80} 79}
81 80
82/* 81/*
83 * initialises the array used by the LOS routines. 82 * initialises the array used by the LOS routines.
87 * these spaces could possibly get blocked, since these 86 * these spaces could possibly get blocked, since these
88 * are the only ones further out that are still possibly in the 87 * are the only ones further out that are still possibly in the
89 * sightline. 88 * sightline.
90 */ 89 */
91 90
91void
92void init_block(void) { 92init_block (void)
93{
93 int x,y, dx, dy, i; 94 int x, y, dx, dy, i;
94 static int block_x[3] = {-1, -1, 0}, block_y[3] = {-1, 0, -1}; 95 static int block_x[3] = { -1, -1, 0 }, block_y[3] =
96 {
97 -1, 0, -1};
95 98
96 for(x=0;x<MAP_CLIENT_X;x++) 99 for (x = 0; x < MAP_CLIENT_X; x++)
97 for(y=0;y<MAP_CLIENT_Y;y++) { 100 for (y = 0; y < MAP_CLIENT_Y; y++)
101 {
98 block[x][y].index=0; 102 block[x][y].index = 0;
99 } 103 }
100 104
101 105
102 /* The table should be symmetric, so only do the upper left 106 /* The table should be symmetric, so only do the upper left
103 * quadrant - makes the processing easier. 107 * quadrant - makes the processing easier.
104 */ 108 */
105 for (x=1; x<=MAP_CLIENT_X/2; x++) { 109 for (x = 1; x <= MAP_CLIENT_X / 2; x++)
110 {
106 for (y=1; y<=MAP_CLIENT_Y/2; y++) { 111 for (y = 1; y <= MAP_CLIENT_Y / 2; y++)
112 {
107 for (i=0; i< 3; i++) { 113 for (i = 0; i < 3; i++)
114 {
108 dx = x + block_x[i]; 115 dx = x + block_x[i];
109 dy = y + block_y[i]; 116 dy = y + block_y[i];
110 117
111 /* center space never blocks */ 118 /* center space never blocks */
112 if (x == MAP_CLIENT_X/2 && y == MAP_CLIENT_Y/2) continue; 119 if (x == MAP_CLIENT_X / 2 && y == MAP_CLIENT_Y / 2)
120 continue;
113 121
114 /* If its a straight line, its blocked */ 122 /* If its a straight line, its blocked */
115 if ((dx == x && x == MAP_CLIENT_X/2) || 123 if ((dx == x && x == MAP_CLIENT_X / 2) || (dy == y && y == MAP_CLIENT_Y / 2))
116 (dy==y && y == MAP_CLIENT_Y/2)) { 124 {
117 /* For simplicity, we mirror the coordinates to block the other 125 /* For simplicity, we mirror the coordinates to block the other
118 * quadrants. 126 * quadrants.
119 */ 127 */
120 set_block(x, y, dx, dy); 128 set_block (x, y, dx, dy);
121 if (x == MAP_CLIENT_X/2) { 129 if (x == MAP_CLIENT_X / 2)
130 {
122 set_block(x, MAP_CLIENT_Y - y -1, dx, MAP_CLIENT_Y - dy-1); 131 set_block (x, MAP_CLIENT_Y - y - 1, dx, MAP_CLIENT_Y - dy - 1);
132 }
123 } else if (y == MAP_CLIENT_Y/2) { 133 else if (y == MAP_CLIENT_Y / 2)
134 {
124 set_block(MAP_CLIENT_X - x -1, y, MAP_CLIENT_X - dx - 1, dy); 135 set_block (MAP_CLIENT_X - x - 1, y, MAP_CLIENT_X - dx - 1, dy);
125 } 136 }
137 }
126 } else { 138 else
139 {
127 float d1, r, s,l; 140 float d1, r, s, l;
128 141
129 /* We use the algorihm that found out how close the point 142 /* We use the algorihm that found out how close the point
130 * (x,y) is to the line from dx,dy to the center of the viewable 143 * (x,y) is to the line from dx,dy to the center of the viewable
131 * area. l is the distance from x,y to the line. 144 * area. l is the distance from x,y to the line.
132 * r is more a curiosity - it lets us know what direction (left/right) 145 * r is more a curiosity - it lets us know what direction (left/right)
133 * the line is off 146 * the line is off
134 */ 147 */
135 148
136 d1 = (float) (pow(MAP_CLIENT_X/2 - dx, 2) + pow(MAP_CLIENT_Y/2 - dy,2)); 149 d1 = (float) (pow (MAP_CLIENT_X / 2 - dx, 2.f) + pow (MAP_CLIENT_Y / 2 - dy, 2.f));
137 r = (float)((dy-y)*(dy - MAP_CLIENT_Y/2) - (dx-x)*(MAP_CLIENT_X/2-dx))/d1; 150 r = (float) ((dy - y) * (dy - MAP_CLIENT_Y / 2) - (dx - x) * (MAP_CLIENT_X / 2 - dx)) / d1;
138 s = (float)((dy-y)*(MAP_CLIENT_X/2 - dx ) - (dx-x)*(MAP_CLIENT_Y/2-dy))/d1; 151 s = (float) ((dy - y) * (MAP_CLIENT_X / 2 - dx) - (dx - x) * (MAP_CLIENT_Y / 2 - dy)) / d1;
139 l = FABS(sqrt(d1) * s); 152 l = FABS (sqrt (d1) * s);
140 153
141 if (l <= SPACE_BLOCK) { 154 if (l <= SPACE_BLOCK)
155 {
142 /* For simplicity, we mirror the coordinates to block the other 156 /* For simplicity, we mirror the coordinates to block the other
143 * quadrants. 157 * quadrants.
144 */ 158 */
145 set_block(x,y,dx,dy); 159 set_block (x, y, dx, dy);
146 set_block(MAP_CLIENT_X - x -1, y, MAP_CLIENT_X - dx - 1, dy); 160 set_block (MAP_CLIENT_X - x - 1, y, MAP_CLIENT_X - dx - 1, dy);
147 set_block(x, MAP_CLIENT_Y - y -1, dx, MAP_CLIENT_Y - dy - 1); 161 set_block (x, MAP_CLIENT_Y - y - 1, dx, MAP_CLIENT_Y - dy - 1);
148 set_block(MAP_CLIENT_X -x-1, MAP_CLIENT_Y -y-1, MAP_CLIENT_X - dx-1, MAP_CLIENT_Y - dy-1); 162 set_block (MAP_CLIENT_X - x - 1, MAP_CLIENT_Y - y - 1, MAP_CLIENT_X - dx - 1, MAP_CLIENT_Y - dy - 1);
149 } 163 }
150 } 164 }
151 } 165 }
152 } 166 }
153 } 167 }
162 * the view of the spaces 'behind' it, and those blocked 176 * the view of the spaces 'behind' it, and those blocked
163 * spaces behind it may block other spaces, etc. 177 * spaces behind it may block other spaces, etc.
164 * In this way, the chain of visibility is set. 178 * In this way, the chain of visibility is set.
165 */ 179 */
166 180
181static void
167static void set_wall(object *op,int x,int y) { 182set_wall (object *op, int x, int y)
183{
168 int i; 184 int i;
169 185
170 for(i=0;i<block[x][y].index;i++) { 186 for (i = 0; i < block[x][y].index; i++)
187 {
171 int dx=block[x][y].x[i],dy=block[x][y].y[i],ax,ay; 188 int dx = block[x][y].x[i], dy = block[x][y].y[i], ax, ay;
172 189
173 /* ax, ay are the values as adjusted to be in the 190 /* ax, ay are the values as adjusted to be in the
174 * socket look structure. 191 * socket look structure.
175 */ 192 */
176 ax = dx - (MAP_CLIENT_X - op->contr->socket.mapx)/2; 193 ax = dx - (MAP_CLIENT_X - op->contr->ns->mapx) / 2;
177 ay = dy - (MAP_CLIENT_Y - op->contr->socket.mapy)/2; 194 ay = dy - (MAP_CLIENT_Y - op->contr->ns->mapy) / 2;
178 195
179 if (ax < 0 || ax>=op->contr->socket.mapx || 196 if (ax < 0 || ax >= op->contr->ns->mapx || ay < 0 || ay >= op->contr->ns->mapy)
180 ay < 0 || ay>=op->contr->socket.mapy) continue; 197 continue;
181#if 0 198#if 0
182 LOG(llevDebug, "blocked %d %d -> %d %d\n", 199 LOG (llevDebug, "blocked %d %d -> %d %d\n", dx, dy, ax, ay);
183 dx, dy, ax, ay);
184#endif 200#endif
185 /* we need to adjust to the fact that the socket 201 /* we need to adjust to the fact that the socket
186 * code wants the los to start from the 0,0 202 * code wants the los to start from the 0,0
187 * and not be relative to middle of los array. 203 * and not be relative to middle of los array.
188 */ 204 */
189 op->contr->blocked_los[ax][ay]=100; 205 op->contr->blocked_los[ax][ay] = 100;
190 set_wall(op,dx,dy); 206 set_wall (op, dx, dy);
191 } 207 }
192} 208}
193 209
194/* 210/*
195 * Used to initialise the array used by the LOS routines. 211 * Used to initialise the array used by the LOS routines.
196 * op is the object, x and y values based on MAP_CLIENT_X and Y. 212 * op is the object, x and y values based on MAP_CLIENT_X and Y.
197 * this is because they index the blocked[][] arrays. 213 * this is because they index the blocked[][] arrays.
198 */ 214 */
199 215
216static void
200static void check_wall(object *op,int x,int y) { 217check_wall (object *op, int x, int y)
218{
201 int ax, ay; 219 int ax, ay;
202 220
203 if(!block[x][y].index) 221 if (!block[x][y].index)
204 return; 222 return;
205 223
206 /* ax, ay are coordinates as indexed into the look window */ 224 /* ax, ay are coordinates as indexed into the look window */
207 ax = x - (MAP_CLIENT_X - op->contr->socket.mapx)/2; 225 ax = x - (MAP_CLIENT_X - op->contr->ns->mapx) / 2;
208 ay = y - (MAP_CLIENT_Y - op->contr->socket.mapy)/2; 226 ay = y - (MAP_CLIENT_Y - op->contr->ns->mapy) / 2;
209 227
210 /* If the converted coordinates are outside the viewable 228 /* If the converted coordinates are outside the viewable
211 * area for the client, return now. 229 * area for the client, return now.
212 */ 230 */
213 if (ax < 0 || ay < 0 || ax >= op->contr->socket.mapx || ay >= op->contr->socket.mapy) 231 if (ax < 0 || ay < 0 || ax >= op->contr->ns->mapx || ay >= op->contr->ns->mapy)
214 return; 232 return;
215 233
216#if 0 234#if 0
217 LOG(llevDebug, "check_wall, ax,ay=%d, %d x,y = %d, %d blocksview = %d, %d\n", 235 LOG (llevDebug, "check_wall, ax,ay=%d, %d x,y = %d, %d blocksview = %d, %d\n",
218 ax, ay, x, y, op->x + x - MAP_CLIENT_X/2, op->y + y - MAP_CLIENT_Y/2); 236 ax, ay, x, y, op->x + x - MAP_CLIENT_X / 2, op->y + y - MAP_CLIENT_Y / 2);
219#endif 237#endif
220 238
221 /* If this space is already blocked, prune the processing - presumably 239 /* If this space is already blocked, prune the processing - presumably
222 * whatever has set this space to be blocked has done the work and already 240 * whatever has set this space to be blocked has done the work and already
223 * done the dependency chain. 241 * done the dependency chain.
224 */ 242 */
225 if (op->contr->blocked_los[ax][ay] == 100) return; 243 if (op->contr->blocked_los[ax][ay] == 100)
244 return;
226 245
227 246
228 if(get_map_flags(op->map, NULL, 247 if (get_map_flags (op->map, NULL, op->x + x - MAP_CLIENT_X / 2, op->y + y - MAP_CLIENT_Y / 2, NULL, NULL) & (P_BLOCKSVIEW | P_OUT_OF_MAP))
229 op->x + x - MAP_CLIENT_X/2, op->y + y - MAP_CLIENT_Y/2,
230 NULL, NULL) & (P_BLOCKSVIEW | P_OUT_OF_MAP))
231 set_wall(op,x,y); 248 set_wall (op, x, y);
232} 249}
233 250
234/* 251/*
235 * Clears/initialises the los-array associated to the player 252 * Clears/initialises the los-array associated to the player
236 * controlling the object. 253 * controlling the object.
237 */ 254 */
238 255
256void
239void clear_los(object *op) { 257clear_los (object *op)
258{
240 /* This is safer than using the socket->mapx, mapy because 259 /* This is safer than using the ns->mapx, mapy because
241 * we index the blocked_los as a 2 way array, so clearing 260 * we index the blocked_los as a 2 way array, so clearing
242 * the first z spaces may not not cover the spaces we are 261 * the first z spaces may not not cover the spaces we are
243 * actually going to use 262 * actually going to use
244 */ 263 */
245 (void)memset((void *) op->contr->blocked_los,0, 264 (void) memset ((void *) op->contr->blocked_los, 0, MAP_CLIENT_X * MAP_CLIENT_Y);
246 MAP_CLIENT_X * MAP_CLIENT_Y);
247} 265}
248 266
249/* 267/*
250 * expand_sight goes through the array of what the given player is 268 * expand_sight goes through the array of what the given player is
251 * able to see, and expands the visible area a bit, so the player will, 269 * able to see, and expands the visible area a bit, so the player will,
252 * to a certain degree, be able to see into corners. 270 * to a certain degree, be able to see into corners.
253 * This is somewhat suboptimal, would be better to improve the formula. 271 * This is somewhat suboptimal, would be better to improve the formula.
254 */ 272 */
255 273
274static void
256static void expand_sight(object *op) 275expand_sight (object *op)
257{ 276{
258 int i,x,y, dx, dy; 277 int i, x, y, dx, dy;
259 278
260 for(x=1;x<op->contr->socket.mapx-1;x++) /* loop over inner squares */ 279 for (x = 1; x < op->contr->ns->mapx - 1; x++) /* loop over inner squares */
261 for(y=1;y<op->contr->socket.mapy-1;y++) { 280 for (y = 1; y < op->contr->ns->mapy - 1; y++)
281 {
262 if (!op->contr->blocked_los[x][y] && 282 if (!op->contr->blocked_los[x][y] &&
263 !(get_map_flags(op->map,NULL, 283 !(get_map_flags (op->map, NULL,
264 op->x-op->contr->socket.mapx/2+x, 284 op->x - op->contr->ns->mapx / 2 + x,
265 op->y-op->contr->socket.mapy/2+y, 285 op->y - op->contr->ns->mapy / 2 + y, NULL, NULL) & (P_BLOCKSVIEW | P_OUT_OF_MAP)))
266 NULL, NULL) & (P_BLOCKSVIEW | P_OUT_OF_MAP))) { 286 {
267 287
268 for(i=1;i<=8;i+=1) { /* mark all directions */ 288 for (i = 1; i <= 8; i += 1)
289 { /* mark all directions */
269 dx = x + freearr_x[i]; 290 dx = x + freearr_x[i];
270 dy = y + freearr_y[i]; 291 dy = y + freearr_y[i];
271 if(op->contr->blocked_los[dx][dy] > 0) /* for any square blocked */ 292 if (op->contr->blocked_los[dx][dy] > 0) /* for any square blocked */
272 op->contr->blocked_los[dx][dy]= -1; 293 op->contr->blocked_los[dx][dy] = -1;
273 } 294 }
274 } 295 }
275 } 296 }
276 297
277 if(MAP_DARKNESS(op->map)>0) /* player is on a dark map */ 298 if (op->map->darkness > 0) /* player is on a dark map */
278 expand_lighted_sight(op); 299 expand_lighted_sight (op);
279 300
280 301
281 /* clear mark squares */ 302 /* clear mark squares */
282 for (x = 0; x < op->contr->socket.mapx; x++) 303 for (x = 0; x < op->contr->ns->mapx; x++)
283 for (y = 0; y < op->contr->socket.mapy; y++) 304 for (y = 0; y < op->contr->ns->mapy; y++)
284 if (op->contr->blocked_los[x][y] < 0) 305 if (op->contr->blocked_los[x][y] < 0)
285 op->contr->blocked_los[x][y] = 0; 306 op->contr->blocked_los[x][y] = 0;
286} 307}
287 308
288 309
289 310
290 311
292 * This is a trivial function now days, but it used to 313 * This is a trivial function now days, but it used to
293 * be a bit longer. Probably better for callers to just 314 * be a bit longer. Probably better for callers to just
294 * check the op->glow_radius instead of calling this. 315 * check the op->glow_radius instead of calling this.
295 */ 316 */
296 317
318int
297int has_carried_lights(const object *op) { 319has_carried_lights (const object *op)
320{
298 /* op may glow! */ 321 /* op may glow! */
299 if(op->glow_radius>0) return 1; 322 if (op->glow_radius > 0)
300
301 return 0; 323 return 1;
324
325 return 0;
302} 326}
303 327
328static void
304static void expand_lighted_sight(object *op) 329expand_lighted_sight (object *op)
305{ 330{
306 int x,y,darklevel,ax,ay, basex, basey, mflags, light, x1, y1; 331 int x, y, darklevel, ax, ay, basex, basey, mflags, light, x1, y1;
307 mapstruct *m=op->map; 332 maptile *m = op->map;
308 sint16 nx, ny; 333 sint16 nx, ny;
309
310 darklevel = MAP_DARKNESS(m);
311 334
335 darklevel = m->darkness;
336
312 /* If the player can see in the dark, lower the darklevel for him */ 337 /* If the player can see in the dark, lower the darklevel for him */
313 if(QUERY_FLAG(op,FLAG_SEE_IN_DARK)) darklevel -= 2; 338 if (QUERY_FLAG (op, FLAG_SEE_IN_DARK))
339 darklevel -= 2;
314 340
315 /* add light, by finding all (non-null) nearby light sources, then 341 /* add light, by finding all (non-null) nearby light sources, then
316 * mark those squares specially. If the darklevel<1, there is no 342 * mark those squares specially. If the darklevel<1, there is no
317 * reason to do this, so we skip this function 343 * reason to do this, so we skip this function
318 */ 344 */
319 345
320 if(darklevel<1) return; 346 if (darklevel < 1)
347 return;
321 348
322 /* Do a sanity check. If not valid, some code below may do odd 349 /* Do a sanity check. If not valid, some code below may do odd
323 * things. 350 * things.
324 */ 351 */
325 if (darklevel > MAX_DARKNESS) { 352 if (darklevel > MAX_DARKNESS)
353 {
326 LOG(llevError,"Map darkness for %s on %s is too high (%d)\n", 354 LOG (llevError, "Map darkness for %s on %s is too high (%d)\n", &op->name, op->map->path, darklevel);
327 op->name, op->map->path, darklevel);
328 darklevel = MAX_DARKNESS; 355 darklevel = MAX_DARKNESS;
329 } 356 }
330 357
331 /* First, limit player furthest (unlighted) vision */ 358 /* First, limit player furthest (unlighted) vision */
332 for (x = 0; x < op->contr->socket.mapx; x++) 359 for (x = 0; x < op->contr->ns->mapx; x++)
333 for (y = 0; y < op->contr->socket.mapy; y++) 360 for (y = 0; y < op->contr->ns->mapy; y++)
334 if(op->contr->blocked_los[x][y]!=100) 361 if (op->contr->blocked_los[x][y] != 100)
335 op->contr->blocked_los[x][y]= MAX_LIGHT_RADII; 362 op->contr->blocked_los[x][y] = MAX_LIGHT_RADII;
336 363
337 /* the spaces[] darkness value contains the information we need. 364 /* the spaces[] darkness value contains the information we need.
338 * Only process the area of interest. 365 * Only process the area of interest.
339 * the basex, basey values represent the position in the op->contr->blocked_los 366 * the basex, basey values represent the position in the op->contr->blocked_los
340 * array. Its easier to just increment them here (and start with the right 367 * array. Its easier to just increment them here (and start with the right
341 * value) than to recalculate them down below. 368 * value) than to recalculate them down below.
342 */ 369 */
343 for (x=(op->x - op->contr->socket.mapx/2 - MAX_LIGHT_RADII), basex=-MAX_LIGHT_RADII; 370 for (x = (op->x - op->contr->ns->mapx / 2 - MAX_LIGHT_RADII), basex = -MAX_LIGHT_RADII;
344 x <= (op->x + op->contr->socket.mapx/2 + MAX_LIGHT_RADII); x++, basex++) { 371 x <= (op->x + op->contr->ns->mapx / 2 + MAX_LIGHT_RADII); x++, basex++)
372 {
345 373
346 for (y=(op->y - op->contr->socket.mapy/2 - MAX_LIGHT_RADII), basey=-MAX_LIGHT_RADII; 374 for (y = (op->y - op->contr->ns->mapy / 2 - MAX_LIGHT_RADII), basey = -MAX_LIGHT_RADII;
347 y <= (op->y + op->contr->socket.mapy/2 + MAX_LIGHT_RADII); y++, basey++) { 375 y <= (op->y + op->contr->ns->mapy / 2 + MAX_LIGHT_RADII); y++, basey++)
376 {
348 m = op->map; 377 m = op->map;
349 nx = x; 378 nx = x;
350 ny = y; 379 ny = y;
351 380
352 mflags = get_map_flags(m, &m, nx, ny, &nx, &ny); 381 mflags = get_map_flags (m, &m, nx, ny, &nx, &ny);
353 382
354 if (mflags & P_OUT_OF_MAP) continue; 383 if (mflags & P_OUT_OF_MAP)
384 continue;
355 385
356 /* This space is providing light, so we need to brighten up the 386 /* This space is providing light, so we need to brighten up the
357 * spaces around here. 387 * spaces around here.
358 */ 388 */
359 light = GET_MAP_LIGHT(m, nx, ny); 389 light = GET_MAP_LIGHT (m, nx, ny);
360 if (light != 0) { 390 if (light != 0)
391 {
361#if 0 392#if 0
362 LOG(llevDebug, "expand_lighted_sight: Found light at x=%d, y=%d, basex=%d, basey=%d\n", 393 LOG (llevDebug, "expand_lighted_sight: Found light at x=%d, y=%d, basex=%d, basey=%d\n", x, y, basex, basey);
363 x, y, basex, basey);
364#endif 394#endif
365 for (ax=basex - light; ax<=basex+light; ax++) { 395 for (ax = basex - light; ax <= basex + light; ax++)
396 {
366 if (ax<0 || ax>=op->contr->socket.mapx) continue; 397 if (ax < 0 || ax >= op->contr->ns->mapx)
398 continue;
367 for (ay=basey - light; ay<=basey+light; ay++) { 399 for (ay = basey - light; ay <= basey + light; ay++)
400 {
368 if (ay<0 || ay>=op->contr->socket.mapy) continue; 401 if (ay < 0 || ay >= op->contr->ns->mapy)
402 continue;
369 403
370 /* If the space is fully blocked, do nothing. Otherwise, we 404 /* If the space is fully blocked, do nothing. Otherwise, we
371 * brighten the space. The further the light is away from the 405 * brighten the space. The further the light is away from the
372 * source (basex-x), the less effect it has. Though light used 406 * source (basex-x), the less effect it has. Though light used
373 * to dim in a square manner, it now dims in a circular manner 407 * to dim in a square manner, it now dims in a circular manner
374 * using the the pythagorean theorem. glow_radius still 408 * using the the pythagorean theorem. glow_radius still
375 * represents the radius 409 * represents the radius
376 */ 410 */
377 if(op->contr->blocked_los[ax][ay]!=100) { 411 if (op->contr->blocked_los[ax][ay] != 100)
378 x1 = abs(basex-ax)*abs(basex-ax); 412 {
379 y1 = abs(basey-ay)*abs(basey-ay); 413 x1 = abs (basex - ax) * abs (basex - ax);
380 if (light > 0) op->contr->blocked_los[ax][ay]-= MAX((light - isqrt(x1 + y1)), 0); 414 y1 = abs (basey - ay) * abs (basey - ay);
381 if (light < 0) op->contr->blocked_los[ax][ay]-= MIN((light + isqrt(x1 + y1)), 0); 415 if (light > 0)
382 } 416 op->contr->blocked_los[ax][ay] -= MAX ((light - isqrt (x1 + y1)), 0);
417 if (light < 0)
418 op->contr->blocked_los[ax][ay] -= MIN ((light + isqrt (x1 + y1)), 0);
419 }
383 } /* for ay */ 420 } /* for ay */
384 } /* for ax */ 421 } /* for ax */
385 } /* if this space is providing light */ 422 } /* if this space is providing light */
386 } /* for y */ 423 } /* for y */
387 } /* for x */ 424 } /* for x */
388 425
389 /* Outdoor should never really be completely pitch black dark like 426 /* Outdoor should never really be completely pitch black dark like
390 * a dungeon, so let the player at least see a little around themselves 427 * a dungeon, so let the player at least see a little around themselves
391 */ 428 */
392 if (op->map->outdoor && darklevel > (MAX_DARKNESS - 3)) { 429 if (op->map->outdoor && darklevel > (MAX_DARKNESS - 3))
430 {
393 if (op->contr->blocked_los[op->contr->socket.mapx/2][op->contr->socket.mapy/2] > (MAX_DARKNESS-3)) 431 if (op->contr->blocked_los[op->contr->ns->mapx / 2][op->contr->ns->mapy / 2] > (MAX_DARKNESS - 3))
394 op->contr->blocked_los[op->contr->socket.mapx/2][op->contr->socket.mapy/2] = MAX_DARKNESS - 3; 432 op->contr->blocked_los[op->contr->ns->mapx / 2][op->contr->ns->mapy / 2] = MAX_DARKNESS - 3;
395 433
396 for (x=-1; x<=1; x++) 434 for (x = -1; x <= 1; x++)
397 for (y=-1; y<=1; y++) { 435 for (y = -1; y <= 1; y++)
436 {
398 if (op->contr->blocked_los[x + op->contr->socket.mapx/2][y + op->contr->socket.mapy/2] > (MAX_DARKNESS-2)) 437 if (op->contr->blocked_los[x + op->contr->ns->mapx / 2][y + op->contr->ns->mapy / 2] > (MAX_DARKNESS - 2))
399 op->contr->blocked_los[x + op->contr->socket.mapx/2][y + op->contr->socket.mapy/2] = MAX_DARKNESS - 2; 438 op->contr->blocked_los[x + op->contr->ns->mapx / 2][y + op->contr->ns->mapy / 2] = MAX_DARKNESS - 2;
400 } 439 }
401 } 440 }
402 /* grant some vision to the player, based on the darklevel */ 441 /* grant some vision to the player, based on the darklevel */
403 for(x=darklevel-MAX_DARKNESS; x<MAX_DARKNESS + 1 -darklevel; x++) 442 for (x = darklevel - MAX_DARKNESS; x < MAX_DARKNESS + 1 - darklevel; x++)
404 for(y=darklevel-MAX_DARKNESS; y<MAX_DARKNESS + 1 -darklevel; y++) 443 for (y = darklevel - MAX_DARKNESS; y < MAX_DARKNESS + 1 - darklevel; y++)
405 if(!(op->contr->blocked_los[x+op->contr->socket.mapx/2][y+op->contr->socket.mapy/2]==100)) 444 if (!(op->contr->blocked_los[x + op->contr->ns->mapx / 2][y + op->contr->ns->mapy / 2] == 100))
406 op->contr->blocked_los[x+op->contr->socket.mapx/2][y+op->contr->socket.mapy/2]-= 445 op->contr->blocked_los[x + op->contr->ns->mapx / 2][y + op->contr->ns->mapy / 2] -=
407 MAX(0,6 -darklevel - MAX(abs(x),abs(y))); 446 MAX (0, 6 - darklevel - MAX (abs (x), abs (y)));
408} 447}
409 448
410/* blinded_sight() - sets all veiwable squares to blocked except 449/* blinded_sight() - sets all veiwable squares to blocked except
411 * for the one the central one that the player occupies. A little 450 * for the one the central one that the player occupies. A little
412 * odd that you can see yourself (and what your standing on), but 451 * odd that you can see yourself (and what your standing on), but
413 * really need for any reasonable game play. 452 * really need for any reasonable game play.
414 */ 453 */
415 454
455static void
416static void blinded_sight(object *op) { 456blinded_sight (object *op)
457{
417 int x,y; 458 int x, y;
418 459
419 for (x = 0; x < op->contr->socket.mapx; x++) 460 for (x = 0; x < op->contr->ns->mapx; x++)
420 for (y = 0; y < op->contr->socket.mapy; y++) 461 for (y = 0; y < op->contr->ns->mapy; y++)
421 op->contr->blocked_los[x][y] = 100; 462 op->contr->blocked_los[x][y] = 100;
422 463
423 op->contr->blocked_los[ op->contr->socket.mapx/2][ op->contr->socket.mapy/2] = 0; 464 op->contr->blocked_los[op->contr->ns->mapx / 2][op->contr->ns->mapy / 2] = 0;
424} 465}
425 466
426/* 467/*
427 * update_los() recalculates the array which specifies what is 468 * update_los() recalculates the array which specifies what is
428 * visible for the given player-object. 469 * visible for the given player-object.
429 */ 470 */
430 471
472void
431void update_los(object *op) { 473update_los (object *op)
474{
432 int dx = op->contr->socket.mapx/2, dy = op->contr->socket.mapy/2, x, y; 475 int dx = op->contr->ns->mapx / 2, dy = op->contr->ns->mapy / 2, x, y;
433 476
434 if(QUERY_FLAG(op,FLAG_REMOVED)) 477 if (QUERY_FLAG (op, FLAG_REMOVED))
435 return; 478 return;
436 479
437 clear_los(op); 480 clear_los (op);
438 if(QUERY_FLAG(op,FLAG_WIZ) /* ||XRAYS(op) */) 481 if (QUERY_FLAG (op, FLAG_WIZ) /* ||XRAYS(op) */ )
439 return; 482 return;
440 483
441 /* For larger maps, this is more efficient than the old way which 484 /* For larger maps, this is more efficient than the old way which
442 * used the chaining of the block array. Since many space views could 485 * used the chaining of the block array. Since many space views could
443 * be blocked by different spaces in front, this mean that a lot of spaces 486 * be blocked by different spaces in front, this mean that a lot of spaces
444 * could be examined multile times, as each path would be looked at. 487 * could be examined multile times, as each path would be looked at.
445 */ 488 */
446 for (x=(MAP_CLIENT_X - op->contr->socket.mapx)/2 - 1; x<(MAP_CLIENT_X + op->contr->socket.mapx)/2 + 1; x++) 489 for (x = (MAP_CLIENT_X - op->contr->ns->mapx) / 2 - 1; x < (MAP_CLIENT_X + op->contr->ns->mapx) / 2 + 1; x++)
447 for (y=(MAP_CLIENT_Y - op->contr->socket.mapy)/2 - 1; y<(MAP_CLIENT_Y + op->contr->socket.mapy)/2 + 1; y++) 490 for (y = (MAP_CLIENT_Y - op->contr->ns->mapy) / 2 - 1; y < (MAP_CLIENT_Y + op->contr->ns->mapy) / 2 + 1; y++)
448 check_wall(op, x, y); 491 check_wall (op, x, y);
449 492
450 493
451 /* do the los of the player. 3 (potential) cases */ 494 /* do the los of the player. 3 (potential) cases */
452 if(QUERY_FLAG(op,FLAG_BLIND)) /* player is blind */ 495 if (QUERY_FLAG (op, FLAG_BLIND)) /* player is blind */
453 blinded_sight(op); 496 blinded_sight (op);
454 else 497 else
455 expand_sight(op); 498 expand_sight (op);
456 499
457 if (QUERY_FLAG(op,FLAG_XRAYS)) { 500 if (QUERY_FLAG (op, FLAG_XRAYS))
501 {
458 int x, y; 502 int x, y;
503
459 for (x = -2; x <= 2; x++) 504 for (x = -2; x <= 2; x++)
460 for (y = -2; y <= 2; y++) 505 for (y = -2; y <= 2; y++)
461 op->contr->blocked_los[dx + x][dy + y] = 0; 506 op->contr->blocked_los[dx + x][dy + y] = 0;
462 } 507 }
463} 508}
464 509
465/* update all_map_los is like update_all_los below, 510/* update all_map_los is like update_all_los below,
466 * but updates everyone on the map, no matter where they 511 * but updates everyone on the map, no matter where they
467 * are. This generally should not be used, as a per 512 * are. This generally should not be used, as a per
468 * specific map change doesn't make much sense when tiling 513 * specific map change doesn't make much sense when tiling
469 * is considered (lowering darkness would certainly be a 514 * is considered (lowering darkness would certainly be a
470 * strange effect if done on a tile map, as it makes 515 * strange effect if done on a tile map, as it makes
471 * the distinction between maps much more obvious to the 516 * the distinction between maps much more obvious to the
472 * players, which is should not be. 517 * players, which is should not be.
473 * Currently, this function is called from the 518 * Currently, this function is called from the
474 * change_map_light function 519 * change_map_light function
475 */ 520 */
521void
476void update_all_map_los(mapstruct *map) { 522update_all_map_los (maptile *map)
477 player *pl; 523{
478 524 for_all_players (pl)
479 for(pl=first_player;pl!=NULL;pl=pl->next) { 525 if (pl->ob && pl->ob->map == map)
480 if(pl->ob->map==map)
481 pl->do_los=1; 526 pl->do_los = 1;
482 }
483} 527}
484
485 528
486/* 529/*
487 * This function makes sure that update_los() will be called for all 530 * This function makes sure that update_los() will be called for all
488 * players on the given map within the next frame. 531 * players on the given map within the next frame.
489 * It is triggered by removal or inserting of objects which blocks 532 * It is triggered by removal or inserting of objects which blocks
493 * means that just being on the same map is not sufficient - the 536 * means that just being on the same map is not sufficient - the
494 * space that changes must be withing your viewable area. 537 * space that changes must be withing your viewable area.
495 * 538 *
496 * map is the map that changed, x and y are the coordinates. 539 * map is the map that changed, x and y are the coordinates.
497 */ 540 */
498 541void
499void update_all_los(const mapstruct *map, int x, int y) { 542update_all_los (const maptile *map, int x, int y)
500 player *pl; 543{
501 544 for_all_players (pl)
502 for(pl=first_player;pl!=NULL;pl=pl->next) { 545 {
503 /* Player should not have a null map, but do this 546 /* Player should not have a null map, but do this
504 * check as a safety 547 * check as a safety
505 */ 548 */
506 if (!pl->ob->map) continue; 549 if (!pl->ob || !pl->ob->map || !pl->ns)
550 continue;
507 551
508 /* Same map is simple case - see if pl is close enough. 552 /* Same map is simple case - see if pl is close enough.
509 * Note in all cases, we did the check for same map first, 553 * Note in all cases, we did the check for same map first,
510 * and then see if the player is close enough and update 554 * and then see if the player is close enough and update
511 * los if that is the case. If the player is on the 555 * los if that is the case. If the player is on the
512 * corresponding map, but not close enough, then the 556 * corresponding map, but not close enough, then the
513 * player can't be on another map that may be closer, 557 * player can't be on another map that may be closer,
514 * so by setting it up this way, we trim processing 558 * so by setting it up this way, we trim processing
515 * some. 559 * some.
516 */ 560 */
517 if(pl->ob->map==map) { 561 if (pl->ob->map == map)
518 if ((abs(pl->ob->x - x) <= pl->socket.mapx/2) && 562 {
519 (abs(pl->ob->y - y) <= pl->socket.mapy/2)) 563 if ((abs (pl->ob->x - x) <= pl->ns->mapx / 2) && (abs (pl->ob->y - y) <= pl->ns->mapy / 2))
520 pl->do_los=1; 564 pl->do_los = 1;
521 } 565 }
566
522 /* Now we check to see if player is on adjacent 567 /* Now we check to see if player is on adjacent
523 * maps to the one that changed and also within 568 * maps to the one that changed and also within
524 * view. The tile_maps[] could be null, but in that 569 * view. The tile_maps[] could be null, but in that
525 * case it should never match the pl->ob->map, so 570 * case it should never match the pl->ob->map, so
526 * we want ever try to dereference any of the data in it. 571 * we want ever try to dereference any of the data in it.
527 */ 572 *
528
529 /* The logic for 0 and 3 is to see how far the player is 573 * The logic for 0 and 3 is to see how far the player is
530 * from the edge of the map (height/width) - pl->ob->(x,y) 574 * from the edge of the map (height/width) - pl->ob->(x,y)
531 * and to add current position on this map - that gives a 575 * and to add current position on this map - that gives a
532 * distance. 576 * distance.
533 * For 1 and 2, we check to see how far the given 577 * For 1 and 2, we check to see how far the given
534 * coordinate (x,y) is from the corresponding edge, 578 * coordinate (x,y) is from the corresponding edge,
535 * and then add the players location, which gives 579 * and then add the players location, which gives
536 * a distance. 580 * a distance.
537 */ 581 */
538 else if (pl->ob->map == map->tile_map[0]) { 582 else if (pl->ob->map == map->tile_map[0])
539 if ((abs(pl->ob->x - x) <= pl->socket.mapx/2) && 583 {
540 (abs(y + MAP_HEIGHT(map->tile_map[0]) - pl->ob->y) <= pl->socket.mapy/2)) 584 if ((abs (pl->ob->x - x) <= pl->ns->mapx / 2) && (abs (y + map->tile_map[0]->height - pl->ob->y) <= pl->ns->mapy / 2))
541 pl->do_los=1; 585 pl->do_los = 1;
542 } 586 }
543 else if (pl->ob->map == map->tile_map[2]) { 587 else if (pl->ob->map == map->tile_map[2])
544 if ((abs(pl->ob->x - x) <= pl->socket.mapx/2) && 588 {
545 (abs(pl->ob->y + MAP_HEIGHT(map) - y) <= pl->socket.mapy/2)) 589 if ((abs (pl->ob->x - x) <= pl->ns->mapx / 2) && (abs (pl->ob->y + map->height - y) <= pl->ns->mapy / 2))
546 pl->do_los=1; 590 pl->do_los = 1;
547 } 591 }
548 else if (pl->ob->map == map->tile_map[1]) { 592 else if (pl->ob->map == map->tile_map[1])
549 if ((abs(pl->ob->x + MAP_WIDTH(map) - x) <= pl->socket.mapx/2) && 593 {
550 (abs(pl->ob->y - y) <= pl->socket.mapy/2)) 594 if ((abs (pl->ob->x + map->width - x) <= pl->ns->mapx / 2) && (abs (pl->ob->y - y) <= pl->ns->mapy / 2))
551 pl->do_los=1; 595 pl->do_los = 1;
552 } 596 }
553 else if (pl->ob->map == map->tile_map[3]) { 597 else if (pl->ob->map == map->tile_map[3])
554 if ((abs(x + MAP_WIDTH(map->tile_map[3]) - pl->ob->x) <= pl->socket.mapx/2) && 598 {
555 (abs(pl->ob->y - y) <= pl->socket.mapy/2)) 599 if ((abs (x + map->tile_map[3]->width - pl->ob->x) <= pl->ns->mapx / 2) && (abs (pl->ob->y - y) <= pl->ns->mapy / 2))
556 pl->do_los=1; 600 pl->do_los = 1;
557 } 601 }
558 } 602 }
559} 603}
560 604
561/* 605/*
562 * Debug-routine which dumps the array which specifies the visible 606 * Debug-routine which dumps the array which specifies the visible
563 * area of a player. Triggered by the z key in DM mode. 607 * area of a player. Triggered by the z key in DM mode.
564 */ 608 */
565 609void
566void print_los(object *op) { 610print_los (object *op)
611{
567 int x,y; 612 int x, y;
568 char buf[50], buf2[10]; 613 char buf[50], buf2[10];
569 614
570 strcpy(buf," "); 615 strcpy (buf, " ");
616
571 for(x=0;x<op->contr->socket.mapx;x++) { 617 for (x = 0; x < op->contr->ns->mapx; x++)
618 {
572 sprintf(buf2,"%2d",x); 619 sprintf (buf2, "%2d", x);
573 strcat(buf,buf2); 620 strcat (buf, buf2);
574 } 621 }
622
575 new_draw_info(NDI_UNIQUE, 0, op, buf); 623 new_draw_info (NDI_UNIQUE, 0, op, buf);
624
576 for(y=0;y<op->contr->socket.mapy;y++) { 625 for (y = 0; y < op->contr->ns->mapy; y++)
626 {
577 sprintf(buf,"%2d:",y); 627 sprintf (buf, "%2d:", y);
628
578 for(x=0;x<op->contr->socket.mapx;x++) { 629 for (x = 0; x < op->contr->ns->mapx; x++)
630 {
579 sprintf(buf2," %1d",op->contr->blocked_los[x][y]); 631 sprintf (buf2, " %1d", op->contr->blocked_los[x][y]);
580 strcat(buf,buf2); 632 strcat (buf, buf2);
581 } 633 }
634
582 new_draw_info(NDI_UNIQUE, 0, op, buf); 635 new_draw_info (NDI_UNIQUE, 0, op, buf);
583 } 636 }
584} 637}
585 638
586/* 639/*
587 * make_sure_seen: The object is supposed to be visible through walls, thus 640 * make_sure_seen: The object is supposed to be visible through walls, thus
588 * check if any players are nearby, and edit their LOS array. 641 * check if any players are nearby, and edit their LOS array.
589 */ 642 */
590 643
644void
591void make_sure_seen(const object *op) { 645make_sure_seen (const object *op)
592 player *pl; 646{
593 647 for_all_players (pl)
594 for (pl = first_player; pl; pl = pl->next)
595 if (pl->ob->map == op->map && 648 if (pl->ob->map == op->map &&
596 pl->ob->y - pl->socket.mapy/2 <= op->y && 649 pl->ob->y - pl->ns->mapy / 2 <= op->y &&
597 pl->ob->y + pl->socket.mapy/2 >= op->y && 650 pl->ob->y + pl->ns->mapy / 2 >= op->y && pl->ob->x - pl->ns->mapx / 2 <= op->x && pl->ob->x + pl->ns->mapx / 2 >= op->x)
598 pl->ob->x - pl->socket.mapx/2 <= op->x && 651 pl->blocked_los[pl->ns->mapx / 2 + op->x - pl->ob->x][pl->ns->mapy / 2 + op->y - pl->ob->y] = 0;
599 pl->ob->x + pl->socket.mapx/2 >= op->x)
600 pl->blocked_los[pl->socket.mapx/2 + op->x - pl->ob->x]
601 [pl->socket.mapy/2 + op->y - pl->ob->y] = 0;
602} 652}
603 653
604/* 654/*
605 * make_sure_not_seen: The object which is supposed to be visible through 655 * make_sure_not_seen: The object which is supposed to be visible through
606 * walls has just been removed from the map, so update the los of any 656 * walls has just been removed from the map, so update the los of any
607 * players within its range 657 * players within its range
608 */ 658 */
609 659
660void
610void make_sure_not_seen(const object *op) { 661make_sure_not_seen (const object *op)
611 player *pl; 662{
612 for (pl = first_player; pl; pl = pl->next) 663 for_all_players (pl)
613 if (pl->ob->map == op->map && 664 if (pl->ob->map == op->map &&
614 pl->ob->y - pl->socket.mapy/2 <= op->y && 665 pl->ob->y - pl->ns->mapy / 2 <= op->y &&
615 pl->ob->y + pl->socket.mapy/2 >= op->y && 666 pl->ob->y + pl->ns->mapy / 2 >= op->y && pl->ob->x - pl->ns->mapx / 2 <= op->x && pl->ob->x + pl->ns->mapx / 2 >= op->x)
616 pl->ob->x - pl->socket.mapx/2 <= op->x &&
617 pl->ob->x + pl->socket.mapx/2 >= op->x)
618 pl->do_los = 1; 667 pl->do_los = 1;
619} 668}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines