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

Comparing deliantra/server/server/main.C (file contents):
Revision 1.22 by root, Sat Sep 9 21:48:29 2006 UTC vs.
Revision 1.51 by root, Thu Dec 21 06:12:37 2006 UTC

1/*
2 * static char *rcsid_main_c =
3 * "$Id: main.C,v 1.22 2006/09/09 21:48:29 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2001-2003 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001-2003 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#include <global.h> 24#include <global.h>
30#include <object.h> 25#include <object.h>
31#include <tod.h> 26#include <tod.h>
32 27
33#ifdef HAVE_DES_H 28#ifdef HAVE_DES_H
34#include <des.h> 29# include <des.h>
35#else 30#else
36# ifdef HAVE_CRYPT_H 31# ifdef HAVE_CRYPT_H
37# include <crypt.h> 32# include <crypt.h>
38# endif 33# endif
39#endif 34#endif
40 35
41#ifndef __CEXTRACT__
42#include <sproto.h> 36#include <sproto.h>
43#endif
44
45#ifdef HAVE_TIME_H
46#include <time.h> 37#include <time.h>
47#endif
48 38
49#include <../random_maps/random_map.h> 39#include <../random_maps/random_map.h>
50#include <../random_maps/rproto.h> 40#include <../random_maps/rproto.h>
51#include "path.h" 41#include "path.h"
52 42
53static char days[7][4] = { 43static char days[7][4] = {
54 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 44 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
55}; 45};
56 46
57void 47void
58version (object * op) 48version (object *op)
59{ 49{
60 if (op != NULL) 50 if (op != NULL)
61 clear_win_info (op); 51 clear_win_info (op);
62 52
63 new_draw_info_format (NDI_UNIQUE, 0, op, "This is Crossfire v%s", VERSION); 53 new_draw_info_format (NDI_UNIQUE, 0, op, "This is Crossfire v%s", VERSION);
111 new_draw_info (NDI_UNIQUE, 0, op, "Images and art:"); 101 new_draw_info (NDI_UNIQUE, 0, op, "Images and art:");
112 new_draw_info (NDI_UNIQUE, 0, op, "Peter Gardner"); 102 new_draw_info (NDI_UNIQUE, 0, op, "Peter Gardner");
113 new_draw_info (NDI_UNIQUE, 0, op, "David Gervais [david_eg@mail.com]"); 103 new_draw_info (NDI_UNIQUE, 0, op, "David Gervais [david_eg@mail.com]");
114 new_draw_info (NDI_UNIQUE, 0, op, "Mitsuhiro Itakura [ita@gold.koma.jaeri.go.jp]"); 104 new_draw_info (NDI_UNIQUE, 0, op, "Mitsuhiro Itakura [ita@gold.koma.jaeri.go.jp]");
115 new_draw_info (NDI_UNIQUE, 0, op, "Hansjoerg Malthaner [hansjoerg.malthaner@danet.de]"); 105 new_draw_info (NDI_UNIQUE, 0, op, "Hansjoerg Malthaner [hansjoerg.malthaner@danet.de]");
116 new_draw_info (NDI_UNIQUE, 0, op, "Mårten Woxberg [maxmc@telia.com]"); 106 new_draw_info (NDI_UNIQUE, 0, op, "MÃ¥rten Woxberg [maxmc@telia.com]");
117 new_draw_info (NDI_UNIQUE, 0, op, "And many more!"); 107 new_draw_info (NDI_UNIQUE, 0, op, "And many more!");
118} 108}
119 109
120void 110void
121info_keys (object * op) 111info_keys (object *op)
122{ 112{
123 clear_win_info (op); 113 clear_win_info (op);
124 new_draw_info (NDI_UNIQUE, 0, op, "Push `hjklynub' to walk in a direction."); 114 new_draw_info (NDI_UNIQUE, 0, op, "Push `hjklynub' to walk in a direction.");
125 new_draw_info (NDI_UNIQUE, 0, op, "Shift + dir = fire, Ctrl + dir = run"); 115 new_draw_info (NDI_UNIQUE, 0, op, "Shift + dir = fire, Ctrl + dir = run");
126 new_draw_info (NDI_UNIQUE, 0, op, "(To fire at yourself, hit `.'"); 116 new_draw_info (NDI_UNIQUE, 0, op, "(To fire at yourself, hit `.'");
139 new_draw_info (NDI_UNIQUE, 0, op, "You can type a number before most commands."); 129 new_draw_info (NDI_UNIQUE, 0, op, "You can type a number before most commands.");
140 new_draw_info (NDI_UNIQUE, 0, op, "(For instance 3d drops 3 items.)"); 130 new_draw_info (NDI_UNIQUE, 0, op, "(For instance 3d drops 3 items.)");
141} 131}
142 132
143void 133void
144start_info (object * op) 134start_info (object *op)
145{ 135{
146 char buf[MAX_BUF]; 136 char buf[MAX_BUF];
147 137
148 sprintf (buf, "Welcome to Crossfire, v%s!", VERSION); 138 sprintf (buf, "Welcome to Crossfire, v%s!", VERSION);
149 new_draw_info (NDI_UNIQUE, 0, op, buf); 139 new_draw_info (NDI_UNIQUE, 0, op, buf);
163 * simple case at top - no encryption - makes it easier to read. 153 * simple case at top - no encryption - makes it easier to read.
164 */ 154 */
165char * 155char *
166crypt_string (char *str, char *salt) 156crypt_string (char *str, char *salt)
167{ 157{
168#if defined(WIN32) || (defined(__FreeBSD__) && !defined(HAVE_LIBDES)) 158#if (defined(__FreeBSD__) && !defined(HAVE_LIBDES))
169 return (str); 159 return (str);
170#else 160#else
171 static char *c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; 161 static char *c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
172 char s[2]; 162 char s[2];
173 163
174 if (salt == NULL) 164 if (salt == NULL)
175 s[0] = c[RANDOM () % (int) strlen (c)], s[1] = c[RANDOM () % (int) strlen (c)]; 165 s[0] = c[RANDOM () % (int) strlen (c)], s[1] = c[RANDOM () % (int) strlen (c)];
176 else 166 else
177 s[0] = salt[0], s[1] = salt[1]; 167 s[0] = salt[0], s[1] = salt[1];
178 168
179# ifdef HAVE_LIBDES 169# ifdef HAVE_LIBDES
180 return (char *) des_crypt (str, s); 170 return (char *) des_crypt (str, s);
181# endif 171# endif
182 /* Default case - just use crypt */ 172 /* Default case - just use crypt */
183 return (char *) crypt (str, s); 173 return (char *) crypt (str, s);
184#endif 174#endif
185} 175}
186 176
194 * savebed. We do some error checking - its possible that the 184 * savebed. We do some error checking - its possible that the
195 * savebed map may no longer exist, so we make sure the player 185 * savebed map may no longer exist, so we make sure the player
196 * goes someplace. 186 * goes someplace.
197 */ 187 */
198void 188void
199enter_player_savebed (object * op) 189enter_player_savebed (object *op)
200{ 190{
201 mapstruct *oldmap = op->map; 191 maptile *oldmap = op->map;
202 object *tmp; 192 object *tmp;
203 193
204 tmp = get_object (); 194 tmp = object::create ();
205 195
206 EXIT_PATH (tmp) = op->contr->savebed_map; 196 EXIT_PATH (tmp) = op->contr->savebed_map;
207 EXIT_X (tmp) = op->contr->bed_x; 197 EXIT_X (tmp) = op->contr->bed_x;
208 EXIT_Y (tmp) = op->contr->bed_y; 198 EXIT_Y (tmp) = op->contr->bed_y;
209 enter_exit (op, tmp); 199 enter_exit (op, tmp);
222 EXIT_PATH (tmp) = op->contr->savebed_map; 212 EXIT_PATH (tmp) = op->contr->savebed_map;
223 EXIT_X (tmp) = op->contr->bed_x; 213 EXIT_X (tmp) = op->contr->bed_x;
224 EXIT_Y (tmp) = op->contr->bed_y; 214 EXIT_Y (tmp) = op->contr->bed_y;
225 enter_exit (op, tmp); 215 enter_exit (op, tmp);
226 } 216 }
227 free_object (tmp); 217
218 tmp->destroy ();
228} 219}
229 220
230/* All this really is is a glorified remove_object that also updates 221/* All this really is is a glorified remove_object that also updates
231 * the counts on the map if needed. 222 * the counts on the map if needed.
232 */ 223 */
233void 224void
234leave_map (object * op) 225leave_map (object *op)
235{ 226{
236 mapstruct *oldmap = op->map; 227 maptile *oldmap = op->map;
237 228
238 remove_ob (op); 229 op->remove ();
239 230
240 if (oldmap) 231 if (oldmap)
241 { 232 {
242 if (!op->contr->hidden) 233 if (!op->contr->hidden)
243 oldmap->players--; 234 oldmap->players--;
235
244 if (oldmap->players <= 0) 236 if (oldmap->players <= 0)
245 { /* can be less than zero due to errors in tracking this */ 237 /* can be less than zero due to errors in tracking this */
246 set_map_timeout (oldmap); 238 set_map_timeout (oldmap);
247 }
248 } 239 }
249} 240}
250 241
251/* 242/*
252 * enter_map(): Moves the player and pets from current map (if any) to 243 * enter_map(): Moves the player and pets from current map (if any) to
254 * player to - it could be the map he just came from if the load failed for 245 * player to - it could be the map he just came from if the load failed for
255 * whatever reason. If default map coordinates are to be used, then 246 * whatever reason. If default map coordinates are to be used, then
256 * the function that calls this should figure them out. 247 * the function that calls this should figure them out.
257 */ 248 */
258static void 249static void
259enter_map (object * op, mapstruct * newmap, int x, int y) 250enter_map (object *op, maptile *newmap, int x, int y)
260{ 251{
261 mapstruct *oldmap = op->map; 252 maptile *oldmap = op->map;
262 253
263 if (out_of_map (newmap, x, y)) 254 if (out_of_map (newmap, x, y))
264 { 255 {
265 LOG (llevError, "enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->path, x, y); 256 LOG (llevError, "enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->path, x, y);
266 x = MAP_ENTER_X (newmap); 257 x = MAP_ENTER_X (newmap);
271 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap)); 262 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap));
272 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed"); 263 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed");
273 return; 264 return;
274 } 265 }
275 } 266 }
267
276 /* try to find a spot for the player */ 268 /* try to find a spot for the player */
277 if (ob_blocked (op, newmap, x, y)) 269 if (ob_blocked (op, newmap, x, y))
278 { /* First choice blocked */ 270 { /* First choice blocked */
279 /* We try to find a spot for the player, starting closest in. 271 /* We try to find a spot for the player, starting closest in.
280 * We could use find_first_free_spot, but that doesn't randomize it at all, 272 * We could use find_first_free_spot, but that doesn't randomize it at all,
282 * if other spaces around are available. 274 * if other spaces around are available.
283 * Note that for the second and third calls, we could start at a position other 275 * Note that for the second and third calls, we could start at a position other
284 * than one, but then we could end up on the other side of walls and so forth. 276 * than one, but then we could end up on the other side of walls and so forth.
285 */ 277 */
286 int i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE1 + 1); 278 int i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE1 + 1);
279
287 if (i == -1) 280 if (i == -1)
288 { 281 {
289 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1); 282 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1);
290 if (i == -1) 283 if (i == -1)
291 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE); 284 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE);
292 } 285 }
286
293 if (i != -1) 287 if (i != -1)
294 { 288 {
295 x += freearr_x[i]; 289 x += freearr_x[i];
296 y += freearr_y[i]; 290 y += freearr_y[i];
297 } 291 }
300 /* not much we can do in this case. */ 294 /* not much we can do in this case. */
301 LOG (llevInfo, "enter_map: Could not find free spot for player - will dump on top of object (%s: %d, %d)\n", newmap->path, x, y); 295 LOG (llevInfo, "enter_map: Could not find free spot for player - will dump on top of object (%s: %d, %d)\n", newmap->path, x, y);
302 } 296 }
303 } /* end if looking for free spot */ 297 } /* end if looking for free spot */
304 298
305 if (op->map != NULL) 299 if (op->map)
306 {
307 INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (op->map), ARG_MAP (newmap));
308 INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)); 300 if (INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)))
309 } 301 return;
302
303 if (INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (newmap), ARG_INT (x), ARG_INT (y)))
304 return;
305
306 if (INVOKE_MAP (ENTER, newmap, ARG_PLAYER (op->contr), ARG_INT (x), ARG_INT (y)))
307 return;
310 308
311 /* If it is a player login, he has yet to be inserted anyplace. 309 /* If it is a player login, he has yet to be inserted anyplace.
312 * otherwise, we need to deal with removing the player here. 310 * otherwise, we need to deal with removing the player here.
313 */ 311 */
314 if (!QUERY_FLAG (op, FLAG_REMOVED)) 312 op->remove ();
315 remove_ob (op);
316 313
317 /* remove_ob clears these so they must be reset after the remove_ob call */ 314 /* remove_ob clears these so they must be reset after the remove_ob call */
318 op->x = x; 315 op->x = x;
319 op->y = y; 316 op->y = y;
320 op->map = newmap; 317 op->map = newmap;
318
321 insert_ob_in_map (op, op->map, NULL, INS_NO_WALK_ON); 319 insert_ob_in_map (op, op->map, NULL, INS_NO_WALK_ON);
322
323 INVOKE_MAP (ENTER, op->map, ARG_PLAYER (op->contr));
324 320
325 if (!op->contr->hidden) 321 if (!op->contr->hidden)
326 newmap->players++; 322 newmap->players++;
327 323
328 newmap->timeout = 0; 324 newmap->timeout = 0;
337 /* Update any golems */ 333 /* Update any golems */
338 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL) 334 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL)
339 { 335 {
340 int i = find_free_spot (op->contr->ranges[range_golem], newmap, 336 int i = find_free_spot (op->contr->ranges[range_golem], newmap,
341 x, y, 1, SIZEOFFREE); 337 x, y, 1, SIZEOFFREE);
338
342 remove_ob (op->contr->ranges[range_golem]); 339 op->contr->ranges[range_golem]->remove ();
340
343 if (i == -1) 341 if (i == -1)
344 { 342 {
345 remove_friendly_object (op->contr->ranges[range_golem]); 343 remove_friendly_object (op->contr->ranges[range_golem]);
346 free_object (op->contr->ranges[range_golem]); 344 op->contr->ranges[range_golem]->destroy ();
347 op->contr->ranges[range_golem] = NULL; 345 op->contr->ranges[range_golem] = 0;
348 op->contr->golem_count = 0;
349 } 346 }
350 else 347 else
351 { 348 {
352 object *tmp;
353 for (tmp = op->contr->ranges[range_golem]; tmp != NULL; tmp = tmp->more) 349 for (object *tmp = op->contr->ranges[range_golem]; tmp != NULL; tmp = tmp->more)
354 { 350 {
355 tmp->x = x + freearr_x[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x); 351 tmp->x = x + freearr_x[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x);
356 tmp->y = y + freearr_y[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y); 352 tmp->y = y + freearr_y[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y);
357 tmp->map = newmap; 353 tmp->map = newmap;
358 } 354 }
355
359 insert_ob_in_map (op->contr->ranges[range_golem], newmap, NULL, 0); 356 insert_ob_in_map (op->contr->ranges[range_golem], newmap, NULL, 0);
360 op->contr->ranges[range_golem]->direction = 357 op->contr->ranges[range_golem]->direction =
361 find_dir_2 (op->x - op->contr->ranges[range_golem]->x, op->y - op->contr->ranges[range_golem]->y); 358 find_dir_2 (op->x - op->contr->ranges[range_golem]->x, op->y - op->contr->ranges[range_golem]->y);
362 } 359 }
363 } 360 }
361
364 op->direction = 0; 362 op->direction = 0;
365 363
366 /* since the players map is already loaded, we don't need to worry 364 /* since the players map is already loaded, we don't need to worry
367 * about pending objects. 365 * about pending objects.
368 */ 366 */
383 } 381 }
384 } 382 }
385} 383}
386 384
387void 385void
388set_map_timeout (mapstruct * oldmap) 386set_map_timeout (maptile *oldmap)
389{ 387{
390#if MAP_MAXTIMEOUT 388#if MAP_MAXTIMEOUT
391 oldmap->timeout = MAP_TIMEOUT (oldmap); 389 oldmap->timeout = MAP_TIMEOUT (oldmap);
392 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is 390 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is
393 * lower than the min value. 391 * lower than the min value.
394 */ 392 */
395#if MAP_MINTIMEOUT 393# if MAP_MINTIMEOUT
396 if (oldmap->timeout < MAP_MINTIMEOUT) 394 if (oldmap->timeout < MAP_MINTIMEOUT)
397 {
398 oldmap->timeout = MAP_MINTIMEOUT; 395 oldmap->timeout = MAP_MINTIMEOUT;
399 }
400#endif 396# endif
397
401 if (oldmap->timeout > MAP_MAXTIMEOUT) 398 if (oldmap->timeout > MAP_MAXTIMEOUT)
402 {
403 oldmap->timeout = MAP_MAXTIMEOUT; 399 oldmap->timeout = MAP_MAXTIMEOUT;
404 } 400
405#else 401#else
406 /* save out the map */ 402 /* save out the map */
407 swap_map (oldmap); 403 swap_map (oldmap);
408#endif /* MAP_MAXTIMEOUT */ 404#endif /* MAP_MAXTIMEOUT */
409} 405}
414 */ 410 */
415char * 411char *
416clean_path (const char *file) 412clean_path (const char *file)
417{ 413{
418 static char newpath[MAX_BUF], *cp; 414 static char newpath[MAX_BUF], *cp;
415 assign (newpath, file);
419 416
420 strncpy (newpath, file, MAX_BUF - 1);
421 newpath[MAX_BUF - 1] = '\0';
422 for (cp = newpath; *cp != '\0'; cp++) 417 for (cp = newpath; *cp != '\0'; cp++)
423 {
424 if (*cp == '/') 418 if (*cp == '/')
425 *cp = '_'; 419 *cp = '_';
426 } 420
427 return newpath; 421 return newpath;
428} 422}
429 423
430 424
431/* unclean_path takes a path and replaces all _ with / 425/* unclean_path takes a path and replaces all _ with /
439unclean_path (const char *src) 433unclean_path (const char *src)
440{ 434{
441 static char newpath[MAX_BUF], *cp; 435 static char newpath[MAX_BUF], *cp;
442 436
443 cp = strrchr (src, '/'); 437 cp = strrchr (src, '/');
444 if (cp) 438 assign (newpath, cp ? cp + 1 : src);
445 strncpy (newpath, cp + 1, MAX_BUF - 1);
446 else
447 strncpy (newpath, src, MAX_BUF - 1);
448 newpath[MAX_BUF - 1] = '\0';
449 439
450 for (cp = newpath; *cp != '\0'; cp++) 440 for (cp = newpath; *cp != '\0'; cp++)
451 {
452 if (*cp == '_') 441 if (*cp == '_')
453 *cp = '/'; 442 *cp = '/';
454 } 443
455 return newpath; 444 return newpath;
456} 445}
457 446
458 447
459/* The player is trying to enter a randomly generated map. In this case, generate the 448/* The player is trying to enter a randomly generated map. In this case, generate the
460 * random map as needed. 449 * random map as needed.
461 */ 450 */
462 451
463static void 452static void
464enter_random_map (object * pl, object * exit_ob) 453enter_random_map (object *pl, object *exit_ob)
465{ 454{
466 mapstruct *new_map; 455 maptile *new_map;
467 char newmap_name[HUGE_BUF], *cp; 456 char newmap_name[HUGE_BUF], *cp;
468 static int reference_number = 0; 457 static int reference_number = 0;
469 RMParms rp; 458 RMParms rp;
470 459
471 memset (&rp, 0, sizeof (RMParms)); 460 memset (&rp, 0, sizeof (RMParms));
478 rp.origin_y = exit_ob->y; 467 rp.origin_y = exit_ob->y;
479 strcpy (rp.origin_map, pl->map->path); 468 strcpy (rp.origin_map, pl->map->path);
480 469
481 /* If we have a final_map, use it as a base name to give some clue 470 /* If we have a final_map, use it as a base name to give some clue
482 * as where the player is. Otherwise, use the origin map. 471 * as where the player is. Otherwise, use the origin map.
483 * Take the last component (after the last slash) to give
484 * shorter names without bogus slashes.
485 */ 472 */
486 if (rp.final_map[0]) 473 sprintf (newmap_name, "/random%s+%04d",
487 { 474 *rp.final_map ? rp.final_map : rp.origin_map,
488 cp = strrchr (rp.final_map, '/'); 475 reference_number++);
489 if (!cp)
490 cp = rp.final_map;
491 }
492 else
493 {
494 char buf[HUGE_BUF];
495
496 cp = strrchr (rp.origin_map, '/');
497 if (!cp)
498 cp = rp.origin_map;
499 /* Need to strip of any trailing digits, if it has them */
500 strcpy (buf, cp);
501 while (isdigit (buf[strlen (buf) - 1]))
502 buf[strlen (buf) - 1] = 0;
503 cp = buf;
504 }
505
506 sprintf (newmap_name, "/random/%s%04d", cp + 1, reference_number++);
507 476
508 /* now to generate the actual map. */ 477 /* now to generate the actual map. */
509 new_map = generate_random_map (newmap_name, &rp); 478 new_map = generate_random_map (newmap_name, &rp);
510 479
511 /* Update the exit_ob so it now points directly at the newly created 480 /* Update the exit_ob so it now points directly at the newly created
515 * the exit leading to it, that the exit will no longer work. 484 * the exit leading to it, that the exit will no longer work.
516 */ 485 */
517 if (new_map) 486 if (new_map)
518 { 487 {
519 int x, y; 488 int x, y;
489
520 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map); 490 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map);
521 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map); 491 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map);
522 EXIT_PATH (exit_ob) = newmap_name; 492 EXIT_PATH (exit_ob) = newmap_name;
523 strcpy (new_map->path, newmap_name); 493 strcpy (new_map->path, newmap_name);
524 enter_map (pl, new_map, x, y); 494 enter_map (pl, new_map, x, y);
528/* The player is trying to enter a non-randomly generated template map. In this 498/* The player is trying to enter a non-randomly generated template map. In this
529 * case, use a map file for a template 499 * case, use a map file for a template
530 */ 500 */
531 501
532static void 502static void
533enter_fixed_template_map (object * pl, object * exit_ob) 503enter_fixed_template_map (object *pl, object *exit_ob)
534{ 504{
535 mapstruct *new_map; 505 maptile *new_map;
536 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap; 506 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap;
537 const char *new_map_name; 507 const char *new_map_name;
538 508
539 /* Split the exit path string into two parts, one 509 /* Split the exit path string into two parts, one
540 * for where to store the map, and one for were 510 * for where to store the map, and one for were
549 */ 519 */
550 LOG (llevError, "enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n", 520 LOG (llevError, "enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n",
551 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); 521 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
552 return; 522 return;
553 } 523 }
524
554 *sourcemap++ = '\0'; 525 *sourcemap++ = '\0';
555 526
556 /* If we are not coming from a template map, we can use relative directories 527 /* If we are not coming from a template map, we can use relative directories
557 * for the map to generate from. 528 * for the map to generate from.
558 */ 529 */
559 if (!exit_ob->map->templatemap) 530 if (!exit_ob->map->templatemap)
560 {
561 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap); 531 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap);
562 }
563 532
564 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 533 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord
565 * of the exit, and the name of the map the exit is on, respectively. 534 * of the exit, and the name of the map the exit is on, respectively.
566 */ 535 */
567 sprintf (tmpnum, "%d", exit_ob->x); 536 sprintf (tmpnum, "%d", exit_ob->x);
576 545
577 /* If we are coming from another template map, use reletive paths unless 546 /* If we are coming from another template map, use reletive paths unless
578 * indicated otherwise. 547 * indicated otherwise.
579 */ 548 */
580 if (exit_ob->map->templatemap && (resultname[0] != '/')) 549 if (exit_ob->map->templatemap && (resultname[0] != '/'))
581 {
582 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname); 550 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname);
583 }
584 else 551 else
585 {
586 new_map_name = create_template_pathname (resultname); 552 new_map_name = create_template_pathname (resultname);
587 }
588 553
589 /* Attempt to load the map, if unable to, then 554 /* Attempt to load the map, if unable to, then
590 * create the map from the template. 555 * create the map from the template.
591 */ 556 */
592 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE); 557 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE);
614 LOG (llevDebug, "enter_fixed_template_map: Exit %s (%d,%d) on map %s leads no where.\n", 579 LOG (llevDebug, "enter_fixed_template_map: Exit %s (%d,%d) on map %s leads no where.\n",
615 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); 580 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
616 } 581 }
617} 582}
618 583
619
620/* The player is trying to enter a randomly generated template map. In this 584/* The player is trying to enter a randomly generated template map. In this
621 * case, generate the map as needed. 585 * case, generate the map as needed.
622 */ 586 */
623 587
624static void 588static void
625enter_random_template_map (object * pl, object * exit_ob) 589enter_random_template_map (object *pl, object *exit_ob)
626{ 590{
627 mapstruct *new_map; 591 maptile *new_map;
628 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF]; 592 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF];
629 const char *new_map_name; 593 const char *new_map_name;
630 RMParms rp; 594 RMParms rp;
631 595
632 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 596 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord
679 * the exit leading to it, that the exit will no longer work. 643 * the exit leading to it, that the exit will no longer work.
680 */ 644 */
681 if (new_map) 645 if (new_map)
682 { 646 {
683 int x, y; 647 int x, y;
648
684 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map); 649 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map);
685 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map); 650 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map);
686 new_map->templatemap = 1; 651 new_map->templatemap = 1;
687 enter_map (pl, new_map, x, y); 652 enter_map (pl, new_map, x, y);
688 } 653 }
690 655
691 656
692/* Code to enter/detect a character entering a unique map. 657/* Code to enter/detect a character entering a unique map.
693 */ 658 */
694static void 659static void
695enter_unique_map (object * op, object * exit_ob) 660enter_unique_map (object *op, object *exit_ob)
696{ 661{
697 char apartment[HUGE_BUF]; 662 char apartment[HUGE_BUF];
698 mapstruct *newmap; 663 maptile *newmap;
699 664
700 if (EXIT_PATH (exit_ob)[0] == '/') 665 if (EXIT_PATH (exit_ob)[0] == '/')
701 { 666 {
702 sprintf (apartment, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, clean_path (EXIT_PATH (exit_ob))); 667 sprintf (apartment, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, clean_path (EXIT_PATH (exit_ob)));
703 newmap = ready_map_name (apartment, MAP_PLAYER_UNIQUE); 668 newmap = ready_map_name (apartment, MAP_PLAYER_UNIQUE);
780 * Largely redone by MSW 2001-01-21 - this function was overly complex 745 * Largely redone by MSW 2001-01-21 - this function was overly complex
781 * and had some obscure bugs. 746 * and had some obscure bugs.
782 */ 747 */
783 748
784void 749void
785enter_exit (object * op, object * exit_ob) 750enter_exit (object *op, object *exit_ob)
786{ 751{
787#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */ 752#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */
788 object *tmp; 753 object *tmp;
754
789 /* It may be nice to support other creatures moving across 755 /* It may be nice to support other creatures moving across
790 * exits, but right now a lot of the code looks at op->contr, 756 * exits, but right now a lot of the code looks at op->contr,
791 * so thta is an RFE. 757 * so that is an RFE.
792 */ 758 */
793 if (op->type != PLAYER) 759 if (op->type != PLAYER)
794 return; 760 return;
795 761
796 /* First, lets figure out what map the player is going to go to */ 762 /* First, lets figure out what map the player is going to go to */
797 if (exit_ob) 763 if (exit_ob)
798 { 764 {
799
800 /* check to see if we make a template map */ 765 /* check to see if we make a template map */
801 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@') 766 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@')
802 { 767 {
803 if (EXIT_PATH (exit_ob)[2] == '!') 768 if (EXIT_PATH (exit_ob)[2] == '!')
804 { 769 {
821 enter_unique_map (op, exit_ob); 786 enter_unique_map (op, exit_ob);
822 } 787 }
823 else 788 else
824 { 789 {
825 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob); 790 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob);
791
826 /* 'Normal' exits that do not do anything special 792 /* 'Normal' exits that do not do anything special
827 * Simple enough we don't need another routine for it. 793 * Simple enough we don't need another routine for it.
828 */ 794 */
829 mapstruct *newmap; 795 maptile *newmap;
796
830 if (exit_ob->map) 797 if (exit_ob->map)
831 { 798 {
832 newmap = ready_map_name (path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)), 0); 799 newmap = ready_map_name (path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)), 0);
833 /* Random map was previously generated, but is no longer about. Lets generate a new 800 /* Random map was previously generated, but is no longer about. Lets generate a new
834 * map. 801 * map.
901 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME)) 868 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME))
902 break; 869 break;
903 } 870 }
904 if (tmp) 871 if (tmp)
905 { 872 {
906 remove_ob (tmp); 873 tmp->remove ();
907 free_object (tmp); 874 tmp->destroy ();
908 } 875 }
909 876
910 strcpy (op->contr->savebed_map, path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob))); 877 strcpy (op->contr->savebed_map, path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)));
911 op->contr->bed_x = EXIT_X (exit_ob), op->contr->bed_y = EXIT_Y (exit_ob); 878 op->contr->bed_x = EXIT_X (exit_ob), op->contr->bed_y = EXIT_Y (exit_ob);
912 save_player (op, 1); 879 save_player (op, 1);
922 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1); 889 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
923 } 890 }
924 else 891 else
925 { 892 {
926 int flags = 0; 893 int flags = 0;
927 mapstruct *newmap; 894 maptile *newmap;
928
929 895
930 /* Hypothetically, I guess its possible that a standard map matches 896 /* Hypothetically, I guess its possible that a standard map matches
931 * the localdir, but that seems pretty unlikely - unlikely enough that 897 * the localdir, but that seems pretty unlikely - unlikely enough that
932 * I'm not going to attempt to try to deal with that possibility. 898 * I'm not going to attempt to try to deal with that possibility.
933 * We use the fact that when a player saves on a unique map, it prepends 899 * We use the fact that when a player saves on a unique map, it prepends
954 { 920 {
955 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n"); 921 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n");
956 abort (); 922 abort ();
957 } 923 }
958 } 924 }
925
959 enter_map (op, newmap, op->x, op->y); 926 enter_map (op, newmap, op->x, op->y);
960 } 927 }
961} 928}
962
963/*
964 * process_active_maps(): Works like process_events(), but it only
965 * processes maps which a player is on.
966 *
967 */
968
969#if 0 // dead code, schmorp
970void
971process_active_maps ()
972{
973 for (mapstruct * map = first_map; map != NULL; map = map->next)
974 if (map->in_memory == MAP_IN_MEMORY)
975 if (players_on_map (map, TRUE))
976 process_events (map);
977}
978#endif
979 929
980/* process_players1 and process_players2 do all the player related stuff. 930/* process_players1 and process_players2 do all the player related stuff.
981 * I moved it out of process events and process_map. This was to some 931 * I moved it out of process events and process_map. This was to some
982 * extent for debugging as well as to get a better idea of the time used 932 * extent for debugging as well as to get a better idea of the time used
983 * by the various functions. process_players1() does the processing before 933 * by the various functions. process_players1() does the processing before
984 * objects have been updated, process_players2() does the processing that 934 * objects have been updated, process_players2() does the processing that
985 * is needed after the players have been updated. 935 * is needed after the players have been updated.
986 */ 936 */
987 937static void
988void 938process_players1 ()
989process_players1 (mapstruct * map)
990{ 939{
991 int flag; 940 int flag;
992 player *pl, *plnext;
993
994 /* Basically, we keep looping until all the players have done their actions. */ 941 /* Basically, we keep looping until all the players have done their actions. */
995 for (flag = 1; flag != 0;) 942 for (flag = 1; flag != 0;)
996 { 943 {
997 flag = 0; 944 flag = 0;
998 for (pl = first_player; pl != NULL; pl = plnext) 945 for (player *plnext, *pl = first_player; pl; pl = plnext)
999 { 946 {
1000 plnext = pl->next; /* In case a player exits the game in handle_player() */ 947 plnext = pl->next; /* In case a player exits the game in handle_player() */
1001 948
1002 if (pl->ob == NULL) 949 if (!pl->ob)
1003 continue;
1004
1005 if (map != NULL && pl->ob->map != map)
1006 continue; 950 continue;
1007 951
1008 if (pl->ob->speed_left > 0) 952 if (pl->ob->speed_left > 0)
1009 { 953 {
1010 if (handle_newcs_player (pl->ob)) 954 if (handle_newcs_player (pl->ob))
1024 /* check for ST_PLAYING state so that we don't try to save off when 968 /* check for ST_PLAYING state so that we don't try to save off when
1025 * the player is logging in. 969 * the player is logging in.
1026 */ 970 */
1027 if ((pl->last_save_tick + AUTOSAVE) < (uint32) pticks && pl->state == ST_PLAYING) 971 if ((pl->last_save_tick + AUTOSAVE) < (uint32) pticks && pl->state == ST_PLAYING)
1028 { 972 {
1029 /* Don't save the player on unholy ground. Instead, increase the
1030 * tick time so it will be about 10 seconds before we try and save
1031 * again.
1032 */
1033// if (get_map_flags(pl->ob->map, NULL, pl->ob->x, pl->ob->y, NULL, NULL) & P_NO_CLERIC) {
1034// pl->last_save_tick += 100;
1035// } else {
1036 save_player (pl->ob, 1); 973 save_player (pl->ob, 1);
1037 pl->last_save_tick = pticks; 974 pl->last_save_tick = pticks;
1038// }
1039 } 975 }
1040#endif 976#endif
1041 } /* end of for loop for all the players */ 977 } /* end of for loop for all the players */
1042 } /* for flag */ 978 } /* for flag */
979
1043 for (pl = first_player; pl != NULL; pl = pl->next) 980 for (player *pl = first_player; pl; pl = pl->next)
1044 { 981 {
1045 if (map != NULL && (pl->ob == NULL || pl->ob->map != map))
1046 continue;
1047 if (settings.casting_time == TRUE) 982 if (settings.casting_time)
1048 { 983 {
1049 if (pl->ob->casting_time > 0) 984 if (pl->ob->casting_time > 0)
1050 { 985 {
1051 pl->ob->casting_time--; 986 pl->ob->casting_time--;
1052 pl->ob->start_holding = 1; 987 pl->ob->start_holding = 1;
1053 } 988 }
989
1054 /* set spell_state so we can update the range in stats field */ 990 /* set spell_state so we can update the range in stats field */
1055 if ((pl->ob->casting_time == 0) && (pl->ob->start_holding == 1)) 991 if ((pl->ob->casting_time == 0) && (pl->ob->start_holding == 1))
1056 {
1057 pl->ob->start_holding = 0; 992 pl->ob->start_holding = 0;
1058 } 993 }
1059 } 994
1060 do_some_living (pl->ob); 995 do_some_living (pl->ob);
1061 /* draw(pl->ob);*//* updated in socket code */
1062 } 996 }
1063} 997}
1064 998
1065void 999static void
1066process_players2 (mapstruct * map) 1000process_players2 ()
1067{ 1001{
1068 player *pl;
1069
1070 /* Then check if any players should use weapon-speed instead of speed */ 1002 /* Then check if any players should use weapon-speed instead of speed */
1071 for (pl = first_player; pl != NULL; pl = pl->next) 1003 for (player *pl = first_player; pl; pl = pl->next)
1072 { 1004 {
1073 if (map != NULL)
1074 {
1075 if (pl->ob == NULL || QUERY_FLAG (pl->ob, FLAG_REMOVED))
1076 continue;
1077 else if (pl->loading != NULL) /* Player is blocked */
1078 pl->ob->speed_left -= pl->ob->speed;
1079 if (pl->ob->map != map)
1080 continue;
1081 }
1082
1083 /* The code that did weapon_sp handling here was out of place - 1005 /* The code that did weapon_sp handling here was out of place -
1084 * this isn't called until after the player has finished there 1006 * this isn't called until after the player has finished there
1085 * actions, and is thus out of place. All we do here is bounds 1007 * actions, and is thus out of place. All we do here is bounds
1086 * checking. 1008 * checking.
1087 */ 1009 */
1093 /* This needs to be here - if the player is running, we need to 1015 /* This needs to be here - if the player is running, we need to
1094 * clear this each tick, but new commands are not being received 1016 * clear this each tick, but new commands are not being received
1095 * so execute_newserver_command() is never called 1017 * so execute_newserver_command() is never called
1096 */ 1018 */
1097 pl->has_hit = 0; 1019 pl->has_hit = 0;
1098
1099 } 1020 }
1100 else if (pl->ob->speed_left > pl->ob->speed) 1021 else if (pl->ob->speed_left > pl->ob->speed)
1101 pl->ob->speed_left = pl->ob->speed; 1022 pl->ob->speed_left = pl->ob->speed;
1102 } 1023 }
1103} 1024}
1104 1025
1105void 1026void
1106process_events (mapstruct * map) 1027process_events ()
1107{ 1028{
1108 object *op; 1029 object *op;
1109 object *marker = get_object ();
1110 tag_t tag;
1111 1030
1031 static object *marker;
1032
1033 if (!marker)
1034 marker = object::create ();
1035
1112 process_players1 (map); 1036 process_players1 ();
1113 1037
1114 marker->active_next = active_objects; 1038 marker->active_next = active_objects;
1115 1039
1116 if (marker->active_next) 1040 if (marker->active_next)
1117 marker->active_next->active_prev = marker; 1041 marker->active_next->active_prev = marker;
1120 active_objects = marker; 1044 active_objects = marker;
1121 1045
1122 while (marker->active_next) 1046 while (marker->active_next)
1123 { 1047 {
1124 op = marker->active_next; 1048 op = marker->active_next;
1125 tag = op->count;
1126 1049
1127 /* Move marker forward - swap op and marker */ 1050 /* Move marker forward - swap op and marker */
1128 op->active_prev = marker->active_prev; 1051 op->active_prev = marker->active_prev;
1129 1052
1130 if (op->active_prev) 1053 if (op->active_prev)
1160 * around. 1083 * around.
1161 */ 1084 */
1162 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY) 1085 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY)
1163 { 1086 {
1164 LOG (llevError, "BUG: process_events(): Removed object on list\n"); 1087 LOG (llevError, "BUG: process_events(): Removed object on list\n");
1165 dump_object (op); 1088 char *dump = dump_object (op);
1166 LOG (llevError, errmsg); 1089 LOG (llevError, dump);
1167 free_object (op); 1090 free (dump);
1091 op->destroy ();
1168 continue; 1092 continue;
1169 } 1093 }
1170 1094
1171 if (!op->speed) 1095 if (!op->speed)
1172 { 1096 {
1173 LOG (llevError, "BUG: process_events(): Object %s has no speed, " "but is on active list\n", &op->arch->name); 1097 LOG (llevError, "BUG: process_events(): Object %s has no speed, "
1098 "but is on active list\n", &op->arch->name);
1174 update_ob_speed (op); 1099 update_ob_speed (op);
1175 continue; 1100 continue;
1176 } 1101 }
1177 1102
1178 if (op->map == NULL && op->env == NULL && op->name && op->type != MAP && map == NULL) 1103 if (op->map == NULL && op->env == NULL && op->name && op->type != MAP)
1179 { 1104 {
1180 LOG (llevError, "BUG: process_events(): Object without map or " "inventory is on active list: %s (%d)\n", &op->name, op->count); 1105 LOG (llevError, "BUG: process_events(): Object without map or "
1106 "inventory is on active list: %s (%d)\n", &op->name, op->count);
1181 op->speed = 0; 1107 op->speed = 0;
1182 update_ob_speed (op); 1108 update_ob_speed (op);
1183 continue; 1109 continue;
1184 } 1110 }
1185 1111
1186 if (map != NULL && op->map != map)
1187 continue;
1188
1189 /* Animate the object. Bug of feature that andim_speed 1112 /* Animate the object. Bug or feature that anim_speed
1190 * is based on ticks, and not the creatures speed? 1113 * is based on ticks, and not the creatures speed?
1191 */ 1114 */
1192 if (op->anim_speed && op->last_anim >= op->anim_speed) 1115 if (op->anim_speed && op->last_anim >= op->anim_speed)
1193 { 1116 {
1194 if ((op->type == PLAYER) || (op->type == MONSTER)) 1117 if ((op->type == PLAYER))
1195 animate_object (op, op->facing); 1118 animate_object (op, op->facing);
1196 else 1119 else
1197 animate_object (op, op->direction); 1120 animate_object (op, op->direction);
1198 1121
1199 op->last_anim = 1; 1122 op->last_anim = 1;
1217 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null"); 1140 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null");
1218 } 1141 }
1219#endif 1142#endif
1220 --op->speed_left; 1143 --op->speed_left;
1221 process_object (op); 1144 process_object (op);
1145
1222 if (was_destroyed (op, tag)) 1146 if (op->destroyed ())
1223 continue; 1147 continue;
1224 } 1148 }
1149
1225 if (settings.casting_time == TRUE && op->casting_time > 0) 1150 if (settings.casting_time == TRUE && op->casting_time > 0)
1226 op->casting_time--; 1151 op->casting_time--;
1152
1227 if (op->speed_left <= 0) 1153 if (op->speed_left <= 0)
1228 op->speed_left += FABS (op->speed); 1154 op->speed_left += FABS (op->speed);
1229 } 1155 }
1230 1156
1231 /* Remove marker object from active list */ 1157 /* Remove marker object from active list */
1232 if (marker->active_prev != NULL) 1158 if (marker->active_prev != NULL)
1233 marker->active_prev->active_next = NULL; 1159 marker->active_prev->active_next = NULL;
1234 else 1160 else
1235 active_objects = NULL; 1161 active_objects = NULL;
1236 1162
1237 process_players2 (map); 1163 process_players2 ();
1238
1239 free_object (marker);
1240} 1164}
1241 1165
1242void 1166void
1243clean_tmp_files (void) 1167clean_tmp_files (void)
1244{ 1168{
1245 mapstruct *m, *next; 1169 maptile *m, *next;
1246 1170
1247 LOG (llevInfo, "Cleaning up...\n"); 1171 LOG (llevInfo, "Cleaning up...\n");
1248 1172
1249 /* We save the maps - it may not be intuitive why, but if there are unique 1173 /* We save the maps - it may not be intuitive why, but if there are unique
1250 * items, we need to save the map so they get saved off. Perhaps we should 1174 * items, we need to save the map so they get saved off. Perhaps we should
1251 * just make a special function that only saves the unique items. 1175 * just make a special function that only saves the unique items.
1252 */ 1176 */
1253 for (m = first_map; m != NULL; m = next) 1177 for (m = first_map; m; m = next)
1254 { 1178 {
1255 next = m->next; 1179 next = m->next;
1180
1256 if (m->in_memory == MAP_IN_MEMORY) 1181 if (m->in_memory == MAP_IN_MEMORY)
1257 { 1182 {
1258 /* If we want to reuse the temp maps, swap it out (note that will also 1183 /* If we want to reuse the temp maps, swap it out (note that will also
1259 * update the log file. Otherwise, save the map (mostly for unique item 1184 * update the log file.
1260 * stuff). Note that the clean_tmp_map is called after the end of
1261 * the for loop but is in the #else bracket. IF we are recycling the maps,
1262 * we certainly don't want the temp maps removed.
1263 */ 1185 */
1264 1186
1265 /* XXX The above comment is dead wrong */
1266 if (settings.recycle_tmp_maps == TRUE)
1267 swap_map (m); 1187 swap_map (m);
1268 else
1269 {
1270 new_save_map (m, 0); /* note we save here into a overlay map */
1271 clean_tmp_map (m);
1272 } 1188 }
1273 }
1274 } 1189 }
1190
1275 write_todclock (); /* lets just write the clock here */ 1191 write_todclock (); /* lets just write the clock here */
1276} 1192}
1277 1193
1278/* clean up everything before exiting */ 1194/* clean up everything before exiting */
1279void 1195void
1280cleanup (void) 1196cleanup (bool make_core)
1281{ 1197{
1282 LOG (llevDebug, "Cleanup called. freeing data.\n"); 1198 LOG (llevDebug, "Cleanup called.\n");
1199
1200 if (init_done)
1201 {
1202 for (player *pl = first_player; pl != NULL; pl = pl->next)
1203 save_player (pl->ob, 0);
1204
1205 for (player *pl = first_player; pl != NULL; pl = pl->next)
1206 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1207 leave_map (pl->ob);
1208
1283 clean_tmp_files (); 1209 clean_tmp_files ();
1284 write_book_archive (); 1210 write_book_archive ();
1285#ifdef MEMORY_DEBUG 1211
1286 free_all_maps (); 1212 INVOKE_GLOBAL (CLEANUP);
1287 free_style_maps (); 1213 }
1288 free_all_object_data (); 1214
1289 free_all_archs (); 1215 if (make_core)
1290 free_all_treasures (); 1216 abort ();
1291 free_all_images (); 1217 else
1292 free_all_newserver ();
1293 free_all_recipes ();
1294 free_all_readable ();
1295 free_all_god ();
1296 free_all_anim ();
1297 /* See what the string data that is out there that hasn't been freed. */
1298/* LOG(llevDebug, ss_dump_table(0xff));*/
1299#endif
1300 exit (0); 1218 _exit (0);
1301} 1219}
1302 1220
1303void 1221void
1304leave (player * pl, int draw_exit) 1222leave (player *pl, int draw_exit)
1305{ 1223{
1306 if (pl != NULL) 1224 if (pl)
1307 { 1225 {
1308 /* We do this so that the socket handling routine can do the final 1226 /* We do this so that the socket handling routine can do the final
1309 * cleanup. We also leave that loop to actually handle the freeing 1227 * cleanup. We also leave that loop to actually handle the freeing
1310 * of the data. 1228 * of the data.
1311 */ 1229 */
1230 if (pl->socket)
1231 pl->socket->destroy ();
1232
1312 if (pl->ob->type != DEAD_OBJECT) 1233 if (pl->ob->type != DEAD_OBJECT)
1313 { 1234 {
1314 pl->socket.status = Ns_Dead;
1315
1316 /* If a hidden dm dropped connection do not create 1235 /* If a hidden dm dropped connection do not create
1317 * inconsistencies by showing that they have left the game 1236 * inconsistencies by showing that they have left the game
1318 */ 1237 */
1319 if (!(QUERY_FLAG (pl->ob, FLAG_WIZ) && pl->ob->contr->hidden) 1238 if (!(QUERY_FLAG (pl->ob, FLAG_WIZ) && pl->ob->contr->hidden)
1320 && draw_exit && (pl->state != ST_GET_NAME && pl->state != ST_GET_PASSWORD && pl->state != ST_CONFIRM_PASSWORD)) 1239 && draw_exit && (pl->state != ST_GET_NAME && pl->state != ST_GET_PASSWORD && pl->state != ST_CONFIRM_PASSWORD))
1321 { 1240 {
1322 if (pl->ob->map) 1241 if (pl->ob->map)
1323 { 1242 {
1324 INVOKE_PLAYER (LOGOUT, pl); 1243 INVOKE_PLAYER (LOGOUT, pl);
1325 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket.host); 1244 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket->host);
1326 } 1245 }
1327 1246
1328 char buf[MAX_BUF]; 1247 char buf[MAX_BUF];
1248
1329 sprintf (buf, "%s left the game.", &pl->ob->name); 1249 sprintf (buf, "%s left the game.", &pl->ob->name);
1330 new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, buf); 1250 new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, buf);
1331 } 1251 }
1332 1252
1333 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED)) 1253 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1405extern unsigned long todtick; 1325extern unsigned long todtick;
1406 1326
1407void 1327void
1408do_specials (void) 1328do_specials (void)
1409{ 1329{
1410
1411#ifdef WATCHDOG
1412 if (!(pticks % 503))
1413 watchdog ();
1414#endif
1415
1416 if (!(pticks % PTICKS_PER_CLOCK)) 1330 if (!(pticks % PTICKS_PER_CLOCK))
1417 tick_the_clock (); 1331 tick_the_clock ();
1418 1332
1419 if (!(pticks % 7)) 1333 if (!(pticks % 7))
1420 shstr::gc (); 1334 shstr::gc ();
1423 flush_old_maps (); /* Clears the tmp-files of maps which have reset */ 1337 flush_old_maps (); /* Clears the tmp-files of maps which have reset */
1424 1338
1425 if (!(pticks % 2503)) 1339 if (!(pticks % 2503))
1426 fix_weight (); /* Hack to fix weightproblems caused by bugs */ 1340 fix_weight (); /* Hack to fix weightproblems caused by bugs */
1427 1341
1428 if (!(pticks % 2521))
1429 metaserver_update (); /* 2500 ticks is about 5 minutes */
1430
1431 if (!(pticks % 5003)) 1342 if (!(pticks % 5003))
1432 write_book_archive (); 1343 write_book_archive ();
1433 1344
1434 if (!(pticks % 5009)) 1345 if (!(pticks % 5009))
1435 clean_friendly_list (); 1346 clean_friendly_list ();
1444void 1355void
1445server_tick () 1356server_tick ()
1446{ 1357{
1447 nroferrors = 0; 1358 nroferrors = 0;
1448 1359
1360 // first do the user visible stuff
1449 doeric_server (); 1361 doeric_server ();
1450 INVOKE_GLOBAL (CLOCK); 1362 INVOKE_GLOBAL (CLOCK);
1451 process_events (NULL); /* "do" something with objects with speed */ 1363 process_events (); /* "do" something with objects with speed */
1452 flush_sockets (); 1364 flush_sockets ();
1365
1366 // then do some bookkeeping, should not really be here
1453 check_active_maps (); /* Removes unused maps after a certain timeout */ 1367 check_active_maps (); /* Removes unused maps after a certain timeout */
1454 do_specials (); /* Routines called from time to time. */ 1368 do_specials (); /* Routines called from time to time. */
1455 object::free_mortals (); 1369 object::free_mortals ();
1456 1370
1457 ++pticks; 1371 ++pticks;
1461main (int argc, char **argv) 1375main (int argc, char **argv)
1462{ 1376{
1463 settings.argc = argc; 1377 settings.argc = argc;
1464 settings.argv = argv; 1378 settings.argv = argv;
1465 1379
1466 cfperl_init ();
1467
1468 init (argc, argv); 1380 init (argc, argv);
1469 1381
1470 initPlugins (); 1382 initPlugins ();
1471 1383
1472 for (;;) 1384 for (;;)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines