1 | /* |
1 | /* |
2 | * static char *rcsid_main_c = |
2 | * static char *rcsid_main_c = |
3 | * "$Id: main.C,v 1.13 2006/08/29 07:34:00 root Exp $"; |
3 | * "$Id: main.C,v 1.16 2006/08/30 16:47:10 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 | |
… | |
… | |
140 | sprintf(buf,"Welcome to Crossfire, v%s!",VERSION); |
140 | sprintf(buf,"Welcome to Crossfire, v%s!",VERSION); |
141 | new_draw_info(NDI_UNIQUE, 0,op,buf); |
141 | new_draw_info(NDI_UNIQUE, 0,op,buf); |
142 | new_draw_info(NDI_UNIQUE, 0,op,"Press `?' for help"); |
142 | new_draw_info(NDI_UNIQUE, 0,op,"Press `?' for help"); |
143 | new_draw_info(NDI_UNIQUE, 0,op," "); |
143 | new_draw_info(NDI_UNIQUE, 0,op," "); |
144 | new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, op, |
144 | new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, op, |
145 | "%s entered the game.",op->name); |
145 | "%s entered the game.",op->name); |
146 | if(!op->contr->name_changed) { |
146 | if(!op->contr->name_changed) { |
147 | new_draw_info(NDI_UNIQUE, 0,op,"Note that you must set your name with the name"); |
147 | new_draw_info(NDI_UNIQUE, 0,op,"Note that you must set your name with the name"); |
148 | new_draw_info(NDI_UNIQUE, 0,op,"command to enter the highscore list."); |
148 | new_draw_info(NDI_UNIQUE, 0,op,"command to enter the highscore list."); |
149 | new_draw_info(NDI_UNIQUE, 0,op,"(You can also use the crossfire.name X-resource.)"); |
149 | new_draw_info(NDI_UNIQUE, 0,op,"(You can also use the crossfire.name X-resource.)"); |
150 | } |
150 | } |
… | |
… | |
157 | char *crypt_string(char *str, char *salt) { |
157 | char *crypt_string(char *str, char *salt) { |
158 | #if defined(WIN32) || (defined(__FreeBSD__) && !defined(HAVE_LIBDES)) |
158 | #if defined(WIN32) || (defined(__FreeBSD__) && !defined(HAVE_LIBDES)) |
159 | return(str); |
159 | return(str); |
160 | #else |
160 | #else |
161 | static char *c= |
161 | static char *c= |
162 | "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; |
162 | "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; |
163 | char s[2]; |
163 | char s[2]; |
164 | |
164 | |
165 | if(salt==NULL) |
165 | if(salt==NULL) |
166 | s[0]= c[RANDOM() % (int)strlen(c)], |
166 | s[0]= c[RANDOM() % (int)strlen(c)], |
167 | s[1]= c[RANDOM() % (int)strlen(c)]; |
167 | s[1]= c[RANDOM() % (int)strlen(c)]; |
168 | else |
168 | else |
169 | s[0]= salt[0], |
169 | s[0]= salt[0], |
170 | s[1]= salt[1]; |
170 | s[1]= salt[1]; |
171 | |
171 | |
172 | # ifdef HAVE_LIBDES |
172 | # ifdef HAVE_LIBDES |
173 | return (char*)des_crypt(str,s); |
173 | return (char*)des_crypt(str,s); |
174 | # endif |
174 | # endif |
175 | /* Default case - just use crypt */ |
175 | /* Default case - just use crypt */ |
… | |
… | |
201 | * that of the savebed, his savebed map is gone. Lets go back |
201 | * that of the savebed, his savebed map is gone. Lets go back |
202 | * to the emergency path. Update what the players savebed is |
202 | * to the emergency path. Update what the players savebed is |
203 | * while we're at it. |
203 | * while we're at it. |
204 | */ |
204 | */ |
205 | if (oldmap == op->map && strcmp(op->contr->savebed_map, oldmap->path)) { |
205 | if (oldmap == op->map && strcmp(op->contr->savebed_map, oldmap->path)) { |
206 | LOG(llevDebug,"Player %s savebed location %s is invalid - going to emergency location (%s)\n", |
206 | LOG(llevDebug,"Player %s savebed location %s is invalid - going to emergency location (%s)\n", |
207 | settings.emergency_mapname, op->name, op->contr->savebed_map); |
207 | settings.emergency_mapname, op->name, op->contr->savebed_map); |
208 | strcpy(op->contr->savebed_map, settings.emergency_mapname); |
208 | strcpy(op->contr->savebed_map, settings.emergency_mapname); |
209 | op->contr->bed_x = settings.emergency_x; |
209 | op->contr->bed_x = settings.emergency_x; |
210 | op->contr->bed_y = settings.emergency_y; |
210 | op->contr->bed_y = settings.emergency_y; |
211 | free_string(op->contr->savebed_map); |
211 | free_string(op->contr->savebed_map); |
212 | EXIT_PATH(tmp) = add_string(op->contr->savebed_map); |
212 | EXIT_PATH(tmp) = add_string(op->contr->savebed_map); |
213 | EXIT_X(tmp) = op->contr->bed_x; |
213 | EXIT_X(tmp) = op->contr->bed_x; |
214 | EXIT_Y(tmp) = op->contr->bed_y; |
214 | EXIT_Y(tmp) = op->contr->bed_y; |
215 | enter_exit(op,tmp); |
215 | enter_exit(op,tmp); |
216 | } |
216 | } |
217 | free_object(tmp); |
217 | free_object(tmp); |
218 | } |
218 | } |
219 | |
219 | |
220 | /* All this really is is a glorified remove_object that also updates |
220 | /* All this really is is a glorified remove_object that also updates |
… | |
… | |
225 | mapstruct *oldmap = op->map; |
225 | mapstruct *oldmap = op->map; |
226 | |
226 | |
227 | remove_ob(op); |
227 | remove_ob(op); |
228 | |
228 | |
229 | if (oldmap) { |
229 | if (oldmap) { |
230 | if (!op->contr->hidden) |
230 | if (!op->contr->hidden) |
231 | oldmap->players--; |
231 | oldmap->players--; |
232 | if (oldmap->players <= 0) { /* can be less than zero due to errors in tracking this */ |
232 | if (oldmap->players <= 0) { /* can be less than zero due to errors in tracking this */ |
233 | set_map_timeout(oldmap); |
233 | set_map_timeout(oldmap); |
234 | } |
234 | } |
235 | } |
235 | } |
236 | } |
236 | } |
237 | |
237 | |
238 | /* |
238 | /* |
239 | * enter_map(): Moves the player and pets from current map (if any) to |
239 | * enter_map(): Moves the player and pets from current map (if any) to |
… | |
… | |
244 | */ |
244 | */ |
245 | static void enter_map(object *op, mapstruct *newmap, int x, int y) { |
245 | static void enter_map(object *op, mapstruct *newmap, int x, int y) { |
246 | mapstruct *oldmap = op->map; |
246 | mapstruct *oldmap = op->map; |
247 | |
247 | |
248 | if (out_of_map(newmap, x, y)) { |
248 | if (out_of_map(newmap, x, y)) { |
249 | LOG(llevError,"enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", |
249 | LOG(llevError,"enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", |
250 | newmap->path, x, y); |
250 | newmap->path, x, y); |
251 | x=MAP_ENTER_X(newmap); |
251 | x=MAP_ENTER_X(newmap); |
252 | y=MAP_ENTER_Y(newmap); |
252 | y=MAP_ENTER_Y(newmap); |
253 | if (out_of_map(newmap, x, y)) { |
253 | if (out_of_map(newmap, x, y)) { |
254 | LOG(llevError,"enter_map: map %s provides invalid default enter location (%d, %d) > (%d, %d)\n", |
254 | LOG(llevError,"enter_map: map %s provides invalid default enter location (%d, %d) > (%d, %d)\n", |
255 | newmap->path, x, y, MAP_WIDTH(newmap), MAP_HEIGHT(newmap)); |
255 | newmap->path, x, y, MAP_WIDTH(newmap), MAP_HEIGHT(newmap)); |
256 | new_draw_info(NDI_UNIQUE, 0, op, "The exit is closed"); |
256 | new_draw_info(NDI_UNIQUE, 0, op, "The exit is closed"); |
257 | return; |
257 | return; |
258 | } |
258 | } |
259 | } |
259 | } |
260 | /* try to find a spot for the player */ |
260 | /* try to find a spot for the player */ |
261 | if (ob_blocked(op, newmap, x, y)) { /* First choice blocked */ |
261 | if (ob_blocked(op, newmap, x, y)) { /* First choice blocked */ |
262 | /* We try to find a spot for the player, starting closest in. |
262 | /* We try to find a spot for the player, starting closest in. |
263 | * We could use find_first_free_spot, but that doesn't randomize it at all, |
263 | * We could use find_first_free_spot, but that doesn't randomize it at all, |
264 | * So for example, if the north space is free, you would always end up there even |
264 | * So for example, if the north space is free, you would always end up there even |
265 | * if other spaces around are available. |
265 | * if other spaces around are available. |
266 | * Note that for the second and third calls, we could start at a position other |
266 | * Note that for the second and third calls, we could start at a position other |
267 | * than one, but then we could end up on the other side of walls and so forth. |
267 | * than one, but then we could end up on the other side of walls and so forth. |
268 | */ |
268 | */ |
269 | int i = find_free_spot(op,newmap, x, y, 1, SIZEOFFREE1+1); |
269 | int i = find_free_spot(op,newmap, x, y, 1, SIZEOFFREE1+1); |
270 | if (i==-1) { |
270 | if (i==-1) { |
271 | i = find_free_spot(op,newmap, x, y, 1, SIZEOFFREE2+1); |
271 | i = find_free_spot(op,newmap, x, y, 1, SIZEOFFREE2+1); |
272 | if (i==-1) |
272 | if (i==-1) |
273 | i = find_free_spot(op,newmap, x, y, 1, SIZEOFFREE); |
273 | i = find_free_spot(op,newmap, x, y, 1, SIZEOFFREE); |
274 | } |
274 | } |
275 | if (i != -1 ) { |
275 | if (i != -1 ) { |
276 | x += freearr_x[i]; |
276 | x += freearr_x[i]; |
277 | y += freearr_y[i]; |
277 | y += freearr_y[i]; |
278 | } else { |
278 | } else { |
279 | /* not much we can do in this case. */ |
279 | /* not much we can do in this case. */ |
280 | LOG(llevInfo,"enter_map: Could not find free spot for player - will dump on top of object (%s: %d, %d)\n", |
280 | LOG(llevInfo,"enter_map: Could not find free spot for player - will dump on top of object (%s: %d, %d)\n", |
281 | newmap->path, x , y); |
281 | newmap->path, x , y); |
282 | } |
282 | } |
283 | } /* end if looking for free spot */ |
283 | } /* end if looking for free spot */ |
284 | |
284 | |
285 | if (op->map!=NULL) |
285 | if (op->map!=NULL) |
286 | { |
286 | { |
287 | INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (op->map), ARG_MAP (newmap)); |
287 | INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (op->map), ARG_MAP (newmap)); |
288 | INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)); |
288 | INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)); |
289 | } |
289 | } |
290 | |
290 | |
291 | /* If it is a player login, he has yet to be inserted anyplace. |
291 | /* If it is a player login, he has yet to be inserted anyplace. |
292 | * otherwise, we need to deal with removing the player here. |
292 | * otherwise, we need to deal with removing the player here. |
293 | */ |
293 | */ |
294 | if(!QUERY_FLAG(op, FLAG_REMOVED)) |
294 | if(!QUERY_FLAG(op, FLAG_REMOVED)) |
295 | remove_ob(op); |
295 | remove_ob(op); |
296 | |
296 | |
297 | /* remove_ob clears these so they must be reset after the remove_ob call */ |
297 | /* remove_ob clears these so they must be reset after the remove_ob call */ |
298 | op->x = x; |
298 | op->x = x; |
299 | op->y = y; |
299 | op->y = y; |
300 | op->map = newmap; |
300 | op->map = newmap; |
301 | insert_ob_in_map(op,op->map,NULL,INS_NO_WALK_ON); |
301 | insert_ob_in_map(op,op->map,NULL,INS_NO_WALK_ON); |
302 | |
302 | |
303 | INVOKE_MAP (ENTER, op->map, ARG_PLAYER (op->contr)); |
303 | INVOKE_MAP (ENTER, op->map, ARG_PLAYER (op->contr)); |
304 | |
304 | |
305 | if (!op->contr->hidden) |
305 | if (!op->contr->hidden) |
306 | newmap->players++; |
306 | newmap->players++; |
307 | |
307 | |
308 | newmap->timeout=0; |
308 | newmap->timeout=0; |
309 | op->enemy = NULL; |
309 | op->enemy = NULL; |
310 | |
310 | |
311 | if (op->contr) { |
311 | if (op->contr) { |
312 | strcpy(op->contr->maplevel, newmap->path); |
312 | strcpy(op->contr->maplevel, newmap->path); |
313 | op->contr->count=0; |
313 | op->contr->count=0; |
314 | } |
314 | } |
315 | |
315 | |
316 | /* Update any golems */ |
316 | /* Update any golems */ |
317 | if(op->type == PLAYER && op->contr->ranges[range_golem] != NULL) { |
317 | if(op->type == PLAYER && op->contr->ranges[range_golem] != NULL) { |
318 | int i = find_free_spot(op->contr->ranges[range_golem],newmap, |
318 | int i = find_free_spot(op->contr->ranges[range_golem],newmap, |
319 | x, y, 1, SIZEOFFREE); |
319 | x, y, 1, SIZEOFFREE); |
320 | remove_ob(op->contr->ranges[range_golem]); |
320 | remove_ob(op->contr->ranges[range_golem]); |
321 | if (i==-1) { |
321 | if (i==-1) { |
322 | remove_friendly_object(op->contr->ranges[range_golem]); |
322 | remove_friendly_object(op->contr->ranges[range_golem]); |
323 | free_object(op->contr->ranges[range_golem]); |
323 | free_object(op->contr->ranges[range_golem]); |
324 | op->contr->ranges[range_golem]=NULL; |
324 | op->contr->ranges[range_golem]=NULL; |
325 | op->contr->golem_count=0; |
325 | op->contr->golem_count=0; |
326 | } |
326 | } |
327 | else { |
327 | else { |
328 | object *tmp; |
328 | object *tmp; |
329 | for (tmp=op->contr->ranges[range_golem]; tmp!=NULL; tmp=tmp->more) { |
329 | for (tmp=op->contr->ranges[range_golem]; tmp!=NULL; tmp=tmp->more) { |
330 | tmp->x = x + freearr_x[i]+ (tmp->arch==NULL?0:tmp->arch->clone.x); |
330 | tmp->x = x + freearr_x[i]+ (tmp->arch==NULL?0:tmp->arch->clone.x); |
331 | tmp->y = y + freearr_y[i]+ (tmp->arch==NULL?0:tmp->arch->clone.y); |
331 | tmp->y = y + freearr_y[i]+ (tmp->arch==NULL?0:tmp->arch->clone.y); |
332 | tmp->map = newmap; |
332 | tmp->map = newmap; |
333 | } |
333 | } |
334 | insert_ob_in_map(op->contr->ranges[range_golem], newmap, NULL,0); |
334 | insert_ob_in_map(op->contr->ranges[range_golem], newmap, NULL,0); |
335 | op->contr->ranges[range_golem]->direction = |
335 | op->contr->ranges[range_golem]->direction = |
336 | find_dir_2(op->x - op->contr->ranges[range_golem]->x, |
336 | find_dir_2(op->x - op->contr->ranges[range_golem]->x, |
337 | op->y - op->contr->ranges[range_golem]->y); |
337 | op->y - op->contr->ranges[range_golem]->y); |
338 | } |
338 | } |
339 | } |
339 | } |
340 | op->direction=0; |
340 | op->direction=0; |
341 | |
341 | |
342 | /* since the players map is already loaded, we don't need to worry |
342 | /* since the players map is already loaded, we don't need to worry |
343 | * about pending objects. |
343 | * about pending objects. |
… | |
… | |
352 | if (oldmap) /* adjust old map */ |
352 | if (oldmap) /* adjust old map */ |
353 | { |
353 | { |
354 | oldmap->players--; |
354 | oldmap->players--; |
355 | |
355 | |
356 | if (oldmap->players <= 0) /* can be less than zero due to errors in tracking this */ |
356 | if (oldmap->players <= 0) /* can be less than zero due to errors in tracking this */ |
357 | set_map_timeout(oldmap); |
357 | set_map_timeout(oldmap); |
358 | } |
358 | } |
359 | } |
359 | } |
360 | swap_below_max (newmap->path); |
360 | swap_below_max (newmap->path); |
361 | } |
361 | } |
362 | |
362 | |
… | |
… | |
367 | /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is |
367 | /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is |
368 | * lower than the min value. |
368 | * lower than the min value. |
369 | */ |
369 | */ |
370 | #if MAP_MINTIMEOUT |
370 | #if MAP_MINTIMEOUT |
371 | if (oldmap->timeout < MAP_MINTIMEOUT) { |
371 | if (oldmap->timeout < MAP_MINTIMEOUT) { |
372 | oldmap->timeout = MAP_MINTIMEOUT; |
372 | oldmap->timeout = MAP_MINTIMEOUT; |
373 | } |
373 | } |
374 | #endif |
374 | #endif |
375 | if (oldmap->timeout > MAP_MAXTIMEOUT) { |
375 | if (oldmap->timeout > MAP_MAXTIMEOUT) { |
376 | oldmap->timeout = MAP_MAXTIMEOUT; |
376 | oldmap->timeout = MAP_MAXTIMEOUT; |
377 | } |
377 | } |
378 | #else |
378 | #else |
379 | /* save out the map */ |
379 | /* save out the map */ |
380 | swap_map(oldmap); |
380 | swap_map(oldmap); |
381 | #endif /* MAP_MAXTIMEOUT */ |
381 | #endif /* MAP_MAXTIMEOUT */ |
… | |
… | |
390 | static char newpath[MAX_BUF],*cp; |
390 | static char newpath[MAX_BUF],*cp; |
391 | |
391 | |
392 | strncpy(newpath, file, MAX_BUF-1); |
392 | strncpy(newpath, file, MAX_BUF-1); |
393 | newpath[MAX_BUF-1]='\0'; |
393 | newpath[MAX_BUF-1]='\0'; |
394 | for (cp=newpath; *cp!='\0'; cp++) { |
394 | for (cp=newpath; *cp!='\0'; cp++) { |
395 | if (*cp=='/') *cp='_'; |
395 | if (*cp=='/') *cp='_'; |
396 | } |
396 | } |
397 | return newpath; |
397 | return newpath; |
398 | } |
398 | } |
399 | |
399 | |
400 | |
400 | |
… | |
… | |
409 | { |
409 | { |
410 | static char newpath[MAX_BUF],*cp; |
410 | static char newpath[MAX_BUF],*cp; |
411 | |
411 | |
412 | cp=strrchr(src, '/'); |
412 | cp=strrchr(src, '/'); |
413 | if (cp) |
413 | if (cp) |
414 | strncpy(newpath, cp+1, MAX_BUF-1); |
414 | strncpy(newpath, cp+1, MAX_BUF-1); |
415 | else |
415 | else |
416 | strncpy(newpath, src, MAX_BUF-1); |
416 | strncpy(newpath, src, MAX_BUF-1); |
417 | newpath[MAX_BUF-1]='\0'; |
417 | newpath[MAX_BUF-1]='\0'; |
418 | |
418 | |
419 | for (cp=newpath; *cp!='\0'; cp++) { |
419 | for (cp=newpath; *cp!='\0'; cp++) { |
420 | if (*cp=='_') *cp='/'; |
420 | if (*cp=='_') *cp='/'; |
421 | } |
421 | } |
422 | return newpath; |
422 | return newpath; |
423 | } |
423 | } |
424 | |
424 | |
425 | |
425 | |
… | |
… | |
447 | * as where the player is. Otherwise, use the origin map. |
447 | * as where the player is. Otherwise, use the origin map. |
448 | * Take the last component (after the last slash) to give |
448 | * Take the last component (after the last slash) to give |
449 | * shorter names without bogus slashes. |
449 | * shorter names without bogus slashes. |
450 | */ |
450 | */ |
451 | if (rp.final_map[0]) { |
451 | if (rp.final_map[0]) { |
452 | cp = strrchr(rp.final_map, '/'); |
452 | cp = strrchr(rp.final_map, '/'); |
453 | if (!cp) cp = rp.final_map; |
453 | if (!cp) cp = rp.final_map; |
454 | } else { |
454 | } else { |
455 | char buf[HUGE_BUF]; |
455 | char buf[HUGE_BUF]; |
456 | |
456 | |
457 | cp = strrchr(rp.origin_map, '/'); |
457 | cp = strrchr(rp.origin_map, '/'); |
458 | if (!cp) cp = rp.origin_map; |
458 | if (!cp) cp = rp.origin_map; |
459 | /* Need to strip of any trailing digits, if it has them */ |
459 | /* Need to strip of any trailing digits, if it has them */ |
460 | strcpy(buf, cp); |
460 | strcpy(buf, cp); |
461 | while (isdigit(buf[strlen(buf) - 1])) |
461 | while (isdigit(buf[strlen(buf) - 1])) |
462 | buf[strlen(buf) - 1] = 0; |
462 | buf[strlen(buf) - 1] = 0; |
463 | cp = buf; |
463 | cp = buf; |
464 | } |
464 | } |
465 | |
465 | |
466 | sprintf(newmap_name,"/random/%s%04d",cp+1, reference_number++); |
466 | sprintf(newmap_name,"/random/%s%04d",cp+1, reference_number++); |
467 | |
467 | |
468 | /* now to generate the actual map. */ |
468 | /* now to generate the actual map. */ |
… | |
… | |
473 | * exit in a unique map leading to a random map will not work properly. |
473 | * exit in a unique map leading to a random map will not work properly. |
474 | * It also means that if the created random map gets reset before |
474 | * It also means that if the created random map gets reset before |
475 | * the exit leading to it, that the exit will no longer work. |
475 | * the exit leading to it, that the exit will no longer work. |
476 | */ |
476 | */ |
477 | if(new_map) { |
477 | if(new_map) { |
478 | int x, y; |
478 | int x, y; |
479 | x=EXIT_X(exit_ob) = MAP_ENTER_X(new_map); |
479 | x=EXIT_X(exit_ob) = MAP_ENTER_X(new_map); |
480 | y=EXIT_Y(exit_ob) = MAP_ENTER_Y(new_map); |
480 | y=EXIT_Y(exit_ob) = MAP_ENTER_Y(new_map); |
481 | EXIT_PATH(exit_ob) = add_string(newmap_name); |
481 | EXIT_PATH(exit_ob) = add_string(newmap_name); |
482 | strcpy(new_map->path, newmap_name); |
482 | strcpy(new_map->path, newmap_name); |
483 | enter_map(pl, new_map, x, y); |
483 | enter_map(pl, new_map, x, y); |
484 | } |
484 | } |
485 | } |
485 | } |
486 | |
486 | |
487 | /* The player is trying to enter a non-randomly generated template map. In this |
487 | /* The player is trying to enter a non-randomly generated template map. In this |
488 | * case, use a map file for a template |
488 | * case, use a map file for a template |
… | |
… | |
499 | * to generate the map from. |
499 | * to generate the map from. |
500 | */ |
500 | */ |
501 | snprintf(exitpath, sizeof(exitpath), "%s", EXIT_PATH(exit_ob)+2); |
501 | snprintf(exitpath, sizeof(exitpath), "%s", EXIT_PATH(exit_ob)+2); |
502 | sourcemap = strchr(exitpath, '!'); |
502 | sourcemap = strchr(exitpath, '!'); |
503 | if (!sourcemap) { |
503 | if (!sourcemap) { |
504 | new_draw_info_format(NDI_UNIQUE, 0, pl, "The %s is closed.", exit_ob->name); |
504 | new_draw_info_format(NDI_UNIQUE, 0, pl, "The %s is closed.", exit_ob->name); |
505 | /* Should only occur when no source map is set. |
505 | /* Should only occur when no source map is set. |
506 | */ |
506 | */ |
507 | LOG(llevError,"enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n", |
507 | LOG(llevError,"enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n", |
508 | exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); |
508 | exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); |
509 | return; |
509 | return; |
510 | } |
510 | } |
511 | *sourcemap++ = '\0'; |
511 | *sourcemap++ = '\0'; |
512 | |
512 | |
513 | /* If we are not coming from a template map, we can use relative directories |
513 | /* If we are not coming from a template map, we can use relative directories |
… | |
… | |
551 | if (new_map) { |
551 | if (new_map) { |
552 | /* set the path of the map to where it should be |
552 | /* set the path of the map to where it should be |
553 | * so we don't just save over the source map. |
553 | * so we don't just save over the source map. |
554 | */ |
554 | */ |
555 | strcpy(new_map->path, new_map_name); |
555 | strcpy(new_map->path, new_map_name); |
556 | new_map->templatemap = 1; |
556 | new_map->templatemap = 1; |
557 | enter_map(pl, new_map, EXIT_X(exit_ob), EXIT_Y(exit_ob)); |
557 | enter_map(pl, new_map, EXIT_X(exit_ob), EXIT_Y(exit_ob)); |
558 | } else { |
558 | } else { |
559 | new_draw_info_format(NDI_UNIQUE, 0, pl, "The %s is closed.", exit_ob->name); |
559 | new_draw_info_format(NDI_UNIQUE, 0, pl, "The %s is closed.", exit_ob->name); |
560 | /* Should only occur when an invalid source map is set. |
560 | /* Should only occur when an invalid source map is set. |
561 | */ |
561 | */ |
562 | LOG(llevDebug,"enter_fixed_template_map: Exit %s (%d,%d) on map %s leads no where.\n", |
562 | LOG(llevDebug,"enter_fixed_template_map: Exit %s (%d,%d) on map %s leads no where.\n", |
563 | exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); |
563 | exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); |
564 | } |
564 | } |
565 | } |
565 | } |
566 | |
566 | |
567 | |
567 | |
568 | /* The player is trying to enter a randomly generated template map. In this |
568 | /* The player is trying to enter a randomly generated template map. In this |
… | |
… | |
598 | new_map_name = create_template_pathname(resultname); |
598 | new_map_name = create_template_pathname(resultname); |
599 | } |
599 | } |
600 | |
600 | |
601 | new_map = ready_map_name(new_map_name, MAP_PLAYER_UNIQUE); |
601 | new_map = ready_map_name(new_map_name, MAP_PLAYER_UNIQUE); |
602 | if (!new_map) { |
602 | if (!new_map) { |
603 | memset(&rp, 0, sizeof(RMParms)); |
603 | memset(&rp, 0, sizeof(RMParms)); |
604 | rp.Xsize=-1; |
604 | rp.Xsize=-1; |
605 | rp.Ysize=-1; |
605 | rp.Ysize=-1; |
606 | rp.region=get_region_by_map(exit_ob->map); |
606 | rp.region=get_region_by_map(exit_ob->map); |
607 | if (exit_ob->msg) set_random_map_variable(&rp,exit_ob->msg); |
607 | if (exit_ob->msg) set_random_map_variable(&rp,exit_ob->msg); |
608 | rp.origin_x = exit_ob->x; |
608 | rp.origin_x = exit_ob->x; |
609 | rp.origin_y = exit_ob->y; |
609 | rp.origin_y = exit_ob->y; |
610 | strcpy(rp.origin_map, pl->map->path); |
610 | strcpy(rp.origin_map, pl->map->path); |
611 | |
611 | |
612 | /* now to generate the actual map. */ |
612 | /* now to generate the actual map. */ |
613 | new_map=generate_random_map(new_map_name,&rp); |
613 | new_map=generate_random_map(new_map_name,&rp); |
614 | } |
614 | } |
615 | |
615 | |
616 | |
616 | |
617 | /* Update the exit_ob so it now points directly at the newly created |
617 | /* Update the exit_ob so it now points directly at the newly created |
618 | * random maps. Not that it is likely to happen, but it does mean that a |
618 | * random maps. Not that it is likely to happen, but it does mean that a |
619 | * exit in a unique map leading to a random map will not work properly. |
619 | * exit in a unique map leading to a random map will not work properly. |
620 | * It also means that if the created random map gets reset before |
620 | * It also means that if the created random map gets reset before |
621 | * the exit leading to it, that the exit will no longer work. |
621 | * the exit leading to it, that the exit will no longer work. |
622 | */ |
622 | */ |
623 | if(new_map) { |
623 | if(new_map) { |
624 | int x, y; |
624 | int x, y; |
625 | x=EXIT_X(exit_ob) = MAP_ENTER_X(new_map); |
625 | x=EXIT_X(exit_ob) = MAP_ENTER_X(new_map); |
626 | y=EXIT_Y(exit_ob) = MAP_ENTER_Y(new_map); |
626 | y=EXIT_Y(exit_ob) = MAP_ENTER_Y(new_map); |
627 | new_map->templatemap = 1; |
627 | new_map->templatemap = 1; |
628 | enter_map(pl, new_map, x, y); |
628 | enter_map(pl, new_map, x, y); |
629 | } |
629 | } |
630 | } |
630 | } |
631 | |
631 | |
632 | |
632 | |
633 | /* Code to enter/detect a character entering a unique map. |
633 | /* Code to enter/detect a character entering a unique map. |
… | |
… | |
636 | { |
636 | { |
637 | char apartment[HUGE_BUF]; |
637 | char apartment[HUGE_BUF]; |
638 | mapstruct *newmap; |
638 | mapstruct *newmap; |
639 | |
639 | |
640 | if (EXIT_PATH(exit_ob)[0]=='/') { |
640 | if (EXIT_PATH(exit_ob)[0]=='/') { |
641 | sprintf(apartment, "%s/%s/%s/%s", settings.localdir, |
641 | sprintf(apartment, "%s/%s/%s/%s", settings.localdir, |
642 | settings.playerdir, op->name, clean_path(EXIT_PATH(exit_ob))); |
642 | settings.playerdir, op->name, clean_path(EXIT_PATH(exit_ob))); |
643 | newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE); |
643 | newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE); |
644 | if (!newmap) { |
644 | if (!newmap) { |
645 | newmap = load_original_map(create_pathname(EXIT_PATH(exit_ob)), MAP_PLAYER_UNIQUE); |
645 | newmap = load_original_map(create_pathname(EXIT_PATH(exit_ob)), MAP_PLAYER_UNIQUE); |
646 | if (newmap) fix_auto_apply(newmap); |
646 | if (newmap) fix_auto_apply(newmap); |
647 | } |
647 | } |
648 | } else { /* relative directory */ |
648 | } else { /* relative directory */ |
649 | char reldir[HUGE_BUF], tmpc[HUGE_BUF], *cp; |
649 | char reldir[HUGE_BUF], tmpc[HUGE_BUF], *cp; |
650 | |
650 | |
651 | if (exit_ob->map->unique) { |
651 | if (exit_ob->map->unique) { |
652 | |
652 | |
653 | strcpy(reldir, unclean_path(exit_ob->map->path)); |
653 | strcpy(reldir, unclean_path(exit_ob->map->path)); |
654 | |
654 | |
655 | /* Need to copy this over, as clean_path only has one static return buffer */ |
655 | /* Need to copy this over, as clean_path only has one static return buffer */ |
656 | strcpy(tmpc, clean_path(reldir)); |
656 | strcpy(tmpc, clean_path(reldir)); |
657 | /* Remove final component, if any */ |
657 | /* Remove final component, if any */ |
658 | if ((cp=strrchr(tmpc, '_'))!=NULL) *cp=0; |
658 | if ((cp=strrchr(tmpc, '_'))!=NULL) *cp=0; |
659 | |
659 | |
660 | sprintf(apartment, "%s/%s/%s/%s_%s", settings.localdir, |
660 | sprintf(apartment, "%s/%s/%s/%s_%s", settings.localdir, |
661 | settings.playerdir, op->name, tmpc, |
661 | settings.playerdir, op->name, tmpc, |
662 | clean_path(EXIT_PATH(exit_ob))); |
662 | clean_path(EXIT_PATH(exit_ob))); |
663 | |
663 | |
664 | newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE); |
664 | newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE); |
665 | if (!newmap) { |
665 | if (!newmap) { |
666 | newmap = load_original_map(create_pathname(path_combine_and_normalize(reldir, EXIT_PATH(exit_ob))), MAP_PLAYER_UNIQUE); |
666 | newmap = load_original_map(create_pathname(path_combine_and_normalize(reldir, EXIT_PATH(exit_ob))), MAP_PLAYER_UNIQUE); |
667 | if (newmap) fix_auto_apply(newmap); |
667 | if (newmap) fix_auto_apply(newmap); |
668 | } |
668 | } |
669 | } |
669 | } |
670 | else { |
670 | else { |
671 | /* The exit is unique, but the map we are coming from is not unique. So |
671 | /* The exit is unique, but the map we are coming from is not unique. So |
672 | * use the basic logic - don't need to demangle the path name |
672 | * use the basic logic - don't need to demangle the path name |
673 | */ |
673 | */ |
674 | sprintf(apartment, "%s/%s/%s/%s", settings.localdir, |
674 | sprintf(apartment, "%s/%s/%s/%s", settings.localdir, |
675 | settings.playerdir, op->name, |
675 | settings.playerdir, op->name, |
676 | clean_path(path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob)))); |
676 | clean_path(path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob)))); |
677 | newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE); |
677 | newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE); |
678 | if (!newmap) { |
678 | if (!newmap) { |
679 | newmap = ready_map_name(path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob)), 0); |
679 | newmap = ready_map_name(path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob)), 0); |
680 | if (newmap) fix_auto_apply(newmap); |
680 | if (newmap) fix_auto_apply(newmap); |
681 | } |
681 | } |
682 | } |
682 | } |
683 | } |
683 | } |
684 | |
684 | |
685 | if (newmap) { |
685 | if (newmap) { |
686 | strcpy(newmap->path, apartment); |
686 | strcpy(newmap->path, apartment); |
687 | newmap->unique = 1; |
687 | newmap->unique = 1; |
688 | enter_map(op, newmap, EXIT_X(exit_ob), EXIT_Y(exit_ob)); |
688 | enter_map(op, newmap, EXIT_X(exit_ob), EXIT_Y(exit_ob)); |
689 | } else { |
689 | } else { |
690 | new_draw_info_format(NDI_UNIQUE, 0, op, "The %s is closed.", exit_ob->name); |
690 | new_draw_info_format(NDI_UNIQUE, 0, op, "The %s is closed.", exit_ob->name); |
691 | /* Perhaps not critical, but I would think that the unique maps |
691 | /* Perhaps not critical, but I would think that the unique maps |
692 | * should be new enough this does not happen. This also creates |
692 | * should be new enough this does not happen. This also creates |
693 | * a strange situation where some players could perhaps have visited |
693 | * a strange situation where some players could perhaps have visited |
694 | * such a map before it was removed, so they have the private |
694 | * such a map before it was removed, so they have the private |
695 | * map, but other players can't get it anymore. |
695 | * map, but other players can't get it anymore. |
696 | */ |
696 | */ |
697 | LOG(llevDebug,"enter_unique_map: Exit %s (%d,%d) on map %s is leads no where.\n", |
697 | LOG(llevDebug,"enter_unique_map: Exit %s (%d,%d) on map %s is leads no where.\n", |
698 | exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); |
698 | exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); |
699 | } |
699 | } |
700 | |
700 | |
701 | } |
701 | } |
702 | |
702 | |
703 | |
703 | |
704 | /* Tries to move 'op' to exit_ob. op is the character or monster that is |
704 | /* Tries to move 'op' to exit_ob. op is the character or monster that is |
705 | * using the exit, where exit_ob is the exit object (boat, door, teleporter, |
705 | * using the exit, where exit_ob is the exit object (boat, door, teleporter, |
… | |
… | |
720 | if (op->type != PLAYER) return; |
720 | if (op->type != PLAYER) return; |
721 | |
721 | |
722 | /* First, lets figure out what map the player is going to go to */ |
722 | /* First, lets figure out what map the player is going to go to */ |
723 | if (exit_ob){ |
723 | if (exit_ob){ |
724 | |
724 | |
725 | /* check to see if we make a template map */ |
725 | /* check to see if we make a template map */ |
726 | if(EXIT_PATH(exit_ob)&&EXIT_PATH(exit_ob)[1]=='@') { |
726 | if(EXIT_PATH(exit_ob)&&EXIT_PATH(exit_ob)[1]=='@') { |
727 | if (EXIT_PATH(exit_ob)[2]=='!') { |
727 | if (EXIT_PATH(exit_ob)[2]=='!') { |
728 | /* generate a template map randomly */ |
728 | /* generate a template map randomly */ |
729 | enter_random_template_map(op, exit_ob); |
729 | enter_random_template_map(op, exit_ob); |
730 | } else { |
730 | } else { |
731 | /* generate a template map from a fixed template */ |
731 | /* generate a template map from a fixed template */ |
732 | enter_fixed_template_map(op, exit_ob); |
732 | enter_fixed_template_map(op, exit_ob); |
733 | } |
733 | } |
734 | } |
734 | } |
735 | /* check to see if we make a randomly generated map */ |
735 | /* check to see if we make a randomly generated map */ |
736 | else if(EXIT_PATH(exit_ob)&&EXIT_PATH(exit_ob)[1]=='!') { |
736 | else if(EXIT_PATH(exit_ob)&&EXIT_PATH(exit_ob)[1]=='!') { |
737 | enter_random_map(op, exit_ob); |
737 | enter_random_map(op, exit_ob); |
738 | } |
738 | } |
739 | else if (QUERY_FLAG(exit_ob, FLAG_UNIQUE)) { |
739 | else if (QUERY_FLAG(exit_ob, FLAG_UNIQUE)) { |
740 | enter_unique_map(op, exit_ob); |
740 | enter_unique_map(op, exit_ob); |
741 | } else { |
741 | } else { |
742 | int x=EXIT_X(exit_ob), y=EXIT_Y(exit_ob); |
742 | int x=EXIT_X(exit_ob), y=EXIT_Y(exit_ob); |
743 | /* 'Normal' exits that do not do anything special |
743 | /* 'Normal' exits that do not do anything special |
744 | * Simple enough we don't need another routine for it. |
744 | * Simple enough we don't need another routine for it. |
745 | */ |
745 | */ |
746 | mapstruct *newmap; |
746 | mapstruct *newmap; |
747 | if (exit_ob->map) { |
747 | if (exit_ob->map) { |
748 | newmap = ready_map_name(path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob)), 0); |
748 | newmap = ready_map_name(path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob)), 0); |
749 | /* Random map was previously generated, but is no longer about. Lets generate a new |
749 | /* Random map was previously generated, but is no longer about. Lets generate a new |
750 | * map. |
750 | * map. |
751 | */ |
751 | */ |
752 | if (!newmap && !strncmp(EXIT_PATH(exit_ob),"/random/",8)) { |
752 | if (!newmap && !strncmp(EXIT_PATH(exit_ob),"/random/",8)) { |
753 | /* Maps that go down have a message set. However, maps that go |
753 | /* Maps that go down have a message set. However, maps that go |
754 | * up, don't. If the going home has reset, there isn't much |
754 | * up, don't. If the going home has reset, there isn't much |
755 | * point generating a random map, because it won't match the maps. |
755 | * point generating a random map, because it won't match the maps. |
756 | */ |
756 | */ |
757 | if (exit_ob->msg) { |
757 | if (exit_ob->msg) { |
758 | enter_random_map(op, exit_ob); |
758 | enter_random_map(op, exit_ob); |
759 | } else { |
759 | } else { |
760 | new_draw_info_format(NDI_UNIQUE, 0, op, "The %s is closed.", exit_ob->name); |
760 | new_draw_info_format(NDI_UNIQUE, 0, op, "The %s is closed.", exit_ob->name); |
761 | return; |
761 | return; |
762 | } |
762 | } |
763 | |
763 | |
764 | /* For exits that cause damages (like pits). Don't know if any |
764 | /* For exits that cause damages (like pits). Don't know if any |
765 | * random maps use this or not. |
765 | * random maps use this or not. |
766 | */ |
766 | */ |
767 | if(exit_ob->stats.dam && op->type==PLAYER) |
767 | if(exit_ob->stats.dam && op->type==PLAYER) |
768 | hit_player(op,exit_ob->stats.dam,exit_ob,exit_ob->attacktype,1); |
768 | hit_player(op,exit_ob->stats.dam,exit_ob,exit_ob->attacktype,1); |
769 | return; |
769 | return; |
770 | } |
770 | } |
771 | } else { |
771 | } else { |
772 | /* For word of recall and other force objects |
772 | /* For word of recall and other force objects |
773 | * They contain the full pathname of the map to go back to, |
773 | * They contain the full pathname of the map to go back to, |
774 | * so we don't need to normalize it. |
774 | * so we don't need to normalize it. |
775 | * But we do need to see if it is unique or not |
775 | * But we do need to see if it is unique or not |
776 | */ |
776 | */ |
777 | if (!strncmp(EXIT_PATH(exit_ob), settings.localdir, strlen(settings.localdir))) |
777 | if (!strncmp(EXIT_PATH(exit_ob), settings.localdir, strlen(settings.localdir))) |
778 | newmap = ready_map_name(EXIT_PATH(exit_ob), MAP_PLAYER_UNIQUE); |
778 | newmap = ready_map_name(EXIT_PATH(exit_ob), MAP_PLAYER_UNIQUE); |
779 | else |
779 | else |
780 | newmap = ready_map_name(EXIT_PATH(exit_ob), 0); |
780 | newmap = ready_map_name(EXIT_PATH(exit_ob), 0); |
781 | } |
781 | } |
782 | if (!newmap) |
782 | if (!newmap) |
783 | { |
783 | { |
784 | if (exit_ob->name) |
784 | if (exit_ob->name) |
785 | new_draw_info_format(NDI_UNIQUE, 0, op, "The %s is closed.", exit_ob->name); |
785 | new_draw_info_format(NDI_UNIQUE, 0, op, "The %s is closed.", exit_ob->name); |
786 | /* don't cry to momma if name is not set - as in tmp objects |
786 | /* don't cry to momma if name is not set - as in tmp objects |
787 | * used by the savebed code and character creation */ |
787 | * used by the savebed code and character creation */ |
788 | return; |
788 | return; |
789 | } |
789 | } |
790 | |
790 | |
791 | /* This supports the old behaviour, but it really should not be used. |
791 | /* This supports the old behaviour, but it really should not be used. |
792 | * I will note for example that with this method, it is impossible to |
792 | * I will note for example that with this method, it is impossible to |
793 | * set 0,0 destination coordinates. Really, if we want to support |
793 | * set 0,0 destination coordinates. Really, if we want to support |
794 | * using the new maps default coordinates, the exit ob should use |
794 | * using the new maps default coordinates, the exit ob should use |
795 | * something like -1, -1 so it is clear to do that. |
795 | * something like -1, -1 so it is clear to do that. |
796 | */ |
796 | */ |
797 | if (x==0 && y==0) { |
797 | if (x==0 && y==0) { |
798 | x=MAP_ENTER_X(newmap); |
798 | x=MAP_ENTER_X(newmap); |
799 | y=MAP_ENTER_Y(newmap); |
799 | y=MAP_ENTER_Y(newmap); |
800 | LOG(llevDebug,"enter_exit: Exit %s (%d,%d) on map %s is 0 destination coordinates\n", |
800 | LOG(llevDebug,"enter_exit: Exit %s (%d,%d) on map %s is 0 destination coordinates\n", |
801 | exit_ob->name?exit_ob->name:"(none)", exit_ob->x, exit_ob->y, |
801 | exit_ob->name?exit_ob->name:"(none)", exit_ob->x, exit_ob->y, |
802 | exit_ob->map?exit_ob->map->path:"(none)"); |
802 | exit_ob->map?exit_ob->map->path:"(none)"); |
803 | } |
803 | } |
804 | |
804 | |
805 | /* mids 02/13/2002 if exit is damned, update players death & WoR home-position and delete town portal */ |
805 | /* mids 02/13/2002 if exit is damned, update players death & WoR home-position and delete town portal */ |
806 | if (QUERY_FLAG(exit_ob, FLAG_DAMNED)) { |
806 | if (QUERY_FLAG(exit_ob, FLAG_DAMNED)) { |
807 | /* remove an old force with a slaying field == PORTAL_DESTINATION_NAME */ |
807 | /* remove an old force with a slaying field == PORTAL_DESTINATION_NAME */ |
808 | for(tmp=op->inv; tmp != NULL; tmp = tmp->below) { |
808 | for(tmp=op->inv; tmp != NULL; tmp = tmp->below) { |
… | |
… | |
819 | /* LOG(llevDebug,"enter_exit: Taking damned exit %s to (%d,%d) on map %s\n", |
819 | /* LOG(llevDebug,"enter_exit: Taking damned exit %s to (%d,%d) on map %s\n", |
820 | * exit_ob->name?exit_ob->name:"(none)", exit_ob->x, exit_ob->y, |
820 | * exit_ob->name?exit_ob->name:"(none)", exit_ob->x, exit_ob->y, |
821 | * path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob))); */ |
821 | * path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob))); */ |
822 | } |
822 | } |
823 | |
823 | |
824 | enter_map(op, newmap, x, y); |
824 | enter_map(op, newmap, x, y); |
825 | } |
825 | } |
826 | /* For exits that cause damages (like pits) */ |
826 | /* For exits that cause damages (like pits) */ |
827 | if(exit_ob->stats.dam && op->type==PLAYER) |
827 | if(exit_ob->stats.dam && op->type==PLAYER) |
828 | hit_player(op,exit_ob->stats.dam,exit_ob,exit_ob->attacktype,1); |
828 | hit_player(op,exit_ob->stats.dam,exit_ob,exit_ob->attacktype,1); |
829 | } else { |
829 | } else { |
830 | int flags = 0; |
830 | int flags = 0; |
831 | mapstruct *newmap; |
831 | mapstruct *newmap; |
832 | |
832 | |
833 | |
833 | |
834 | /* Hypothetically, I guess its possible that a standard map matches |
834 | /* Hypothetically, I guess its possible that a standard map matches |
835 | * the localdir, but that seems pretty unlikely - unlikely enough that |
835 | * the localdir, but that seems pretty unlikely - unlikely enough that |
836 | * I'm not going to attempt to try to deal with that possibility. |
836 | * I'm not going to attempt to try to deal with that possibility. |
837 | * We use the fact that when a player saves on a unique map, it prepends |
837 | * We use the fact that when a player saves on a unique map, it prepends |
838 | * the localdir to that name. So its an easy way to see of the map is |
838 | * the localdir to that name. So its an easy way to see of the map is |
839 | * unique or not. |
839 | * unique or not. |
840 | */ |
840 | */ |
841 | if (!strncmp(op->contr->maplevel, settings.localdir, strlen(settings.localdir))) |
841 | if (!strncmp(op->contr->maplevel, settings.localdir, strlen(settings.localdir))) |
842 | flags = MAP_PLAYER_UNIQUE; |
842 | flags = MAP_PLAYER_UNIQUE; |
843 | |
843 | |
844 | /* newmap returns the map (if already loaded), or loads it for |
844 | /* newmap returns the map (if already loaded), or loads it for |
845 | * us. |
845 | * us. |
846 | */ |
846 | */ |
847 | newmap = ready_map_name(op->contr->maplevel, flags); |
847 | newmap = ready_map_name(op->contr->maplevel, flags); |
848 | if (!newmap) |
848 | if (!newmap) |
849 | { |
849 | { |
850 | LOG(llevError, |
850 | LOG(llevError, |
851 | "enter_exit: Pathname to map does not exist! (%s)\n", |
851 | "enter_exit: Pathname to map does not exist! (%s)\n", |
852 | op->contr->maplevel); |
852 | op->contr->maplevel); |
853 | newmap = ready_map_name(settings.emergency_mapname, 0); |
853 | newmap = ready_map_name(settings.emergency_mapname, 0); |
854 | op->x = settings.emergency_x; |
854 | op->x = settings.emergency_x; |
855 | op->y = settings.emergency_y; |
855 | op->y = settings.emergency_y; |
856 | /* If we can't load the emergency map, something is probably really |
856 | /* If we can't load the emergency map, something is probably really |
857 | * screwed up, so bail out now. |
857 | * screwed up, so bail out now. |
858 | */ |
858 | */ |
859 | if (!newmap) { |
859 | if (!newmap) { |
860 | LOG(llevError,"enter_exit: could not load emergency map? Fatal error\n"); |
860 | LOG(llevError,"enter_exit: could not load emergency map? Fatal error\n"); |
861 | abort(); |
861 | abort(); |
862 | } |
862 | } |
863 | } |
863 | } |
864 | enter_map(op, newmap, op->x, op->y); |
864 | enter_map(op, newmap, op->x, op->y); |
865 | } |
865 | } |
866 | } |
866 | } |
867 | |
867 | |
868 | /* |
868 | /* |
869 | * process_active_maps(): Works like process_events(), but it only |
869 | * process_active_maps(): Works like process_events(), but it only |
… | |
… | |
894 | int flag; |
894 | int flag; |
895 | player *pl,*plnext; |
895 | player *pl,*plnext; |
896 | |
896 | |
897 | /* Basically, we keep looping until all the players have done their actions. */ |
897 | /* Basically, we keep looping until all the players have done their actions. */ |
898 | for(flag=1;flag!=0;) { |
898 | for(flag=1;flag!=0;) { |
899 | flag=0; |
899 | flag=0; |
900 | for(pl=first_player;pl!=NULL;pl=plnext) { |
900 | for(pl=first_player;pl!=NULL;pl=plnext) { |
901 | plnext=pl->next; /* In case a player exits the game in handle_player() */ |
901 | plnext=pl->next; /* In case a player exits the game in handle_player() */ |
902 | |
902 | |
903 | if (pl->ob == NULL) continue; |
903 | if (pl->ob == NULL) continue; |
904 | |
904 | |
905 | if (map!=NULL && pl->ob->map!=map) continue; |
905 | if (map!=NULL && pl->ob->map!=map) continue; |
906 | |
906 | |
907 | if(pl->ob->speed_left>0) { |
907 | if(pl->ob->speed_left>0) { |
908 | if (handle_newcs_player(pl->ob)) |
908 | if (handle_newcs_player(pl->ob)) |
909 | flag=1; |
909 | flag=1; |
910 | } /* end if player has speed left */ |
910 | } /* end if player has speed left */ |
911 | |
911 | |
912 | /* If the player is not actively playing, don't make a |
912 | /* If the player is not actively playing, don't make a |
913 | * backup save - nothing to save anyway. Plus, the |
913 | * backup save - nothing to save anyway. Plus, the |
914 | * map may not longer be valid. This can happen when the |
914 | * map may not longer be valid. This can happen when the |
915 | * player quits - they exist for purposes of tracking on the map, |
915 | * player quits - they exist for purposes of tracking on the map, |
916 | * but don't actually reside on any actual map. |
916 | * but don't actually reside on any actual map. |
917 | */ |
917 | */ |
918 | if (QUERY_FLAG(pl->ob, FLAG_REMOVED)) continue; |
918 | if (QUERY_FLAG(pl->ob, FLAG_REMOVED)) continue; |
919 | |
919 | |
920 | #ifdef AUTOSAVE |
920 | #ifdef AUTOSAVE |
921 | /* check for ST_PLAYING state so that we don't try to save off when |
921 | /* check for ST_PLAYING state so that we don't try to save off when |
922 | * the player is logging in. |
922 | * the player is logging in. |
923 | */ |
923 | */ |
924 | if ((pl->last_save_tick+AUTOSAVE)<pticks && pl->state==ST_PLAYING) { |
924 | if ((pl->last_save_tick+AUTOSAVE)<pticks && pl->state==ST_PLAYING) { |
925 | /* Don't save the player on unholy ground. Instead, increase the |
925 | /* Don't save the player on unholy ground. Instead, increase the |
926 | * tick time so it will be about 10 seconds before we try and save |
926 | * tick time so it will be about 10 seconds before we try and save |
927 | * again. |
927 | * again. |
928 | */ |
928 | */ |
929 | // if (get_map_flags(pl->ob->map, NULL, pl->ob->x, pl->ob->y, NULL, NULL) & P_NO_CLERIC) { |
929 | // if (get_map_flags(pl->ob->map, NULL, pl->ob->x, pl->ob->y, NULL, NULL) & P_NO_CLERIC) { |
930 | // pl->last_save_tick += 100; |
930 | // pl->last_save_tick += 100; |
931 | // } else { |
931 | // } else { |
932 | save_player(pl->ob,1); |
932 | save_player(pl->ob,1); |
933 | pl->last_save_tick = pticks; |
933 | pl->last_save_tick = pticks; |
934 | // } |
934 | // } |
935 | } |
935 | } |
936 | #endif |
936 | #endif |
937 | } /* end of for loop for all the players */ |
937 | } /* end of for loop for all the players */ |
938 | } /* for flag */ |
938 | } /* for flag */ |
939 | for(pl=first_player;pl!=NULL;pl=pl->next) { |
939 | for(pl=first_player;pl!=NULL;pl=pl->next) { |
940 | if (map!=NULL && (pl->ob == NULL || pl->ob->map!=map)) |
940 | if (map!=NULL && (pl->ob == NULL || pl->ob->map!=map)) |
941 | continue; |
941 | continue; |
942 | if (settings.casting_time == TRUE) { |
942 | if (settings.casting_time == TRUE) { |
943 | if (pl->ob->casting_time > 0){ |
943 | if (pl->ob->casting_time > 0){ |
944 | pl->ob->casting_time--; |
944 | pl->ob->casting_time--; |
945 | pl->ob->start_holding = 1; |
945 | pl->ob->start_holding = 1; |
946 | } |
946 | } |
947 | /* set spell_state so we can update the range in stats field */ |
947 | /* set spell_state so we can update the range in stats field */ |
948 | if ((pl->ob->casting_time == 0) && (pl->ob->start_holding ==1)){ |
948 | if ((pl->ob->casting_time == 0) && (pl->ob->start_holding ==1)){ |
949 | pl->ob->start_holding = 0; |
949 | pl->ob->start_holding = 0; |
950 | } |
950 | } |
951 | } |
951 | } |
952 | do_some_living(pl->ob); |
952 | do_some_living(pl->ob); |
953 | /* draw(pl->ob);*/ /* updated in socket code */ |
953 | /* draw(pl->ob);*/ /* updated in socket code */ |
954 | } |
954 | } |
955 | } |
955 | } |
956 | |
956 | |
957 | void process_players2(mapstruct *map) |
957 | void process_players2(mapstruct *map) |
958 | { |
958 | { |
959 | player *pl; |
959 | player *pl; |
960 | |
960 | |
961 | /* Then check if any players should use weapon-speed instead of speed */ |
961 | /* Then check if any players should use weapon-speed instead of speed */ |
962 | for(pl=first_player;pl!=NULL;pl=pl->next) { |
962 | for(pl=first_player;pl!=NULL;pl=pl->next) { |
963 | if (map!=NULL) { |
963 | if (map!=NULL) { |
964 | if(pl->ob == NULL || QUERY_FLAG(pl->ob,FLAG_REMOVED)) |
964 | if(pl->ob == NULL || QUERY_FLAG(pl->ob,FLAG_REMOVED)) |
965 | continue; |
965 | continue; |
966 | else if(pl->loading != NULL) /* Player is blocked */ |
966 | else if(pl->loading != NULL) /* Player is blocked */ |
967 | pl->ob->speed_left -= pl->ob->speed; |
967 | pl->ob->speed_left -= pl->ob->speed; |
968 | if (pl->ob->map!=map) continue; |
968 | if (pl->ob->map!=map) continue; |
969 | } |
969 | } |
970 | |
970 | |
971 | /* The code that did weapon_sp handling here was out of place - |
971 | /* The code that did weapon_sp handling here was out of place - |
972 | * this isn't called until after the player has finished there |
972 | * this isn't called until after the player has finished there |
973 | * actions, and is thus out of place. All we do here is bounds |
973 | * actions, and is thus out of place. All we do here is bounds |
974 | * checking. |
974 | * checking. |
975 | */ |
975 | */ |
976 | if (pl->has_hit) { |
976 | if (pl->has_hit) { |
977 | if (pl->ob->speed_left > pl->weapon_sp) pl->ob->speed_left = pl->weapon_sp; |
977 | if (pl->ob->speed_left > pl->weapon_sp) pl->ob->speed_left = pl->weapon_sp; |
978 | |
978 | |
979 | /* This needs to be here - if the player is running, we need to |
979 | /* This needs to be here - if the player is running, we need to |
980 | * clear this each tick, but new commands are not being received |
980 | * clear this each tick, but new commands are not being received |
981 | * so execute_newserver_command() is never called |
981 | * so execute_newserver_command() is never called |
982 | */ |
982 | */ |
983 | pl->has_hit=0; |
983 | pl->has_hit=0; |
984 | |
984 | |
985 | } else if (pl->ob->speed_left>pl->ob->speed) |
985 | } else if (pl->ob->speed_left>pl->ob->speed) |
986 | pl->ob->speed_left = pl->ob->speed; |
986 | pl->ob->speed_left = pl->ob->speed; |
987 | } |
987 | } |
988 | } |
988 | } |
989 | |
989 | |
990 | #define SPEED_DEBUG |
990 | #define SPEED_DEBUG |
991 | |
991 | |
… | |
… | |
1001 | memset(&marker, 0, sizeof(object)); |
1001 | memset(&marker, 0, sizeof(object)); |
1002 | /* Put marker object at beginning of active list */ |
1002 | /* Put marker object at beginning of active list */ |
1003 | marker.active_next = active_objects; |
1003 | marker.active_next = active_objects; |
1004 | |
1004 | |
1005 | if (marker.active_next) |
1005 | if (marker.active_next) |
1006 | marker.active_next->active_prev = ▮ |
1006 | marker.active_next->active_prev = ▮ |
1007 | marker.active_prev = NULL; |
1007 | marker.active_prev = NULL; |
1008 | active_objects = ▮ |
1008 | active_objects = ▮ |
1009 | |
1009 | |
1010 | while (marker.active_next) { |
1010 | while (marker.active_next) { |
1011 | op = marker.active_next; |
1011 | op = marker.active_next; |
1012 | tag = op->count; |
1012 | tag = op->count; |
1013 | |
1013 | |
1014 | /* Move marker forward - swap op and marker */ |
1014 | /* Move marker forward - swap op and marker */ |
1015 | op->active_prev = marker.active_prev; |
1015 | op->active_prev = marker.active_prev; |
1016 | |
1016 | |
1017 | if (op->active_prev) |
1017 | if (op->active_prev) |
1018 | op->active_prev->active_next = op; |
1018 | op->active_prev->active_next = op; |
1019 | else |
1019 | else |
1020 | active_objects = op; |
1020 | active_objects = op; |
1021 | |
1021 | |
1022 | marker.active_next = op->active_next; |
1022 | marker.active_next = op->active_next; |
1023 | |
1023 | |
1024 | if (marker.active_next) |
1024 | if (marker.active_next) |
1025 | marker.active_next->active_prev = ▮ |
1025 | marker.active_next->active_prev = ▮ |
1026 | marker.active_prev = op; |
1026 | marker.active_prev = op; |
1027 | op->active_next = ▮ |
1027 | op->active_next = ▮ |
1028 | |
1028 | |
1029 | /* Now process op */ |
1029 | /* Now process op */ |
1030 | if (QUERY_FLAG (op, FLAG_FREED)) { |
1030 | if (QUERY_FLAG (op, FLAG_FREED)) { |
1031 | LOG (llevError, "BUG: process_events(): Free object on list\n"); |
1031 | LOG (llevError, "BUG: process_events(): Free object on list\n"); |
1032 | op->speed = 0; |
1032 | op->speed = 0; |
1033 | update_ob_speed (op); |
1033 | update_ob_speed (op); |
1034 | continue; |
1034 | continue; |
1035 | } |
1035 | } |
1036 | |
1036 | |
1037 | /* I've seen occasional crashes due to this - the object is removed, |
1037 | /* I've seen occasional crashes due to this - the object is removed, |
1038 | * and thus the map it points to (last map it was on) may be bogus |
1038 | * and thus the map it points to (last map it was on) may be bogus |
1039 | * The real bug is to try to find out the cause of this - someone |
1039 | * The real bug is to try to find out the cause of this - someone |
1040 | * is probably calling remove_ob without either an insert_ob or |
1040 | * is probably calling remove_ob without either an insert_ob or |
1041 | * free_object afterwards, leaving an object dangling. But I'd |
1041 | * free_object afterwards, leaving an object dangling. But I'd |
1042 | * rather log this and continue on instead of crashing. |
1042 | * rather log this and continue on instead of crashing. |
1043 | * Don't remove players - when a player quits, the object is in |
1043 | * Don't remove players - when a player quits, the object is in |
1044 | * sort of a limbo, of removed, but something we want to keep |
1044 | * sort of a limbo, of removed, but something we want to keep |
1045 | * around. |
1045 | * around. |
1046 | */ |
1046 | */ |
1047 | if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && |
1047 | if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && |
1048 | op->map && op->map->in_memory != MAP_IN_MEMORY) { |
1048 | op->map && op->map->in_memory != MAP_IN_MEMORY) { |
1049 | LOG (llevError, "BUG: process_events(): Removed object on list\n"); |
1049 | LOG (llevError, "BUG: process_events(): Removed object on list\n"); |
1050 | dump_object(op); |
1050 | dump_object(op); |
1051 | LOG(llevError, errmsg); |
1051 | LOG(llevError, errmsg); |
1052 | free_object(op); |
1052 | free_object(op); |
1053 | continue; |
1053 | continue; |
1054 | } |
1054 | } |
1055 | |
1055 | |
1056 | if ( ! op->speed) { |
1056 | if ( ! op->speed) { |
1057 | LOG (llevError, "BUG: process_events(): Object %s has no speed, " |
1057 | LOG (llevError, "BUG: process_events(): Object %s has no speed, " |
1058 | "but is on active list\n", op->arch->name); |
1058 | "but is on active list\n", op->arch->name); |
1059 | update_ob_speed (op); |
1059 | update_ob_speed (op); |
1060 | continue; |
1060 | continue; |
1061 | } |
1061 | } |
1062 | |
1062 | |
1063 | if (op->map == NULL && op->env == NULL && op->name && |
1063 | if (op->map == NULL && op->env == NULL && op->name && |
1064 | op->type != MAP && map == NULL) { |
1064 | op->type != MAP && map == NULL) { |
1065 | LOG (llevError, "BUG: process_events(): Object without map or " |
1065 | LOG (llevError, "BUG: process_events(): Object without map or " |
1066 | "inventory is on active list: %s (%d)\n", |
1066 | "inventory is on active list: %s (%d)\n", |
1067 | op->name, op->count); |
1067 | op->name, op->count); |
1068 | op->speed = 0; |
1068 | op->speed = 0; |
1069 | update_ob_speed (op); |
1069 | update_ob_speed (op); |
1070 | continue; |
1070 | continue; |
1071 | } |
1071 | } |
1072 | |
1072 | |
1073 | if (map != NULL && op->map != map) |
1073 | if (map != NULL && op->map != map) |
1074 | continue; |
1074 | continue; |
1075 | |
1075 | |
1076 | /* Animate the object. Bug of feature that andim_speed |
1076 | /* Animate the object. Bug of feature that andim_speed |
1077 | * is based on ticks, and not the creatures speed? |
1077 | * is based on ticks, and not the creatures speed? |
1078 | */ |
1078 | */ |
1079 | if (op->anim_speed && op->last_anim >= op->anim_speed) |
1079 | if (op->anim_speed && op->last_anim >= op->anim_speed) |
1080 | { |
1080 | { |
1081 | if ((op->type==PLAYER)||(op->type==MONSTER)) |
1081 | if ((op->type==PLAYER)||(op->type==MONSTER)) |
1082 | animate_object(op, op->facing); |
1082 | animate_object(op, op->facing); |
1083 | else |
1083 | else |
… | |
… | |
1086 | op->last_anim = 1; |
1086 | op->last_anim = 1; |
1087 | } |
1087 | } |
1088 | else |
1088 | else |
1089 | op->last_anim++; |
1089 | op->last_anim++; |
1090 | |
1090 | |
1091 | if (op->speed_left > 0) { |
1091 | if (op->speed_left > 0) { |
1092 | #if 0 |
1092 | #if 0 |
1093 | /* I've seen occasional crashes in move_symptom() with it |
1093 | /* I've seen occasional crashes in move_symptom() with it |
1094 | * crashing because op is removed - add some debugging to |
1094 | * crashing because op is removed - add some debugging to |
1095 | * track if it is removed at this point. |
1095 | * track if it is removed at this point. |
1096 | * This unfortunately is a bit too verbose it seems - not sure |
1096 | * This unfortunately is a bit too verbose it seems - not sure |
1097 | * why - I think what happens is a map is freed or something and |
1097 | * why - I think what happens is a map is freed or something and |
1098 | * some objects get 'lost' - removed never to be reclaimed. |
1098 | * some objects get 'lost' - removed never to be reclaimed. |
1099 | * removed objects generally shouldn't exist. |
1099 | * removed objects generally shouldn't exist. |
1100 | */ |
1100 | */ |
1101 | if (QUERY_FLAG(op, FLAG_REMOVED)) { |
1101 | if (QUERY_FLAG(op, FLAG_REMOVED)) { |
1102 | LOG(llevDebug,"process_events: calling process_object with removed object %s\n", |
1102 | LOG(llevDebug,"process_events: calling process_object with removed object %s\n", |
1103 | op->name?op->name:"null"); |
1103 | op->name?op->name:"null"); |
1104 | } |
1104 | } |
1105 | #endif |
1105 | #endif |
1106 | --op->speed_left; |
1106 | --op->speed_left; |
1107 | process_object (op); |
1107 | process_object (op); |
1108 | if (was_destroyed (op, tag)) |
1108 | if (was_destroyed (op, tag)) |
1109 | continue; |
1109 | continue; |
1110 | } |
1110 | } |
1111 | if (settings.casting_time == TRUE && op->casting_time > 0) |
1111 | if (settings.casting_time == TRUE && op->casting_time > 0) |
1112 | op->casting_time--; |
1112 | op->casting_time--; |
1113 | if (op->speed_left <= 0) |
1113 | if (op->speed_left <= 0) |
1114 | op->speed_left += FABS (op->speed); |
1114 | op->speed_left += FABS (op->speed); |
1115 | } |
1115 | } |
1116 | |
1116 | |
1117 | /* Remove marker object from active list */ |
1117 | /* Remove marker object from active list */ |
1118 | if (marker.active_prev != NULL) |
1118 | if (marker.active_prev != NULL) |
1119 | marker.active_prev->active_next = NULL; |
1119 | marker.active_prev->active_next = NULL; |
1120 | else |
1120 | else |
1121 | active_objects = NULL; |
1121 | active_objects = NULL; |
1122 | |
1122 | |
1123 | process_players2 (map); |
1123 | process_players2 (map); |
1124 | } |
1124 | } |
1125 | |
1125 | |
1126 | void clean_tmp_files(void) { |
1126 | void clean_tmp_files(void) { |
… | |
… | |
1133 | * just make a special function that only saves the unique items. |
1133 | * just make a special function that only saves the unique items. |
1134 | */ |
1134 | */ |
1135 | for(m=first_map;m!=NULL;m=next) { |
1135 | for(m=first_map;m!=NULL;m=next) { |
1136 | next=m->next; |
1136 | next=m->next; |
1137 | if (m->in_memory == MAP_IN_MEMORY) { |
1137 | if (m->in_memory == MAP_IN_MEMORY) { |
1138 | /* If we want to reuse the temp maps, swap it out (note that will also |
1138 | /* If we want to reuse the temp maps, swap it out (note that will also |
1139 | * update the log file. Otherwise, save the map (mostly for unique item |
1139 | * update the log file. Otherwise, save the map (mostly for unique item |
1140 | * stuff). Note that the clean_tmp_map is called after the end of |
1140 | * stuff). Note that the clean_tmp_map is called after the end of |
1141 | * the for loop but is in the #else bracket. IF we are recycling the maps, |
1141 | * the for loop but is in the #else bracket. IF we are recycling the maps, |
1142 | * we certainly don't want the temp maps removed. |
1142 | * we certainly don't want the temp maps removed. |
1143 | */ |
1143 | */ |
1144 | |
1144 | |
1145 | /* XXX The above comment is dead wrong */ |
1145 | /* XXX The above comment is dead wrong */ |
1146 | if (settings.recycle_tmp_maps == TRUE) |
1146 | if (settings.recycle_tmp_maps == TRUE) |
1147 | swap_map(m); |
1147 | swap_map(m); |
1148 | else { |
1148 | else { |
1149 | new_save_map(m, 0); /* note we save here into a overlay map */ |
1149 | new_save_map(m, 0); /* note we save here into a overlay map */ |
1150 | clean_tmp_map(m); |
1150 | clean_tmp_map(m); |
1151 | } |
1151 | } |
1152 | } |
1152 | } |
1153 | } |
1153 | } |
1154 | write_todclock(); /* lets just write the clock here */ |
1154 | write_todclock(); /* lets just write the clock here */ |
1155 | } |
1155 | } |
1156 | |
1156 | |
… | |
… | |
1178 | exit(0); |
1178 | exit(0); |
1179 | } |
1179 | } |
1180 | |
1180 | |
1181 | void leave(player *pl, int draw_exit) { |
1181 | void leave(player *pl, int draw_exit) { |
1182 | if (pl != NULL) { |
1182 | if (pl != NULL) { |
1183 | /* We do this so that the socket handling routine can do the final |
1183 | /* We do this so that the socket handling routine can do the final |
1184 | * cleanup. We also leave that loop to actually handle the freeing |
1184 | * cleanup. We also leave that loop to actually handle the freeing |
1185 | * of the data. |
1185 | * of the data. |
1186 | */ |
1186 | */ |
1187 | if (pl->ob->type != DEAD_OBJECT) |
1187 | if (pl->ob->type != DEAD_OBJECT) |
1188 | { |
1188 | { |
1189 | pl->socket.status = Ns_Dead; |
1189 | pl->socket.status = Ns_Dead; |
1190 | |
1190 | |
1191 | /* If a hidden dm dropped connection do not create |
1191 | /* If a hidden dm dropped connection do not create |
… | |
… | |
1226 | clock = time (NULL); |
1226 | clock = time (NULL); |
1227 | tm = (struct tm *) localtime (&clock); |
1227 | tm = (struct tm *) localtime (&clock); |
1228 | |
1228 | |
1229 | sprintf (buf, "%s/%s", settings.confdir, PERM_FILE); |
1229 | sprintf (buf, "%s/%s", settings.confdir, PERM_FILE); |
1230 | if ((fp = open_and_uncompress(buf, 0, &comp)) == NULL) |
1230 | if ((fp = open_and_uncompress(buf, 0, &comp)) == NULL) |
1231 | return 0; |
1231 | return 0; |
1232 | |
1232 | |
1233 | while (fgets (buf, MAX_BUF, fp)) { |
1233 | while (fgets (buf, MAX_BUF, fp)) { |
1234 | if (buf[0]=='#') continue; |
1234 | if (buf[0]=='#') continue; |
1235 | if (!strncmp (buf, "msg", 3)) { |
1235 | if (!strncmp (buf, "msg", 3)) { |
1236 | if (forbit) |
1236 | if (forbit) |
1237 | while (fgets (buf, MAX_BUF, fp)) /* print message */ |
1237 | while (fgets (buf, MAX_BUF, fp)) /* print message */ |
1238 | fputs (buf, logfile); |
1238 | fputs (buf, logfile); |
1239 | break; |
1239 | break; |
1240 | |
1240 | |
1241 | } else if (sscanf (buf, "%s %d%*c%d\n", day, &start, &stop) != 3) { |
1241 | } else if (sscanf (buf, "%s %d%*c%d\n", day, &start, &stop) != 3) { |
1242 | LOG(llevDebug, "Warning: Incomplete line in permission file ignored.\n"); |
1242 | LOG(llevDebug, "Warning: Incomplete line in permission file ignored.\n"); |
1243 | continue; |
1243 | continue; |
1244 | } |
1244 | } |
1245 | |
1245 | |
1246 | for (i=0; i< 7; i++) { |
1246 | for (i=0; i< 7; i++) { |
1247 | if (!strncmp (buf, days[i], 3) && (tm->tm_wday == i) && |
1247 | if (!strncmp (buf, days[i], 3) && (tm->tm_wday == i) && |
1248 | (tm->tm_hour >= start) && (tm->tm_hour < stop)) |
1248 | (tm->tm_hour >= start) && (tm->tm_hour < stop)) |
1249 | forbit = 1; |
1249 | forbit = 1; |
1250 | } |
1250 | } |
1251 | } |
1251 | } |
1252 | |
1252 | |
1253 | close_and_delete(fp, comp); |
1253 | close_and_delete(fp, comp); |
1254 | |
1254 | |
1255 | return forbit; |
1255 | return forbit; |
… | |
… | |
1276 | |
1276 | |
1277 | void do_specials(void) { |
1277 | void do_specials(void) { |
1278 | |
1278 | |
1279 | #ifdef WATCHDOG |
1279 | #ifdef WATCHDOG |
1280 | if (!(pticks % 503)) |
1280 | if (!(pticks % 503)) |
1281 | watchdog(); |
1281 | watchdog(); |
1282 | #endif |
1282 | #endif |
1283 | |
1283 | |
1284 | if (!(pticks % PTICKS_PER_CLOCK)) |
1284 | if (!(pticks % PTICKS_PER_CLOCK)) |
1285 | tick_the_clock(); |
1285 | tick_the_clock(); |
1286 | |
1286 | |
1287 | if (!(pticks % 509)) |
1287 | if (!(pticks % 79)) |
1288 | flush_old_maps(); /* Clears the tmp-files of maps which have reset */ |
1288 | flush_old_maps(); /* Clears the tmp-files of maps which have reset */ |
1289 | |
1289 | |
1290 | if (!(pticks % 2503)) |
1290 | if (!(pticks % 2503)) |
1291 | fix_weight(); /* Hack to fix weightproblems caused by bugs */ |
1291 | fix_weight(); /* Hack to fix weightproblems caused by bugs */ |
1292 | |
1292 | |
1293 | if (!(pticks % 2521)) |
1293 | if (!(pticks % 2521)) |
1294 | metaserver_update(); /* 2500 ticks is about 5 minutes */ |
1294 | metaserver_update(); /* 2500 ticks is about 5 minutes */ |
1295 | |
1295 | |
1296 | if (!(pticks % 5003)) |
1296 | if (!(pticks % 5003)) |
1297 | write_book_archive(); |
1297 | write_book_archive(); |
1298 | |
1298 | |
1299 | if (!(pticks % 5009)) |
1299 | if (!(pticks % 5009)) |
1300 | clean_friendly_list(); |
1300 | clean_friendly_list(); |
1301 | |
1301 | |
1302 | if (!(pticks % 5011)) |
1302 | if (!(pticks % 5011)) |
1303 | obsolete_parties(); |
1303 | obsolete_parties(); |
1304 | |
1304 | |
1305 | if (!(pticks % 12503)) |
1305 | if (!(pticks % 12503)) |
1306 | fix_luck(); |
1306 | fix_luck(); |
1307 | } |
1307 | } |
1308 | |
1308 | |
… | |
… | |
1323 | int main(int argc, char **argv) |
1323 | int main(int argc, char **argv) |
1324 | { |
1324 | { |
1325 | settings.argc = argc; |
1325 | settings.argc = argc; |
1326 | settings.argv = argv; |
1326 | settings.argv = argv; |
1327 | |
1327 | |
|
|
1328 | cfperl_init (); |
|
|
1329 | |
1328 | init (argc, argv); |
1330 | init (argc, argv); |
1329 | |
1331 | |
1330 | cfperl_init (); |
1332 | cfperl_boot (); |
1331 | initPlugins (); |
1333 | initPlugins (); |
1332 | |
1334 | |
1333 | for (;;) |
1335 | for (;;) |
1334 | cfperl_main (); |
1336 | cfperl_main (); |
1335 | |
1337 | |