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.1 by elmex, Sun Aug 13 17:16:00 2006 UTC vs.
Revision 1.8 by root, Thu Dec 14 04:30:31 2006 UTC

1/*
2 * static char *rcsid_los_c =
3 * "$Id: los.C,v 1.1 2006/08/13 17:16:00 elmex 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++)
108 dx = x + block_x[i]; 114 {
109 dy = y + block_y[i]; 115 dx = x + block_x[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);
123 } else if (y == MAP_CLIENT_Y/2) { 132 }
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 }
126 } else { 137 }
127 float d1, r, s,l; 138 else
139 {
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 }
154} 168}
155 169
156/* 170/*
157 * Used to initialise the array used by the LOS routines. 171 * Used to initialise the array used by the LOS routines.
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->socket->mapx) / 2;
177 ay = dy - (MAP_CLIENT_Y - op->contr->socket.mapy)/2; 194 ay = dy - (MAP_CLIENT_Y - op->contr->socket->mapy) / 2;
178 195
179 if (ax < 0 || ax>=op->contr->socket.mapx || 196 if (ax < 0 || ax >= op->contr->socket->mapx || ay < 0 || ay >= op->contr->socket->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->socket->mapx) / 2;
208 ay = y - (MAP_CLIENT_Y - op->contr->socket.mapy)/2; 226 ay = y - (MAP_CLIENT_Y - op->contr->socket->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->socket->mapx || ay >= op->contr->socket->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 socket->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->socket->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->socket->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->socket->mapx / 2 + x,
265 op->y-op->contr->socket.mapy/2+y, 285 op->y - op->contr->socket->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 }
295 }
274 } 296 }
275 }
276 297
277 if(MAP_DARKNESS(op->map)>0) /* player is on a dark map */ 298 if (MAP_DARKNESS (op->map) > 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->socket->mapx; x++)
283 for (y = 0; y < op->contr->socket.mapy; y++) 304 for (y = 0; y < op->contr->socket->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 334
310 darklevel = MAP_DARKNESS(m); 335 darklevel = MAP_DARKNESS (m);
311 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)
326 LOG(llevError,"Map darkness for %s on %s is too high (%d)\n", 353 {
327 op->name, op->map->path, darklevel); 354 LOG (llevError, "Map darkness for %s on %s is too high (%d)\n", &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->socket->mapx; x++)
333 for (y = 0; y < op->contr->socket.mapy; y++) 360 for (y = 0; y < op->contr->socket->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->socket->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->socket->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->socket->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->socket->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++)
366 if (ax<0 || ax>=op->contr->socket.mapx) continue; 396 {
397 if (ax < 0 || ax >= op->contr->socket->mapx)
398 continue;
367 for (ay=basey - light; ay<=basey+light; ay++) { 399 for (ay = basey - light; ay <= basey + light; ay++)
368 if (ay<0 || ay>=op->contr->socket.mapy) continue; 400 {
401 if (ay < 0 || ay >= op->contr->socket->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);
383 } /* for ay */ 417 if (light < 0)
384 } /* for ax */ 418 op->contr->blocked_los[ax][ay] -= MIN ((light + isqrt (x1 + y1)), 0);
419 }
420 } /* for ay */
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->socket->mapx / 2][op->contr->socket->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->socket->mapx / 2][op->contr->socket->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->socket->mapx / 2][y + op->contr->socket->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->socket->mapx / 2][y + op->contr->socket->mapy / 2] = MAX_DARKNESS - 2;
439 }
400 } 440 }
401 }
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->socket->mapx / 2][y + op->contr->socket->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->socket->mapx / 2][y + op->contr->socket->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->socket->mapx; x++)
420 for (y = 0; y < op->contr->socket.mapy; y++) 461 for (y = 0; y < op->contr->socket->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->socket->mapx / 2][op->contr->socket->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->socket->mapx / 2, dy = op->contr->socket->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->socket->mapx) / 2 - 1; x < (MAP_CLIENT_X + op->contr->socket->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->socket->mapy) / 2 - 1; y < (MAP_CLIENT_Y + op->contr->socket->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))
458 int x, y; 501 {
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
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)
523{
477 player *pl; 524 player *pl;
478 525
479 for(pl=first_player;pl!=NULL;pl=pl->next) { 526 for (pl = first_player; pl != NULL; pl = pl->next)
527 {
480 if(pl->ob->map==map) 528 if (pl->ob->map == map)
481 pl->do_los=1; 529 pl->do_los = 1;
482 } 530 }
483} 531}
484 532
485 533
486/* 534/*
494 * space that changes must be withing your viewable area. 542 * space that changes must be withing your viewable area.
495 * 543 *
496 * map is the map that changed, x and y are the coordinates. 544 * map is the map that changed, x and y are the coordinates.
497 */ 545 */
498 546
547void
499void update_all_los(const mapstruct *map, int x, int y) { 548update_all_los (const maptile *map, int x, int y)
549{
500 player *pl; 550 player *pl;
501 551
502 for(pl=first_player;pl!=NULL;pl=pl->next) { 552 for (pl = first_player; pl != NULL; pl = pl->next)
553 {
503 /* Player should not have a null map, but do this 554 /* Player should not have a null map, but do this
504 * check as a safety 555 * check as a safety
505 */ 556 */
506 if (!pl->ob->map) continue; 557 if (!pl->ob->map)
558 continue;
507 559
508 /* Same map is simple case - see if pl is close enough. 560 /* Same map is simple case - see if pl is close enough.
509 * Note in all cases, we did the check for same map first, 561 * Note in all cases, we did the check for same map first,
510 * and then see if the player is close enough and update 562 * and then see if the player is close enough and update
511 * los if that is the case. If the player is on the 563 * los if that is the case. If the player is on the
512 * corresponding map, but not close enough, then the 564 * corresponding map, but not close enough, then the
513 * player can't be on another map that may be closer, 565 * player can't be on another map that may be closer,
514 * so by setting it up this way, we trim processing 566 * so by setting it up this way, we trim processing
515 * some. 567 * some.
516 */ 568 */
517 if(pl->ob->map==map) { 569 if (pl->ob->map == map)
518 if ((abs(pl->ob->x - x) <= pl->socket.mapx/2) && 570 {
519 (abs(pl->ob->y - y) <= pl->socket.mapy/2)) 571 if ((abs (pl->ob->x - x) <= pl->socket->mapx / 2) && (abs (pl->ob->y - y) <= pl->socket->mapy / 2))
520 pl->do_los=1; 572 pl->do_los = 1;
521 } 573 }
522 /* Now we check to see if player is on adjacent 574 /* Now we check to see if player is on adjacent
523 * maps to the one that changed and also within 575 * maps to the one that changed and also within
524 * view. The tile_maps[] could be null, but in that 576 * view. The tile_maps[] could be null, but in that
525 * case it should never match the pl->ob->map, so 577 * case it should never match the pl->ob->map, so
526 * we want ever try to dereference any of the data in it. 578 * we want ever try to dereference any of the data in it.
527 */ 579 */
528 580
529 /* The logic for 0 and 3 is to see how far the player is 581 /* 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) 582 * from the edge of the map (height/width) - pl->ob->(x,y)
531 * and to add current position on this map - that gives a 583 * and to add current position on this map - that gives a
532 * distance. 584 * distance.
533 * For 1 and 2, we check to see how far the given 585 * For 1 and 2, we check to see how far the given
534 * coordinate (x,y) is from the corresponding edge, 586 * coordinate (x,y) is from the corresponding edge,
535 * and then add the players location, which gives 587 * and then add the players location, which gives
536 * a distance. 588 * a distance.
537 */ 589 */
538 else if (pl->ob->map == map->tile_map[0]) { 590 else if (pl->ob->map == map->tile_map[0])
539 if ((abs(pl->ob->x - x) <= pl->socket.mapx/2) && 591 {
540 (abs(y + MAP_HEIGHT(map->tile_map[0]) - pl->ob->y) <= pl->socket.mapy/2)) 592 if ((abs (pl->ob->x - x) <= pl->socket->mapx / 2) && (abs (y + MAP_HEIGHT (map->tile_map[0]) - pl->ob->y) <= pl->socket->mapy / 2))
541 pl->do_los=1; 593 pl->do_los = 1;
542 } 594 }
543 else if (pl->ob->map == map->tile_map[2]) { 595 else if (pl->ob->map == map->tile_map[2])
544 if ((abs(pl->ob->x - x) <= pl->socket.mapx/2) && 596 {
545 (abs(pl->ob->y + MAP_HEIGHT(map) - y) <= pl->socket.mapy/2)) 597 if ((abs (pl->ob->x - x) <= pl->socket->mapx / 2) && (abs (pl->ob->y + MAP_HEIGHT (map) - y) <= pl->socket->mapy / 2))
546 pl->do_los=1; 598 pl->do_los = 1;
547 } 599 }
548 else if (pl->ob->map == map->tile_map[1]) { 600 else if (pl->ob->map == map->tile_map[1])
549 if ((abs(pl->ob->x + MAP_WIDTH(map) - x) <= pl->socket.mapx/2) && 601 {
550 (abs(pl->ob->y - y) <= pl->socket.mapy/2)) 602 if ((abs (pl->ob->x + MAP_WIDTH (map) - x) <= pl->socket->mapx / 2) && (abs (pl->ob->y - y) <= pl->socket->mapy / 2))
551 pl->do_los=1; 603 pl->do_los = 1;
552 } 604 }
553 else if (pl->ob->map == map->tile_map[3]) { 605 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) && 606 {
555 (abs(pl->ob->y - y) <= pl->socket.mapy/2)) 607 if ((abs (x + MAP_WIDTH (map->tile_map[3]) - pl->ob->x) <= pl->socket->mapx / 2) && (abs (pl->ob->y - y) <= pl->socket->mapy / 2))
556 pl->do_los=1; 608 pl->do_los = 1;
557 } 609 }
558 } 610 }
559} 611}
560 612
561/* 613/*
562 * Debug-routine which dumps the array which specifies the visible 614 * Debug-routine which dumps the array which specifies the visible
563 * area of a player. Triggered by the z key in DM mode. 615 * area of a player. Triggered by the z key in DM mode.
564 */ 616 */
565 617
618void
566void print_los(object *op) { 619print_los (object *op)
620{
567 int x,y; 621 int x, y;
568 char buf[50], buf2[10]; 622 char buf[50], buf2[10];
569 623
570 strcpy(buf," "); 624 strcpy (buf, " ");
625 for (x = 0; x < op->contr->socket->mapx; x++)
626 {
627 sprintf (buf2, "%2d", x);
628 strcat (buf, buf2);
629 }
630 new_draw_info (NDI_UNIQUE, 0, op, buf);
631 for (y = 0; y < op->contr->socket->mapy; y++)
632 {
633 sprintf (buf, "%2d:", y);
571 for(x=0;x<op->contr->socket.mapx;x++) { 634 for (x = 0; x < op->contr->socket->mapx; x++)
572 sprintf(buf2,"%2d",x); 635 {
573 strcat(buf,buf2); 636 sprintf (buf2, " %1d", op->contr->blocked_los[x][y]);
574 } 637 strcat (buf, buf2);
638 }
575 new_draw_info(NDI_UNIQUE, 0, op, buf); 639 new_draw_info (NDI_UNIQUE, 0, op, buf);
576 for(y=0;y<op->contr->socket.mapy;y++) {
577 sprintf(buf,"%2d:",y);
578 for(x=0;x<op->contr->socket.mapx;x++) {
579 sprintf(buf2," %1d",op->contr->blocked_los[x][y]);
580 strcat(buf,buf2);
581 }
582 new_draw_info(NDI_UNIQUE, 0, op, buf);
583 } 640 }
584} 641}
585 642
586/* 643/*
587 * make_sure_seen: The object is supposed to be visible through walls, thus 644 * 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. 645 * check if any players are nearby, and edit their LOS array.
589 */ 646 */
590 647
648void
591void make_sure_seen(const object *op) { 649make_sure_seen (const object *op)
650{
592 player *pl; 651 player *pl;
593 652
594 for (pl = first_player; pl; pl = pl->next) 653 for (pl = first_player; pl; pl = pl->next)
595 if (pl->ob->map == op->map && 654 if (pl->ob->map == op->map &&
596 pl->ob->y - pl->socket.mapy/2 <= op->y && 655 pl->ob->y - pl->socket->mapy / 2 <= op->y &&
597 pl->ob->y + pl->socket.mapy/2 >= op->y && 656 pl->ob->y + pl->socket->mapy / 2 >= op->y && pl->ob->x - pl->socket->mapx / 2 <= op->x && pl->ob->x + pl->socket->mapx / 2 >= op->x)
598 pl->ob->x - pl->socket.mapx/2 <= op->x && 657 pl->blocked_los[pl->socket->mapx / 2 + op->x - pl->ob->x][pl->socket->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} 658}
603 659
604/* 660/*
605 * make_sure_not_seen: The object which is supposed to be visible through 661 * 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 662 * walls has just been removed from the map, so update the los of any
607 * players within its range 663 * players within its range
608 */ 664 */
609 665
666void
610void make_sure_not_seen(const object *op) { 667make_sure_not_seen (const object *op)
668{
611 player *pl; 669 player *pl;
670
612 for (pl = first_player; pl; pl = pl->next) 671 for (pl = first_player; pl; pl = pl->next)
613 if (pl->ob->map == op->map && 672 if (pl->ob->map == op->map &&
614 pl->ob->y - pl->socket.mapy/2 <= op->y && 673 pl->ob->y - pl->socket->mapy / 2 <= op->y &&
615 pl->ob->y + pl->socket.mapy/2 >= op->y && 674 pl->ob->y + pl->socket->mapy / 2 >= op->y && pl->ob->x - pl->socket->mapx / 2 <= op->x && pl->ob->x + pl->socket->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; 675 pl->do_los = 1;
619} 676}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines