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.23 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.60 by root, Wed Dec 27 09:28:02 2006 UTC

1
2/*
3 * static char *rcsid_main_c =
4 * "$Id: main.C,v 1.23 2006/09/10 15:59:57 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2001-2003 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001-2003 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 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
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 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>
28*/ 22*/
29 23
30#include <global.h> 24#include <global.h>
31#include <object.h> 25#include <object.h>
32#include <tod.h> 26#include <tod.h>
37# ifdef HAVE_CRYPT_H 31# ifdef HAVE_CRYPT_H
38# include <crypt.h> 32# include <crypt.h>
39# endif 33# endif
40#endif 34#endif
41 35
42#ifndef __CEXTRACT__
43# include <sproto.h> 36#include <sproto.h>
44#endif
45
46#ifdef HAVE_TIME_H
47# include <time.h> 37#include <time.h>
48#endif
49 38
50#include <../random_maps/random_map.h> 39#include <../random_maps/random_map.h>
51#include <../random_maps/rproto.h> 40#include <../random_maps/rproto.h>
52#include "path.h" 41#include "path.h"
53 42
112 new_draw_info (NDI_UNIQUE, 0, op, "Images and art:"); 101 new_draw_info (NDI_UNIQUE, 0, op, "Images and art:");
113 new_draw_info (NDI_UNIQUE, 0, op, "Peter Gardner"); 102 new_draw_info (NDI_UNIQUE, 0, op, "Peter Gardner");
114 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]");
115 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]");
116 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]");
117 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]");
118 new_draw_info (NDI_UNIQUE, 0, op, "And many more!"); 107 new_draw_info (NDI_UNIQUE, 0, op, "And many more!");
119} 108}
120 109
121void 110void
122info_keys (object *op) 111info_keys (object *op)
144void 133void
145start_info (object *op) 134start_info (object *op)
146{ 135{
147 char buf[MAX_BUF]; 136 char buf[MAX_BUF];
148 137
149 sprintf (buf, "Welcome to Crossfire, v%s!", VERSION); 138 sprintf (buf, "Welcome to Crossfire v%s!", VERSION);
150 new_draw_info (NDI_UNIQUE, 0, op, buf); 139 new_draw_info (NDI_UNIQUE, 0, op, buf);
151 new_draw_info (NDI_UNIQUE, 0, op, "Press `?' for help"); 140 new_draw_info (NDI_UNIQUE, 0, op, "Press `?' for help");
152 new_draw_info (NDI_UNIQUE, 0, op, " "); 141 new_draw_info (NDI_UNIQUE, 0, op, " ");
153 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, op, "%s entered the game.", &op->name); 142 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, op, "%s entered the game.", &op->name);
154 if (!op->contr->name_changed)
155 {
156 new_draw_info (NDI_UNIQUE, 0, op, "Note that you must set your name with the name");
157 new_draw_info (NDI_UNIQUE, 0, op, "command to enter the highscore list.");
158 new_draw_info (NDI_UNIQUE, 0, op, "(You can also use the crossfire.name X-resource.)");
159 }
160}
161
162/* Really, there is no reason to crypt the passwords any system. But easier
163 * to just leave this enabled for backward compatibility. Put the
164 * simple case at top - no encryption - makes it easier to read.
165 */
166char *
167crypt_string (char *str, char *salt)
168{
169#if defined(WIN32) || (defined(__FreeBSD__) && !defined(HAVE_LIBDES))
170 return (str);
171#else
172 static char *c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
173 char s[2];
174
175 if (salt == NULL)
176 s[0] = c[RANDOM () % (int) strlen (c)], s[1] = c[RANDOM () % (int) strlen (c)];
177 else
178 s[0] = salt[0], s[1] = salt[1];
179
180# ifdef HAVE_LIBDES
181 return (char *) des_crypt (str, s);
182# endif
183 /* Default case - just use crypt */
184 return (char *) crypt (str, s);
185#endif
186}
187
188int
189check_password (char *typed, char *crypted)
190{
191 return !strcmp (crypt_string (typed, crypted), crypted);
192} 143}
193 144
194/* This is a basic little function to put the player back to his 145/* This is a basic little function to put the player back to his
195 * savebed. We do some error checking - its possible that the 146 * savebed. We do some error checking - its possible that the
196 * savebed map may no longer exist, so we make sure the player 147 * savebed map may no longer exist, so we make sure the player
197 * goes someplace. 148 * goes someplace.
198 */ 149 */
199void 150void
200enter_player_savebed (object *op) 151enter_player_savebed (object *op)
201{ 152{
202 mapstruct *oldmap = op->map; 153 maptile *oldmap = op->map;
203 object *tmp; 154 object *tmp;
204 155
205 tmp = get_object (); 156 tmp = object::create ();
206 157
207 EXIT_PATH (tmp) = op->contr->savebed_map; 158 EXIT_PATH (tmp) = op->contr->savebed_map;
208 EXIT_X (tmp) = op->contr->bed_x; 159 EXIT_X (tmp) = op->contr->bed_x;
209 EXIT_Y (tmp) = op->contr->bed_y; 160 EXIT_Y (tmp) = op->contr->bed_y;
210 enter_exit (op, tmp); 161 enter_exit (op, tmp);
223 EXIT_PATH (tmp) = op->contr->savebed_map; 174 EXIT_PATH (tmp) = op->contr->savebed_map;
224 EXIT_X (tmp) = op->contr->bed_x; 175 EXIT_X (tmp) = op->contr->bed_x;
225 EXIT_Y (tmp) = op->contr->bed_y; 176 EXIT_Y (tmp) = op->contr->bed_y;
226 enter_exit (op, tmp); 177 enter_exit (op, tmp);
227 } 178 }
228 free_object (tmp); 179
180 tmp->destroy ();
229} 181}
230 182
231/* All this really is is a glorified remove_object that also updates 183/* All this really is is a glorified remove_object that also updates
232 * the counts on the map if needed. 184 * the counts on the map if needed.
233 */ 185 */
234void 186void
235leave_map (object *op) 187leave_map (object *op)
236{ 188{
237 mapstruct *oldmap = op->map; 189 maptile *oldmap = op->map;
238 190
239 remove_ob (op); 191 op->remove ();
240 192
241 if (oldmap) 193 if (oldmap)
242 { 194 {
243 if (!op->contr->hidden) 195 if (!op->contr->hidden)
244 oldmap->players--; 196 oldmap->players--;
197
245 if (oldmap->players <= 0) 198 if (oldmap->players <= 0)
246 { /* can be less than zero due to errors in tracking this */ 199 /* can be less than zero due to errors in tracking this */
247 set_map_timeout (oldmap); 200 set_map_timeout (oldmap);
248 }
249 } 201 }
250} 202}
251 203
252/* 204/*
253 * enter_map(): Moves the player and pets from current map (if any) to 205 * enter_map(): Moves the player and pets from current map (if any) to
255 * player to - it could be the map he just came from if the load failed for 207 * player to - it could be the map he just came from if the load failed for
256 * whatever reason. If default map coordinates are to be used, then 208 * whatever reason. If default map coordinates are to be used, then
257 * the function that calls this should figure them out. 209 * the function that calls this should figure them out.
258 */ 210 */
259static void 211static void
260enter_map (object *op, mapstruct *newmap, int x, int y) 212enter_map (object *op, maptile *newmap, int x, int y)
261{ 213{
262 mapstruct *oldmap = op->map; 214 maptile *oldmap = op->map;
263 215
264 if (out_of_map (newmap, x, y)) 216 if (out_of_map (newmap, x, y))
265 { 217 {
266 LOG (llevError, "enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->path, x, y); 218 LOG (llevError, "enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->path, x, y);
267 x = MAP_ENTER_X (newmap); 219 x = newmap->enter_x;
268 y = MAP_ENTER_Y (newmap); 220 y = newmap->enter_y;
269 if (out_of_map (newmap, x, y)) 221 if (out_of_map (newmap, x, y))
270 { 222 {
271 LOG (llevError, "enter_map: map %s provides invalid default enter location (%d, %d) > (%d, %d)\n", 223 LOG (llevError, "enter_map: map %s provides invalid default enter location (%d, %d) > (%d, %d)\n",
272 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap)); 224 newmap->path, x, y, newmap->width, newmap->height);
273 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed"); 225 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed");
274 return; 226 return;
275 } 227 }
276 } 228 }
229
277 /* try to find a spot for the player */ 230 /* try to find a spot for the player */
278 if (ob_blocked (op, newmap, x, y)) 231 if (ob_blocked (op, newmap, x, y))
279 { /* First choice blocked */ 232 { /* First choice blocked */
280 /* We try to find a spot for the player, starting closest in. 233 /* We try to find a spot for the player, starting closest in.
281 * We could use find_first_free_spot, but that doesn't randomize it at all, 234 * We could use find_first_free_spot, but that doesn't randomize it at all,
290 { 243 {
291 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1); 244 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1);
292 if (i == -1) 245 if (i == -1)
293 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE); 246 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE);
294 } 247 }
248
295 if (i != -1) 249 if (i != -1)
296 { 250 {
297 x += freearr_x[i]; 251 x += freearr_x[i];
298 y += freearr_y[i]; 252 y += freearr_y[i];
299 } 253 }
302 /* not much we can do in this case. */ 256 /* not much we can do in this case. */
303 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); 257 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);
304 } 258 }
305 } /* end if looking for free spot */ 259 } /* end if looking for free spot */
306 260
307 if (op->map != NULL) 261 if (op->map)
308 {
309 INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (op->map), ARG_MAP (newmap));
310 INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)); 262 if (INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)))
311 } 263 return;
264
265 if (INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (newmap), ARG_INT (x), ARG_INT (y)))
266 return;
267
268 if (INVOKE_MAP (ENTER, newmap, ARG_PLAYER (op->contr), ARG_INT (x), ARG_INT (y)))
269 return;
312 270
313 /* If it is a player login, he has yet to be inserted anyplace. 271 /* If it is a player login, he has yet to be inserted anyplace.
314 * otherwise, we need to deal with removing the player here. 272 * otherwise, we need to deal with removing the player here.
315 */ 273 */
316 if (!QUERY_FLAG (op, FLAG_REMOVED)) 274 op->remove ();
317 remove_ob (op);
318 275
319 /* remove_ob clears these so they must be reset after the remove_ob call */ 276 /* remove_ob clears these so they must be reset after the remove_ob call */
320 op->x = x; 277 op->x = x;
321 op->y = y; 278 op->y = y;
322 op->map = newmap; 279 op->map = newmap;
280
323 insert_ob_in_map (op, op->map, NULL, INS_NO_WALK_ON); 281 insert_ob_in_map (op, op->map, NULL, INS_NO_WALK_ON);
324
325 INVOKE_MAP (ENTER, op->map, ARG_PLAYER (op->contr));
326 282
327 if (!op->contr->hidden) 283 if (!op->contr->hidden)
328 newmap->players++; 284 newmap->players++;
329 285
330 newmap->timeout = 0; 286 newmap->timeout = 0;
340 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL) 296 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL)
341 { 297 {
342 int i = find_free_spot (op->contr->ranges[range_golem], newmap, 298 int i = find_free_spot (op->contr->ranges[range_golem], newmap,
343 x, y, 1, SIZEOFFREE); 299 x, y, 1, SIZEOFFREE);
344 300
345 remove_ob (op->contr->ranges[range_golem]); 301 op->contr->ranges[range_golem]->remove ();
302
346 if (i == -1) 303 if (i == -1)
347 { 304 {
348 remove_friendly_object (op->contr->ranges[range_golem]); 305 remove_friendly_object (op->contr->ranges[range_golem]);
349 free_object (op->contr->ranges[range_golem]); 306 op->contr->ranges[range_golem]->destroy ();
350 op->contr->ranges[range_golem] = NULL; 307 op->contr->ranges[range_golem] = 0;
351 op->contr->golem_count = 0;
352 } 308 }
353 else 309 else
354 { 310 {
355 object *tmp;
356
357 for (tmp = op->contr->ranges[range_golem]; tmp != NULL; tmp = tmp->more) 311 for (object *tmp = op->contr->ranges[range_golem]; tmp != NULL; tmp = tmp->more)
358 { 312 {
359 tmp->x = x + freearr_x[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x); 313 tmp->x = x + freearr_x[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x);
360 tmp->y = y + freearr_y[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y); 314 tmp->y = y + freearr_y[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y);
361 tmp->map = newmap; 315 tmp->map = newmap;
362 } 316 }
317
363 insert_ob_in_map (op->contr->ranges[range_golem], newmap, NULL, 0); 318 insert_ob_in_map (op->contr->ranges[range_golem], newmap, NULL, 0);
364 op->contr->ranges[range_golem]->direction = 319 op->contr->ranges[range_golem]->direction =
365 find_dir_2 (op->x - op->contr->ranges[range_golem]->x, op->y - op->contr->ranges[range_golem]->y); 320 find_dir_2 (op->x - op->contr->ranges[range_golem]->x, op->y - op->contr->ranges[range_golem]->y);
366 } 321 }
367 } 322 }
323
368 op->direction = 0; 324 op->direction = 0;
369 325
370 /* since the players map is already loaded, we don't need to worry 326 /* since the players map is already loaded, we don't need to worry
371 * about pending objects. 327 * about pending objects.
372 */ 328 */
387 } 343 }
388 } 344 }
389} 345}
390 346
391void 347void
392set_map_timeout (mapstruct *oldmap) 348set_map_timeout (maptile *oldmap)
393{ 349{
394#if MAP_MAXTIMEOUT 350#if MAP_MAXTIMEOUT
395 oldmap->timeout = MAP_TIMEOUT (oldmap); 351 oldmap->timeout = oldmap->timeout;
396 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is 352 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is
397 * lower than the min value. 353 * lower than the min value.
398 */ 354 */
399# if MAP_MINTIMEOUT 355# if MAP_MINTIMEOUT
400 if (oldmap->timeout < MAP_MINTIMEOUT) 356 if (oldmap->timeout < MAP_MINTIMEOUT)
401 {
402 oldmap->timeout = MAP_MINTIMEOUT; 357 oldmap->timeout = MAP_MINTIMEOUT;
403 }
404# endif 358# endif
359
405 if (oldmap->timeout > MAP_MAXTIMEOUT) 360 if (oldmap->timeout > MAP_MAXTIMEOUT)
406 {
407 oldmap->timeout = MAP_MAXTIMEOUT; 361 oldmap->timeout = MAP_MAXTIMEOUT;
408 } 362
409#else 363#else
410 /* save out the map */ 364 /* save out the map */
411 swap_map (oldmap); 365 swap_map (oldmap);
412#endif /* MAP_MAXTIMEOUT */ 366#endif /* MAP_MAXTIMEOUT */
413} 367}
418 */ 372 */
419char * 373char *
420clean_path (const char *file) 374clean_path (const char *file)
421{ 375{
422 static char newpath[MAX_BUF], *cp; 376 static char newpath[MAX_BUF], *cp;
377 assign (newpath, file);
423 378
424 strncpy (newpath, file, MAX_BUF - 1);
425 newpath[MAX_BUF - 1] = '\0';
426 for (cp = newpath; *cp != '\0'; cp++) 379 for (cp = newpath; *cp != '\0'; cp++)
427 {
428 if (*cp == '/') 380 if (*cp == '/')
429 *cp = '_'; 381 *cp = '_';
430 } 382
431 return newpath; 383 return newpath;
432} 384}
433 385
434 386
435/* unclean_path takes a path and replaces all _ with / 387/* unclean_path takes a path and replaces all _ with /
443unclean_path (const char *src) 395unclean_path (const char *src)
444{ 396{
445 static char newpath[MAX_BUF], *cp; 397 static char newpath[MAX_BUF], *cp;
446 398
447 cp = strrchr (src, '/'); 399 cp = strrchr (src, '/');
448 if (cp) 400 assign (newpath, cp ? cp + 1 : src);
449 strncpy (newpath, cp + 1, MAX_BUF - 1);
450 else
451 strncpy (newpath, src, MAX_BUF - 1);
452 newpath[MAX_BUF - 1] = '\0';
453 401
454 for (cp = newpath; *cp != '\0'; cp++) 402 for (cp = newpath; *cp != '\0'; cp++)
455 {
456 if (*cp == '_') 403 if (*cp == '_')
457 *cp = '/'; 404 *cp = '/';
458 } 405
459 return newpath; 406 return newpath;
460} 407}
461 408
462 409
463/* The player is trying to enter a randomly generated map. In this case, generate the 410/* The player is trying to enter a randomly generated map. In this case, generate the
465 */ 412 */
466 413
467static void 414static void
468enter_random_map (object *pl, object *exit_ob) 415enter_random_map (object *pl, object *exit_ob)
469{ 416{
470 mapstruct *new_map; 417 maptile *new_map;
471 char newmap_name[HUGE_BUF], *cp; 418 char newmap_name[HUGE_BUF], *cp;
472 static int reference_number = 0; 419 static int reference_number = 0;
473 RMParms rp; 420 RMParms rp;
474 421
475 memset (&rp, 0, sizeof (RMParms)); 422 memset (&rp, 0, sizeof (RMParms));
482 rp.origin_y = exit_ob->y; 429 rp.origin_y = exit_ob->y;
483 strcpy (rp.origin_map, pl->map->path); 430 strcpy (rp.origin_map, pl->map->path);
484 431
485 /* If we have a final_map, use it as a base name to give some clue 432 /* If we have a final_map, use it as a base name to give some clue
486 * as where the player is. Otherwise, use the origin map. 433 * as where the player is. Otherwise, use the origin map.
487 * Take the last component (after the last slash) to give
488 * shorter names without bogus slashes.
489 */ 434 */
490 if (rp.final_map[0]) 435 sprintf (newmap_name, "/random%s+%04d",
491 { 436 *rp.final_map ? rp.final_map : rp.origin_map,
492 cp = strrchr (rp.final_map, '/'); 437 reference_number++);
493 if (!cp)
494 cp = rp.final_map;
495 }
496 else
497 {
498 char buf[HUGE_BUF];
499
500 cp = strrchr (rp.origin_map, '/');
501 if (!cp)
502 cp = rp.origin_map;
503 /* Need to strip of any trailing digits, if it has them */
504 strcpy (buf, cp);
505 while (isdigit (buf[strlen (buf) - 1]))
506 buf[strlen (buf) - 1] = 0;
507 cp = buf;
508 }
509
510 sprintf (newmap_name, "/random/%s%04d", cp + 1, reference_number++);
511 438
512 /* now to generate the actual map. */ 439 /* now to generate the actual map. */
513 new_map = generate_random_map (newmap_name, &rp); 440 new_map = generate_random_map (newmap_name, &rp);
514 441
515 /* Update the exit_ob so it now points directly at the newly created 442 /* Update the exit_ob so it now points directly at the newly created
520 */ 447 */
521 if (new_map) 448 if (new_map)
522 { 449 {
523 int x, y; 450 int x, y;
524 451
525 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map); 452 x = EXIT_X (exit_ob) = new_map->enter_x;
526 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map); 453 y = EXIT_Y (exit_ob) = new_map->enter_y;
527 EXIT_PATH (exit_ob) = newmap_name; 454 EXIT_PATH (exit_ob) = newmap_name;
528 strcpy (new_map->path, newmap_name); 455 strcpy (new_map->path, newmap_name);
529 enter_map (pl, new_map, x, y); 456 enter_map (pl, new_map, x, y);
530 } 457 }
531} 458}
535 */ 462 */
536 463
537static void 464static void
538enter_fixed_template_map (object *pl, object *exit_ob) 465enter_fixed_template_map (object *pl, object *exit_ob)
539{ 466{
540 mapstruct *new_map; 467 maptile *new_map;
541 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap; 468 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap;
542 const char *new_map_name; 469 const char *new_map_name;
543 470
544 /* Split the exit path string into two parts, one 471 /* Split the exit path string into two parts, one
545 * for where to store the map, and one for were 472 * for where to store the map, and one for were
554 */ 481 */
555 LOG (llevError, "enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n", 482 LOG (llevError, "enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n",
556 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); 483 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
557 return; 484 return;
558 } 485 }
486
559 *sourcemap++ = '\0'; 487 *sourcemap++ = '\0';
560 488
561 /* If we are not coming from a template map, we can use relative directories 489 /* If we are not coming from a template map, we can use relative directories
562 * for the map to generate from. 490 * for the map to generate from.
563 */ 491 */
564 if (!exit_ob->map->templatemap) 492 if (!exit_ob->map->templatemap)
565 {
566 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap); 493 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap);
567 }
568 494
569 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 495 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord
570 * of the exit, and the name of the map the exit is on, respectively. 496 * of the exit, and the name of the map the exit is on, respectively.
571 */ 497 */
572 sprintf (tmpnum, "%d", exit_ob->x); 498 sprintf (tmpnum, "%d", exit_ob->x);
581 507
582 /* If we are coming from another template map, use reletive paths unless 508 /* If we are coming from another template map, use reletive paths unless
583 * indicated otherwise. 509 * indicated otherwise.
584 */ 510 */
585 if (exit_ob->map->templatemap && (resultname[0] != '/')) 511 if (exit_ob->map->templatemap && (resultname[0] != '/'))
586 {
587 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname); 512 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname);
588 }
589 else 513 else
590 {
591 new_map_name = create_template_pathname (resultname); 514 new_map_name = create_template_pathname (resultname);
592 }
593 515
594 /* Attempt to load the map, if unable to, then 516 /* Attempt to load the map, if unable to, then
595 * create the map from the template. 517 * create the map from the template.
596 */ 518 */
597 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE); 519 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE);
619 LOG (llevDebug, "enter_fixed_template_map: Exit %s (%d,%d) on map %s leads no where.\n", 541 LOG (llevDebug, "enter_fixed_template_map: Exit %s (%d,%d) on map %s leads no where.\n",
620 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); 542 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
621 } 543 }
622} 544}
623 545
624
625/* The player is trying to enter a randomly generated template map. In this 546/* The player is trying to enter a randomly generated template map. In this
626 * case, generate the map as needed. 547 * case, generate the map as needed.
627 */ 548 */
628 549
629static void 550static void
630enter_random_template_map (object *pl, object *exit_ob) 551enter_random_template_map (object *pl, object *exit_ob)
631{ 552{
632 mapstruct *new_map; 553 maptile *new_map;
633 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF]; 554 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF];
634 const char *new_map_name; 555 const char *new_map_name;
635 RMParms rp; 556 RMParms rp;
636 557
637 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 558 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord
649 570
650 /* If we are coming from another template map, use reletive paths unless 571 /* If we are coming from another template map, use reletive paths unless
651 * indicated otherwise. 572 * indicated otherwise.
652 */ 573 */
653 if (exit_ob->map->templatemap && (resultname[0] != '/')) 574 if (exit_ob->map->templatemap && (resultname[0] != '/'))
654 {
655 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname); 575 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname);
656 }
657 else 576 else
658 {
659 new_map_name = create_template_pathname (resultname); 577 new_map_name = create_template_pathname (resultname);
660 }
661 578
662 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE); 579 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE);
663 if (!new_map) 580 if (!new_map)
664 { 581 {
665 memset (&rp, 0, sizeof (RMParms)); 582 memset (&rp, 0, sizeof (RMParms));
685 */ 602 */
686 if (new_map) 603 if (new_map)
687 { 604 {
688 int x, y; 605 int x, y;
689 606
690 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map); 607 x = EXIT_X (exit_ob) = new_map->enter_x;
691 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map); 608 y = EXIT_Y (exit_ob) = new_map->enter_y;
692 new_map->templatemap = 1; 609 new_map->templatemap = 1;
693 enter_map (pl, new_map, x, y); 610 enter_map (pl, new_map, x, y);
694 } 611 }
695} 612}
696 613
699 */ 616 */
700static void 617static void
701enter_unique_map (object *op, object *exit_ob) 618enter_unique_map (object *op, object *exit_ob)
702{ 619{
703 char apartment[HUGE_BUF]; 620 char apartment[HUGE_BUF];
704 mapstruct *newmap; 621 maptile *newmap;
705 622
706 if (EXIT_PATH (exit_ob)[0] == '/') 623 if (EXIT_PATH (exit_ob)[0] == '/')
707 { 624 {
708 sprintf (apartment, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, clean_path (EXIT_PATH (exit_ob))); 625 sprintf (apartment, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, clean_path (EXIT_PATH (exit_ob)));
709 newmap = ready_map_name (apartment, MAP_PLAYER_UNIQUE); 626 newmap = ready_map_name (apartment, MAP_PLAYER_UNIQUE);
793#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */ 710#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */
794 object *tmp; 711 object *tmp;
795 712
796 /* It may be nice to support other creatures moving across 713 /* It may be nice to support other creatures moving across
797 * exits, but right now a lot of the code looks at op->contr, 714 * exits, but right now a lot of the code looks at op->contr,
798 * so thta is an RFE. 715 * so that is an RFE.
799 */ 716 */
800 if (op->type != PLAYER) 717 if (op->type != PLAYER)
801 return; 718 return;
802 719
803 /* First, lets figure out what map the player is going to go to */ 720 /* First, lets figure out what map the player is going to go to */
804 if (exit_ob) 721 if (exit_ob)
805 { 722 {
806
807 /* check to see if we make a template map */ 723 /* check to see if we make a template map */
808 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@') 724 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@')
809 { 725 {
810 if (EXIT_PATH (exit_ob)[2] == '!') 726 if (EXIT_PATH (exit_ob)[2] == '!')
811 { 727 {
832 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob); 748 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob);
833 749
834 /* 'Normal' exits that do not do anything special 750 /* 'Normal' exits that do not do anything special
835 * Simple enough we don't need another routine for it. 751 * Simple enough we don't need another routine for it.
836 */ 752 */
837 mapstruct *newmap; 753 maptile *newmap;
838 754
839 if (exit_ob->map) 755 if (exit_ob->map)
840 { 756 {
841 newmap = ready_map_name (path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)), 0); 757 newmap = ready_map_name (path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)), 0);
842 /* Random map was previously generated, but is no longer about. Lets generate a new 758 /* Random map was previously generated, but is no longer about. Lets generate a new
893 * using the new maps default coordinates, the exit ob should use 809 * using the new maps default coordinates, the exit ob should use
894 * something like -1, -1 so it is clear to do that. 810 * something like -1, -1 so it is clear to do that.
895 */ 811 */
896 if (x == 0 && y == 0) 812 if (x == 0 && y == 0)
897 { 813 {
898 x = MAP_ENTER_X (newmap); 814 x = newmap->enter_x;
899 y = MAP_ENTER_Y (newmap); 815 y = newmap->enter_y;
900 LOG (llevDebug, "enter_exit: Exit %s (%d,%d) on map %s is 0 destination coordinates\n", 816 LOG (llevDebug, "enter_exit: Exit %s (%d,%d) on map %s is 0 destination coordinates\n",
901 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map ? exit_ob->map->path : "<nil>"); 817 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map ? exit_ob->map->path : "<nil>");
902 } 818 }
903 819
904 /* mids 02/13/2002 if exit is damned, update players death & WoR home-position and delete town portal */ 820 /* mids 02/13/2002 if exit is damned, update players death & WoR home-position and delete town portal */
910 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME)) 826 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME))
911 break; 827 break;
912 } 828 }
913 if (tmp) 829 if (tmp)
914 { 830 {
915 remove_ob (tmp); 831 tmp->remove ();
916 free_object (tmp); 832 tmp->destroy ();
917 } 833 }
918 834
919 strcpy (op->contr->savebed_map, path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob))); 835 strcpy (op->contr->savebed_map, path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)));
920 op->contr->bed_x = EXIT_X (exit_ob), op->contr->bed_y = EXIT_Y (exit_ob); 836 op->contr->bed_x = EXIT_X (exit_ob), op->contr->bed_y = EXIT_Y (exit_ob);
921 save_player (op, 1); 837 op->contr->save ();
922 /* LOG(llevDebug,"enter_exit: Taking damned exit %s to (%d,%d) on map %s\n", 838 /* LOG(llevDebug,"enter_exit: Taking damned exit %s to (%d,%d) on map %s\n",
923 * exit_ob->name?exit_ob->name:"(none)", exit_ob->x, exit_ob->y, 839 * exit_ob->name?exit_ob->name:"(none)", exit_ob->x, exit_ob->y,
924 * path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob))); */ 840 * path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob))); */
925 } 841 }
926 842
931 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1); 847 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
932 } 848 }
933 else 849 else
934 { 850 {
935 int flags = 0; 851 int flags = 0;
936 mapstruct *newmap; 852 maptile *newmap;
937
938 853
939 /* Hypothetically, I guess its possible that a standard map matches 854 /* Hypothetically, I guess its possible that a standard map matches
940 * the localdir, but that seems pretty unlikely - unlikely enough that 855 * the localdir, but that seems pretty unlikely - unlikely enough that
941 * I'm not going to attempt to try to deal with that possibility. 856 * I'm not going to attempt to try to deal with that possibility.
942 * We use the fact that when a player saves on a unique map, it prepends 857 * We use the fact that when a player saves on a unique map, it prepends
963 { 878 {
964 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n"); 879 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n");
965 abort (); 880 abort ();
966 } 881 }
967 } 882 }
883
968 enter_map (op, newmap, op->x, op->y); 884 enter_map (op, newmap, op->x, op->y);
969 } 885 }
970} 886}
971
972/*
973 * process_active_maps(): Works like process_events(), but it only
974 * processes maps which a player is on.
975 *
976 */
977
978#if 0 // dead code, schmorp
979void
980process_active_maps ()
981{
982 for (mapstruct *map = first_map; map != NULL; map = map->next)
983 if (map->in_memory == MAP_IN_MEMORY)
984 if (players_on_map (map, TRUE))
985 process_events (map);
986}
987#endif
988 887
989/* process_players1 and process_players2 do all the player related stuff. 888/* process_players1 and process_players2 do all the player related stuff.
990 * I moved it out of process events and process_map. This was to some 889 * I moved it out of process events and process_map. This was to some
991 * extent for debugging as well as to get a better idea of the time used 890 * extent for debugging as well as to get a better idea of the time used
992 * by the various functions. process_players1() does the processing before 891 * by the various functions. process_players1() does the processing before
993 * objects have been updated, process_players2() does the processing that 892 * objects have been updated, process_players2() does the processing that
994 * is needed after the players have been updated. 893 * is needed after the players have been updated.
995 */ 894 */
996 895static void
997void 896process_players1 ()
998process_players1 (mapstruct *map)
999{ 897{
1000 int flag; 898 int flag;
1001 player *pl, *plnext;
1002 899
1003 /* Basically, we keep looping until all the players have done their actions. */ 900 /* Basically, we keep looping until all the players have done their actions. */
1004 for (flag = 1; flag != 0;) 901 for (flag = 1; flag != 0;)
1005 { 902 {
1006 flag = 0; 903 flag = 0;
1007 for (pl = first_player; pl != NULL; pl = plnext) 904 for_all_players (pl)
1008 { 905 {
1009 plnext = pl->next; /* In case a player exits the game in handle_player() */ 906 pl->refcnt_chk ();
1010 907
1011 if (pl->ob == NULL) 908 if (!pl->ob || !pl->ns)
1012 continue; 909 continue;
1013 910
1014 if (map != NULL && pl->ob->map != map)
1015 continue;
1016
1017 if (pl->ob->speed_left > 0) 911 if (pl->ob->speed_left > 0)
1018 {
1019 if (handle_newcs_player (pl->ob)) 912 if (handle_newcs_player (pl->ob))
1020 flag = 1; 913 flag = 1;
1021 } /* end if player has speed left */
1022 914
1023 /* If the player is not actively playing, don't make a 915 /* If the player is not actively playing, don't make a
1024 * backup save - nothing to save anyway. Plus, the 916 * backup save - nothing to save anyway. Plus, the
1025 * map may not longer be valid. This can happen when the 917 * map may not longer be valid. This can happen when the
1026 * player quits - they exist for purposes of tracking on the map, 918 * player quits - they exist for purposes of tracking on the map,
1031 923
1032#ifdef AUTOSAVE 924#ifdef AUTOSAVE
1033 /* check for ST_PLAYING state so that we don't try to save off when 925 /* check for ST_PLAYING state so that we don't try to save off when
1034 * the player is logging in. 926 * the player is logging in.
1035 */ 927 */
1036 if ((pl->last_save_tick + AUTOSAVE) < (uint32) pticks && pl->state == ST_PLAYING) 928 if ((pl->last_save_tick + AUTOSAVE) < (uint32) pticks && pl->ns->state == ST_PLAYING)
1037 {
1038 /* Don't save the player on unholy ground. Instead, increase the
1039 * tick time so it will be about 10 seconds before we try and save
1040 * again.
1041 */ 929 {
1042// if (get_map_flags(pl->ob->map, NULL, pl->ob->x, pl->ob->y, NULL, NULL) & P_NO_CLERIC) { 930 pl->ob->contr->save ();
1043// pl->last_save_tick += 100;
1044// } else {
1045 save_player (pl->ob, 1);
1046 pl->last_save_tick = pticks; 931 pl->last_save_tick = pticks;
1047// }
1048 } 932 }
1049#endif 933#endif
1050 } /* end of for loop for all the players */ 934 } /* end of for loop for all the players */
1051 } /* for flag */ 935 } /* for flag */
1052 for (pl = first_player; pl != NULL; pl = pl->next) 936
937 for_all_players (pl)
1053 { 938 {
1054 if (map != NULL && (pl->ob == NULL || pl->ob->map != map)) 939 if (!pl->ob || !pl->ns)
1055 continue; 940 continue;
941
1056 if (settings.casting_time == TRUE) 942 if (settings.casting_time)
1057 { 943 {
1058 if (pl->ob->casting_time > 0) 944 if (pl->ob->casting_time > 0)
1059 { 945 {
1060 pl->ob->casting_time--; 946 pl->ob->casting_time--;
1061 pl->ob->start_holding = 1; 947 pl->ob->start_holding = 1;
1062 } 948 }
949
1063 /* set spell_state so we can update the range in stats field */ 950 /* set spell_state so we can update the range in stats field */
1064 if ((pl->ob->casting_time == 0) && (pl->ob->start_holding == 1)) 951 if ((pl->ob->casting_time == 0) && (pl->ob->start_holding == 1))
1065 {
1066 pl->ob->start_holding = 0; 952 pl->ob->start_holding = 0;
1067 } 953 }
1068 } 954
1069 do_some_living (pl->ob); 955 do_some_living (pl->ob);
1070 /* draw(pl->ob); *//* updated in socket code */
1071 } 956 }
1072} 957}
1073 958
1074void 959static void
1075process_players2 (mapstruct *map) 960process_players2 ()
1076{ 961{
1077 player *pl;
1078
1079 /* Then check if any players should use weapon-speed instead of speed */ 962 /* Then check if any players should use weapon-speed instead of speed */
1080 for (pl = first_player; pl != NULL; pl = pl->next) 963 for_all_players (pl)
1081 { 964 {
1082 if (map != NULL)
1083 {
1084 if (pl->ob == NULL || QUERY_FLAG (pl->ob, FLAG_REMOVED))
1085 continue;
1086 else if (pl->loading != NULL) /* Player is blocked */
1087 pl->ob->speed_left -= pl->ob->speed;
1088 if (pl->ob->map != map)
1089 continue;
1090 }
1091
1092 /* The code that did weapon_sp handling here was out of place - 965 /* The code that did weapon_sp handling here was out of place -
1093 * this isn't called until after the player has finished there 966 * this isn't called until after the player has finished there
1094 * actions, and is thus out of place. All we do here is bounds 967 * actions, and is thus out of place. All we do here is bounds
1095 * checking. 968 * checking.
1096 */ 969 */
1102 /* This needs to be here - if the player is running, we need to 975 /* This needs to be here - if the player is running, we need to
1103 * clear this each tick, but new commands are not being received 976 * clear this each tick, but new commands are not being received
1104 * so execute_newserver_command() is never called 977 * so execute_newserver_command() is never called
1105 */ 978 */
1106 pl->has_hit = 0; 979 pl->has_hit = 0;
1107
1108 } 980 }
1109 else if (pl->ob->speed_left > pl->ob->speed) 981 else if (pl->ob->speed_left > pl->ob->speed)
1110 pl->ob->speed_left = pl->ob->speed; 982 pl->ob->speed_left = pl->ob->speed;
1111 } 983 }
1112} 984}
1113 985
1114void 986void
1115process_events (mapstruct *map) 987process_events ()
1116{ 988{
1117 object *op; 989 object *op;
1118 object *marker = get_object ();
1119 tag_t tag;
1120 990
991 static object_ptr marker_;
992
993 if (!marker_)
994 marker_ = object::create ();
995
996 object *marker = marker_;
997
1121 process_players1 (map); 998 process_players1 ();
1122 999
1123 marker->active_next = active_objects; 1000 marker->active_next = active_objects;
1124 1001
1125 if (marker->active_next) 1002 if (marker->active_next)
1126 marker->active_next->active_prev = marker; 1003 marker->active_next->active_prev = marker;
1127 1004
1128 marker->active_prev = NULL; 1005 marker->active_prev = 0;
1129 active_objects = marker; 1006 active_objects = marker;
1130 1007
1131 while (marker->active_next) 1008 while (marker->active_next)
1132 { 1009 {
1133 op = marker->active_next; 1010 op = marker->active_next;
1134 tag = op->count;
1135 1011
1136 /* Move marker forward - swap op and marker */ 1012 /* Move marker forward - swap op and marker */
1137 op->active_prev = marker->active_prev; 1013 op->active_prev = marker->active_prev;
1138 1014
1139 if (op->active_prev) 1015 if (op->active_prev)
1151 1027
1152 /* Now process op */ 1028 /* Now process op */
1153 if (QUERY_FLAG (op, FLAG_FREED)) 1029 if (QUERY_FLAG (op, FLAG_FREED))
1154 { 1030 {
1155 LOG (llevError, "BUG: process_events(): Free object on list\n"); 1031 LOG (llevError, "BUG: process_events(): Free object on list\n");
1156 op->speed = 0; 1032 op->set_speed (0);
1157 update_ob_speed (op);
1158 continue; 1033 continue;
1159 } 1034 }
1160 1035
1161 /* I've seen occasional crashes due to this - the object is removed, 1036 /* I've seen occasional crashes due to this - the object is removed,
1162 * and thus the map it points to (last map it was on) may be bogus 1037 * and thus the map it points to (last map it was on) may be bogus
1169 * around. 1044 * around.
1170 */ 1045 */
1171 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY) 1046 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY)
1172 { 1047 {
1173 LOG (llevError, "BUG: process_events(): Removed object on list\n"); 1048 LOG (llevError, "BUG: process_events(): Removed object on list\n");
1174 dump_object (op); 1049 char *dump = dump_object (op);
1175 LOG (llevError, errmsg); 1050 LOG (llevError, dump);
1176 free_object (op); 1051 free (dump);
1052 op->destroy ();
1177 continue; 1053 continue;
1178 } 1054 }
1179 1055
1180 if (!op->speed) 1056 if (!op->speed)
1181 { 1057 {
1182 LOG (llevError, "BUG: process_events(): Object %s has no speed, " "but is on active list\n", &op->arch->name); 1058 LOG (llevError, "BUG: process_events(): Object %s has no speed, "
1183 update_ob_speed (op); 1059 "but is on active list\n", &op->arch->name);
1060 op->set_speed (0);
1184 continue; 1061 continue;
1185 } 1062 }
1186 1063
1187 if (op->map == NULL && op->env == NULL && op->name && op->type != MAP && map == NULL) 1064 if (op->map == NULL && op->env == NULL && op->name && op->type != MAP)
1188 { 1065 {
1189 LOG (llevError, "BUG: process_events(): Object without map or " "inventory is on active list: %s (%d)\n", &op->name, op->count); 1066 LOG (llevError, "BUG: process_events(): Object without map or "
1067 "inventory is on active list: %s (%d)\n", &op->name, op->count);
1190 op->speed = 0; 1068 op->set_speed (0);
1191 update_ob_speed (op);
1192 continue; 1069 continue;
1193 } 1070 }
1194 1071
1195 if (map != NULL && op->map != map)
1196 continue;
1197
1198 /* Animate the object. Bug of feature that andim_speed 1072 /* Animate the object. Bug or feature that anim_speed
1199 * is based on ticks, and not the creatures speed? 1073 * is based on ticks, and not the creatures speed?
1200 */ 1074 */
1201 if (op->anim_speed && op->last_anim >= op->anim_speed) 1075 if (op->anim_speed && op->last_anim >= op->anim_speed)
1202 { 1076 {
1203 if ((op->type == PLAYER) || (op->type == MONSTER)) 1077 if ((op->type == PLAYER))
1204 animate_object (op, op->facing); 1078 animate_object (op, op->facing);
1205 else 1079 else
1206 animate_object (op, op->direction); 1080 animate_object (op, op->direction);
1207 1081
1208 op->last_anim = 1; 1082 op->last_anim = 1;
1226 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null"); 1100 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null");
1227 } 1101 }
1228#endif 1102#endif
1229 --op->speed_left; 1103 --op->speed_left;
1230 process_object (op); 1104 process_object (op);
1105
1231 if (was_destroyed (op, tag)) 1106 if (op->destroyed ())
1232 continue; 1107 continue;
1233 } 1108 }
1109
1234 if (settings.casting_time == TRUE && op->casting_time > 0) 1110 if (settings.casting_time == TRUE && op->casting_time > 0)
1235 op->casting_time--; 1111 op->casting_time--;
1112
1236 if (op->speed_left <= 0) 1113 if (op->speed_left <= 0)
1237 op->speed_left += FABS (op->speed); 1114 op->speed_left += FABS (op->speed);
1238 } 1115 }
1239 1116
1240 /* Remove marker object from active list */ 1117 /* Remove marker object from active list */
1241 if (marker->active_prev != NULL) 1118 if (marker->active_prev != NULL)
1242 marker->active_prev->active_next = NULL; 1119 marker->active_prev->active_next = NULL;
1243 else 1120 else
1244 active_objects = NULL; 1121 active_objects = NULL;
1245 1122
1246 process_players2 (map); 1123 process_players2 ();
1247
1248 free_object (marker);
1249} 1124}
1250 1125
1251void 1126void
1252clean_tmp_files (void) 1127clean_tmp_files (void)
1253{ 1128{
1254 mapstruct *m, *next; 1129 maptile *m, *next;
1255 1130
1256 LOG (llevInfo, "Cleaning up...\n"); 1131 LOG (llevInfo, "Cleaning up...\n");
1257 1132
1258 /* We save the maps - it may not be intuitive why, but if there are unique 1133 /* We save the maps - it may not be intuitive why, but if there are unique
1259 * items, we need to save the map so they get saved off. Perhaps we should 1134 * items, we need to save the map so they get saved off. Perhaps we should
1260 * just make a special function that only saves the unique items. 1135 * just make a special function that only saves the unique items.
1261 */ 1136 */
1262 for (m = first_map; m != NULL; m = next) 1137 for_all_maps (m)
1263 {
1264 next = m->next;
1265 if (m->in_memory == MAP_IN_MEMORY) 1138 if (m->in_memory == MAP_IN_MEMORY)
1266 {
1267 /* If we want to reuse the temp maps, swap it out (note that will also 1139 /* If we want to reuse the temp maps, swap it out (note that will also
1268 * update the log file. Otherwise, save the map (mostly for unique item 1140 * update the log file.
1269 * stuff). Note that the clean_tmp_map is called after the end of
1270 * the for loop but is in the #else bracket. IF we are recycling the maps,
1271 * we certainly don't want the temp maps removed.
1272 */ 1141 */
1273
1274 /* XXX The above comment is dead wrong */
1275 if (settings.recycle_tmp_maps == TRUE)
1276 swap_map (m); 1142 swap_map (m);
1277 else 1143
1278 {
1279 new_save_map (m, 0); /* note we save here into a overlay map */
1280 clean_tmp_map (m);
1281 }
1282 }
1283 }
1284 write_todclock (); /* lets just write the clock here */ 1144 write_todclock (); /* lets just write the clock here */
1285} 1145}
1286 1146
1287/* clean up everything before exiting */ 1147/* clean up everything before exiting */
1288void 1148void
1289cleanup (void) 1149cleanup (bool make_core)
1290{ 1150{
1291 LOG (llevDebug, "Cleanup called. freeing data.\n"); 1151 LOG (llevDebug, "Cleanup called.\n");
1152
1153 if (init_done)
1154 {
1155 for_all_players (pl)
1156 pl->save (1);
1157
1158 for_all_players (pl)
1159 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1160 leave_map (pl->ob);
1161
1292 clean_tmp_files (); 1162 clean_tmp_files ();
1293 write_book_archive (); 1163 write_book_archive ();
1294#ifdef MEMORY_DEBUG
1295 free_all_maps ();
1296 free_style_maps ();
1297 free_all_object_data ();
1298 free_all_archs ();
1299 free_all_treasures ();
1300 free_all_images ();
1301 free_all_newserver ();
1302 free_all_recipes ();
1303 free_all_readable ();
1304 free_all_god ();
1305 free_all_anim ();
1306 /* See what the string data that is out there that hasn't been freed. */
1307 1164
1308/* LOG(llevDebug, ss_dump_table(0xff));*/ 1165 INVOKE_GLOBAL (CLEANUP);
1309#endif 1166 }
1167
1168 if (make_core)
1169 abort ();
1170 else
1310 exit (0); 1171 _exit (0);
1311} 1172}
1312 1173
1313void 1174void
1314leave (player *pl, int draw_exit) 1175leave (player *pl, int draw_exit)
1315{ 1176{
1316 if (pl != NULL) 1177 if (pl)
1317 { 1178 {
1179 if (pl->ob->type != DEAD_OBJECT)
1180 {
1181 /* If a hidden dm dropped connection do not create
1182 * inconsistencies by showing that they have left the game
1183 */
1184 if (!(QUERY_FLAG (pl->ob, FLAG_WIZ) && pl->ob->contr->hidden)
1185 && draw_exit)
1186 {
1187 if (pl->ob->map)
1188 {
1189 INVOKE_PLAYER (LOGOUT, pl);
1190 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->ns->host);
1191 }
1192
1193 char buf[MAX_BUF];
1194
1195 sprintf (buf, "%s left the game.", &pl->ob->name);
1196 new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, 0, buf);
1197 }
1198
1199 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1200 leave_map (pl->ob);
1201
1202 pl->ob->type = DEAD_OBJECT; /* To avoid problems with inventory window */
1203 }
1204
1318 /* We do this so that the socket handling routine can do the final 1205 /* We do this so that the socket handling routine can do the final
1319 * cleanup. We also leave that loop to actually handle the freeing 1206 * cleanup. We also leave that loop to actually handle the freeing
1320 * of the data. 1207 * of the data.
1321 */ 1208 */
1322 if (pl->ob->type != DEAD_OBJECT) 1209 if (pl->ns)
1323 { 1210 pl->ns->destroy ();
1324 pl->socket.status = Ns_Dead;
1325 1211
1326 /* If a hidden dm dropped connection do not create
1327 * inconsistencies by showing that they have left the game
1328 */
1329 if (!(QUERY_FLAG (pl->ob, FLAG_WIZ) && pl->ob->contr->hidden)
1330 && draw_exit && (pl->state != ST_GET_NAME && pl->state != ST_GET_PASSWORD && pl->state != ST_CONFIRM_PASSWORD))
1331 {
1332 if (pl->ob->map)
1333 {
1334 INVOKE_PLAYER (LOGOUT, pl);
1335 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket.host);
1336 }
1337
1338 char buf[MAX_BUF];
1339
1340 sprintf (buf, "%s left the game.", &pl->ob->name);
1341 new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, buf);
1342 }
1343
1344 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1345 leave_map (pl->ob);
1346
1347 pl->ob->type = DEAD_OBJECT; /* To avoid problems with inventory window */
1348 }
1349 } 1212 }
1350} 1213}
1351 1214
1352int 1215int
1353forbid_play (void) 1216forbid_play (void)
1416extern unsigned long todtick; 1279extern unsigned long todtick;
1417 1280
1418void 1281void
1419do_specials (void) 1282do_specials (void)
1420{ 1283{
1421
1422#ifdef WATCHDOG
1423 if (!(pticks % 503))
1424 watchdog ();
1425#endif
1426
1427 if (!(pticks % PTICKS_PER_CLOCK)) 1284 if (!(pticks % PTICKS_PER_CLOCK))
1428 tick_the_clock (); 1285 tick_the_clock ();
1429 1286
1430 if (!(pticks % 7)) 1287 if (!(pticks % 7))
1431 shstr::gc (); 1288 shstr::gc ();
1434 flush_old_maps (); /* Clears the tmp-files of maps which have reset */ 1291 flush_old_maps (); /* Clears the tmp-files of maps which have reset */
1435 1292
1436 if (!(pticks % 2503)) 1293 if (!(pticks % 2503))
1437 fix_weight (); /* Hack to fix weightproblems caused by bugs */ 1294 fix_weight (); /* Hack to fix weightproblems caused by bugs */
1438 1295
1439 if (!(pticks % 2521))
1440 metaserver_update (); /* 2500 ticks is about 5 minutes */
1441
1442 if (!(pticks % 5003)) 1296 if (!(pticks % 5003))
1443 write_book_archive (); 1297 write_book_archive ();
1444 1298
1445 if (!(pticks % 5009)) 1299 if (!(pticks % 5009))
1446 clean_friendly_list (); 1300 clean_friendly_list ();
1455void 1309void
1456server_tick () 1310server_tick ()
1457{ 1311{
1458 nroferrors = 0; 1312 nroferrors = 0;
1459 1313
1314 // first do the user visible stuff
1460 doeric_server (); 1315 doeric_server ();
1461 INVOKE_GLOBAL (CLOCK); 1316 INVOKE_GLOBAL (CLOCK);
1462 process_events (NULL); /* "do" something with objects with speed */ 1317 process_events (); /* "do" something with objects with speed */
1463 flush_sockets (); 1318 flush_sockets ();
1319
1320 // then do some bookkeeping, should not really be here
1464 check_active_maps (); /* Removes unused maps after a certain timeout */ 1321 check_active_maps (); /* Removes unused maps after a certain timeout */
1465 do_specials (); /* Routines called from time to time. */ 1322 do_specials (); /* Routines called from time to time. */
1466 object::free_mortals (); 1323 attachable::check_mortals ();
1467 1324
1468 ++pticks; 1325 ++pticks;
1469} 1326}
1470 1327
1471int 1328int
1472main (int argc, char **argv) 1329main (int argc, char **argv)
1473{ 1330{
1474 settings.argc = argc; 1331 settings.argc = argc;
1475 settings.argv = argv; 1332 settings.argv = argv;
1476
1477 cfperl_init ();
1478 1333
1479 init (argc, argv); 1334 init (argc, argv);
1480 1335
1481 initPlugins (); 1336 initPlugins ();
1482 1337

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines