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.47 by root, Mon Dec 18 02:35:01 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)
164 * simple case at top - no encryption - makes it easier to read. 153 * simple case at top - no encryption - makes it easier to read.
165 */ 154 */
166char * 155char *
167crypt_string (char *str, char *salt) 156crypt_string (char *str, char *salt)
168{ 157{
169#if defined(WIN32) || (defined(__FreeBSD__) && !defined(HAVE_LIBDES)) 158#if (defined(__FreeBSD__) && !defined(HAVE_LIBDES))
170 return (str); 159 return (str);
171#else 160#else
172 static char *c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; 161 static char *c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
173 char s[2]; 162 char s[2];
174 163
197 * goes someplace. 186 * goes someplace.
198 */ 187 */
199void 188void
200enter_player_savebed (object *op) 189enter_player_savebed (object *op)
201{ 190{
202 mapstruct *oldmap = op->map; 191 maptile *oldmap = op->map;
203 object *tmp; 192 object *tmp;
204 193
205 tmp = get_object (); 194 tmp = object::create ();
206 195
207 EXIT_PATH (tmp) = op->contr->savebed_map; 196 EXIT_PATH (tmp) = op->contr->savebed_map;
208 EXIT_X (tmp) = op->contr->bed_x; 197 EXIT_X (tmp) = op->contr->bed_x;
209 EXIT_Y (tmp) = op->contr->bed_y; 198 EXIT_Y (tmp) = op->contr->bed_y;
210 enter_exit (op, tmp); 199 enter_exit (op, tmp);
223 EXIT_PATH (tmp) = op->contr->savebed_map; 212 EXIT_PATH (tmp) = op->contr->savebed_map;
224 EXIT_X (tmp) = op->contr->bed_x; 213 EXIT_X (tmp) = op->contr->bed_x;
225 EXIT_Y (tmp) = op->contr->bed_y; 214 EXIT_Y (tmp) = op->contr->bed_y;
226 enter_exit (op, tmp); 215 enter_exit (op, tmp);
227 } 216 }
228 free_object (tmp); 217
218 tmp->destroy ();
229} 219}
230 220
231/* 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
232 * the counts on the map if needed. 222 * the counts on the map if needed.
233 */ 223 */
234void 224void
235leave_map (object *op) 225leave_map (object *op)
236{ 226{
237 mapstruct *oldmap = op->map; 227 maptile *oldmap = op->map;
238 228
239 remove_ob (op); 229 op->remove ();
240 230
241 if (oldmap) 231 if (oldmap)
242 { 232 {
243 if (!op->contr->hidden) 233 if (!op->contr->hidden)
244 oldmap->players--; 234 oldmap->players--;
235
245 if (oldmap->players <= 0) 236 if (oldmap->players <= 0)
246 { /* can be less than zero due to errors in tracking this */ 237 /* can be less than zero due to errors in tracking this */
247 set_map_timeout (oldmap); 238 set_map_timeout (oldmap);
248 }
249 } 239 }
250} 240}
251 241
252/* 242/*
253 * 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
255 * 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
256 * whatever reason. If default map coordinates are to be used, then 246 * whatever reason. If default map coordinates are to be used, then
257 * the function that calls this should figure them out. 247 * the function that calls this should figure them out.
258 */ 248 */
259static void 249static void
260enter_map (object *op, mapstruct *newmap, int x, int y) 250enter_map (object *op, maptile *newmap, int x, int y)
261{ 251{
262 mapstruct *oldmap = op->map; 252 maptile *oldmap = op->map;
263 253
264 if (out_of_map (newmap, x, y)) 254 if (out_of_map (newmap, x, y))
265 { 255 {
266 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);
267 x = MAP_ENTER_X (newmap); 257 x = MAP_ENTER_X (newmap);
272 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap)); 262 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap));
273 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed"); 263 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed");
274 return; 264 return;
275 } 265 }
276 } 266 }
267
277 /* try to find a spot for the player */ 268 /* try to find a spot for the player */
278 if (ob_blocked (op, newmap, x, y)) 269 if (ob_blocked (op, newmap, x, y))
279 { /* First choice blocked */ 270 { /* First choice blocked */
280 /* 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.
281 * 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,
290 { 281 {
291 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1); 282 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1);
292 if (i == -1) 283 if (i == -1)
293 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE); 284 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE);
294 } 285 }
286
295 if (i != -1) 287 if (i != -1)
296 { 288 {
297 x += freearr_x[i]; 289 x += freearr_x[i];
298 y += freearr_y[i]; 290 y += freearr_y[i];
299 } 291 }
302 /* not much we can do in this case. */ 294 /* 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); 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);
304 } 296 }
305 } /* end if looking for free spot */ 297 } /* end if looking for free spot */
306 298
307 if (op->map != NULL) 299 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)); 300 if (INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)))
311 } 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;
312 308
313 /* 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.
314 * otherwise, we need to deal with removing the player here. 310 * otherwise, we need to deal with removing the player here.
315 */ 311 */
316 if (!QUERY_FLAG (op, FLAG_REMOVED)) 312 op->remove ();
317 remove_ob (op);
318 313
319 /* 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 */
320 op->x = x; 315 op->x = x;
321 op->y = y; 316 op->y = y;
322 op->map = newmap; 317 op->map = newmap;
318
323 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);
324
325 INVOKE_MAP (ENTER, op->map, ARG_PLAYER (op->contr));
326 320
327 if (!op->contr->hidden) 321 if (!op->contr->hidden)
328 newmap->players++; 322 newmap->players++;
329 323
330 newmap->timeout = 0; 324 newmap->timeout = 0;
340 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL) 334 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL)
341 { 335 {
342 int i = find_free_spot (op->contr->ranges[range_golem], newmap, 336 int i = find_free_spot (op->contr->ranges[range_golem], newmap,
343 x, y, 1, SIZEOFFREE); 337 x, y, 1, SIZEOFFREE);
344 338
345 remove_ob (op->contr->ranges[range_golem]); 339 op->contr->ranges[range_golem]->remove ();
340
346 if (i == -1) 341 if (i == -1)
347 { 342 {
348 remove_friendly_object (op->contr->ranges[range_golem]); 343 remove_friendly_object (op->contr->ranges[range_golem]);
349 free_object (op->contr->ranges[range_golem]); 344 op->contr->ranges[range_golem]->destroy ();
350 op->contr->ranges[range_golem] = NULL; 345 op->contr->ranges[range_golem] = 0;
351 op->contr->golem_count = 0;
352 } 346 }
353 else 347 else
354 { 348 {
355 object *tmp;
356
357 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)
358 { 350 {
359 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);
360 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);
361 tmp->map = newmap; 353 tmp->map = newmap;
362 } 354 }
355
363 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);
364 op->contr->ranges[range_golem]->direction = 357 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); 358 find_dir_2 (op->x - op->contr->ranges[range_golem]->x, op->y - op->contr->ranges[range_golem]->y);
366 } 359 }
367 } 360 }
361
368 op->direction = 0; 362 op->direction = 0;
369 363
370 /* 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
371 * about pending objects. 365 * about pending objects.
372 */ 366 */
387 } 381 }
388 } 382 }
389} 383}
390 384
391void 385void
392set_map_timeout (mapstruct *oldmap) 386set_map_timeout (maptile *oldmap)
393{ 387{
394#if MAP_MAXTIMEOUT 388#if MAP_MAXTIMEOUT
395 oldmap->timeout = MAP_TIMEOUT (oldmap); 389 oldmap->timeout = MAP_TIMEOUT (oldmap);
396 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is 390 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is
397 * lower than the min value. 391 * lower than the min value.
398 */ 392 */
399# if MAP_MINTIMEOUT 393# if MAP_MINTIMEOUT
400 if (oldmap->timeout < MAP_MINTIMEOUT) 394 if (oldmap->timeout < MAP_MINTIMEOUT)
401 {
402 oldmap->timeout = MAP_MINTIMEOUT; 395 oldmap->timeout = MAP_MINTIMEOUT;
403 }
404# endif 396# endif
397
405 if (oldmap->timeout > MAP_MAXTIMEOUT) 398 if (oldmap->timeout > MAP_MAXTIMEOUT)
406 {
407 oldmap->timeout = MAP_MAXTIMEOUT; 399 oldmap->timeout = MAP_MAXTIMEOUT;
408 } 400
409#else 401#else
410 /* save out the map */ 402 /* save out the map */
411 swap_map (oldmap); 403 swap_map (oldmap);
412#endif /* MAP_MAXTIMEOUT */ 404#endif /* MAP_MAXTIMEOUT */
413} 405}
418 */ 410 */
419char * 411char *
420clean_path (const char *file) 412clean_path (const char *file)
421{ 413{
422 static char newpath[MAX_BUF], *cp; 414 static char newpath[MAX_BUF], *cp;
415 assign (newpath, file);
423 416
424 strncpy (newpath, file, MAX_BUF - 1);
425 newpath[MAX_BUF - 1] = '\0';
426 for (cp = newpath; *cp != '\0'; cp++) 417 for (cp = newpath; *cp != '\0'; cp++)
427 {
428 if (*cp == '/') 418 if (*cp == '/')
429 *cp = '_'; 419 *cp = '_';
430 } 420
431 return newpath; 421 return newpath;
432} 422}
433 423
434 424
435/* unclean_path takes a path and replaces all _ with / 425/* unclean_path takes a path and replaces all _ with /
443unclean_path (const char *src) 433unclean_path (const char *src)
444{ 434{
445 static char newpath[MAX_BUF], *cp; 435 static char newpath[MAX_BUF], *cp;
446 436
447 cp = strrchr (src, '/'); 437 cp = strrchr (src, '/');
448 if (cp) 438 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 439
454 for (cp = newpath; *cp != '\0'; cp++) 440 for (cp = newpath; *cp != '\0'; cp++)
455 {
456 if (*cp == '_') 441 if (*cp == '_')
457 *cp = '/'; 442 *cp = '/';
458 } 443
459 return newpath; 444 return newpath;
460} 445}
461 446
462 447
463/* 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
465 */ 450 */
466 451
467static void 452static void
468enter_random_map (object *pl, object *exit_ob) 453enter_random_map (object *pl, object *exit_ob)
469{ 454{
470 mapstruct *new_map; 455 maptile *new_map;
471 char newmap_name[HUGE_BUF], *cp; 456 char newmap_name[HUGE_BUF], *cp;
472 static int reference_number = 0; 457 static int reference_number = 0;
473 RMParms rp; 458 RMParms rp;
474 459
475 memset (&rp, 0, sizeof (RMParms)); 460 memset (&rp, 0, sizeof (RMParms));
535 */ 520 */
536 521
537static void 522static void
538enter_fixed_template_map (object *pl, object *exit_ob) 523enter_fixed_template_map (object *pl, object *exit_ob)
539{ 524{
540 mapstruct *new_map; 525 maptile *new_map;
541 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap; 526 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap;
542 const char *new_map_name; 527 const char *new_map_name;
543 528
544 /* Split the exit path string into two parts, one 529 /* Split the exit path string into two parts, one
545 * for where to store the map, and one for were 530 * for where to store the map, and one for were
554 */ 539 */
555 LOG (llevError, "enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n", 540 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); 541 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
557 return; 542 return;
558 } 543 }
544
559 *sourcemap++ = '\0'; 545 *sourcemap++ = '\0';
560 546
561 /* If we are not coming from a template map, we can use relative directories 547 /* If we are not coming from a template map, we can use relative directories
562 * for the map to generate from. 548 * for the map to generate from.
563 */ 549 */
564 if (!exit_ob->map->templatemap) 550 if (!exit_ob->map->templatemap)
565 {
566 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap); 551 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap);
567 }
568 552
569 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 553 /* 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. 554 * of the exit, and the name of the map the exit is on, respectively.
571 */ 555 */
572 sprintf (tmpnum, "%d", exit_ob->x); 556 sprintf (tmpnum, "%d", exit_ob->x);
581 565
582 /* If we are coming from another template map, use reletive paths unless 566 /* If we are coming from another template map, use reletive paths unless
583 * indicated otherwise. 567 * indicated otherwise.
584 */ 568 */
585 if (exit_ob->map->templatemap && (resultname[0] != '/')) 569 if (exit_ob->map->templatemap && (resultname[0] != '/'))
586 {
587 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname); 570 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname);
588 }
589 else 571 else
590 {
591 new_map_name = create_template_pathname (resultname); 572 new_map_name = create_template_pathname (resultname);
592 }
593 573
594 /* Attempt to load the map, if unable to, then 574 /* Attempt to load the map, if unable to, then
595 * create the map from the template. 575 * create the map from the template.
596 */ 576 */
597 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE); 577 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", 599 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); 600 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
621 } 601 }
622} 602}
623 603
624
625/* The player is trying to enter a randomly generated template map. In this 604/* The player is trying to enter a randomly generated template map. In this
626 * case, generate the map as needed. 605 * case, generate the map as needed.
627 */ 606 */
628 607
629static void 608static void
630enter_random_template_map (object *pl, object *exit_ob) 609enter_random_template_map (object *pl, object *exit_ob)
631{ 610{
632 mapstruct *new_map; 611 maptile *new_map;
633 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF]; 612 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF];
634 const char *new_map_name; 613 const char *new_map_name;
635 RMParms rp; 614 RMParms rp;
636 615
637 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 616 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord
699 */ 678 */
700static void 679static void
701enter_unique_map (object *op, object *exit_ob) 680enter_unique_map (object *op, object *exit_ob)
702{ 681{
703 char apartment[HUGE_BUF]; 682 char apartment[HUGE_BUF];
704 mapstruct *newmap; 683 maptile *newmap;
705 684
706 if (EXIT_PATH (exit_ob)[0] == '/') 685 if (EXIT_PATH (exit_ob)[0] == '/')
707 { 686 {
708 sprintf (apartment, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, clean_path (EXIT_PATH (exit_ob))); 687 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); 688 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 */ 772#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */
794 object *tmp; 773 object *tmp;
795 774
796 /* It may be nice to support other creatures moving across 775 /* It may be nice to support other creatures moving across
797 * exits, but right now a lot of the code looks at op->contr, 776 * exits, but right now a lot of the code looks at op->contr,
798 * so thta is an RFE. 777 * so that is an RFE.
799 */ 778 */
800 if (op->type != PLAYER) 779 if (op->type != PLAYER)
801 return; 780 return;
802 781
803 /* First, lets figure out what map the player is going to go to */ 782 /* First, lets figure out what map the player is going to go to */
804 if (exit_ob) 783 if (exit_ob)
805 { 784 {
806
807 /* check to see if we make a template map */ 785 /* check to see if we make a template map */
808 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@') 786 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@')
809 { 787 {
810 if (EXIT_PATH (exit_ob)[2] == '!') 788 if (EXIT_PATH (exit_ob)[2] == '!')
811 { 789 {
832 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob); 810 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob);
833 811
834 /* 'Normal' exits that do not do anything special 812 /* 'Normal' exits that do not do anything special
835 * Simple enough we don't need another routine for it. 813 * Simple enough we don't need another routine for it.
836 */ 814 */
837 mapstruct *newmap; 815 maptile *newmap;
838 816
839 if (exit_ob->map) 817 if (exit_ob->map)
840 { 818 {
841 newmap = ready_map_name (path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)), 0); 819 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 820 /* Random map was previously generated, but is no longer about. Lets generate a new
910 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME)) 888 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME))
911 break; 889 break;
912 } 890 }
913 if (tmp) 891 if (tmp)
914 { 892 {
915 remove_ob (tmp); 893 tmp->remove ();
916 free_object (tmp); 894 tmp->destroy ();
917 } 895 }
918 896
919 strcpy (op->contr->savebed_map, path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob))); 897 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); 898 op->contr->bed_x = EXIT_X (exit_ob), op->contr->bed_y = EXIT_Y (exit_ob);
921 save_player (op, 1); 899 save_player (op, 1);
931 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1); 909 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
932 } 910 }
933 else 911 else
934 { 912 {
935 int flags = 0; 913 int flags = 0;
936 mapstruct *newmap; 914 maptile *newmap;
937
938 915
939 /* Hypothetically, I guess its possible that a standard map matches 916 /* Hypothetically, I guess its possible that a standard map matches
940 * the localdir, but that seems pretty unlikely - unlikely enough that 917 * the localdir, but that seems pretty unlikely - unlikely enough that
941 * I'm not going to attempt to try to deal with that possibility. 918 * 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 919 * We use the fact that when a player saves on a unique map, it prepends
963 { 940 {
964 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n"); 941 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n");
965 abort (); 942 abort ();
966 } 943 }
967 } 944 }
945
968 enter_map (op, newmap, op->x, op->y); 946 enter_map (op, newmap, op->x, op->y);
969 } 947 }
970} 948}
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 949
989/* process_players1 and process_players2 do all the player related stuff. 950/* 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 951 * 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 952 * 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 953 * by the various functions. process_players1() does the processing before
993 * objects have been updated, process_players2() does the processing that 954 * objects have been updated, process_players2() does the processing that
994 * is needed after the players have been updated. 955 * is needed after the players have been updated.
995 */ 956 */
996 957static void
997void 958process_players1 ()
998process_players1 (mapstruct *map)
999{ 959{
1000 int flag; 960 int flag;
1001 player *pl, *plnext;
1002
1003 /* Basically, we keep looping until all the players have done their actions. */ 961 /* Basically, we keep looping until all the players have done their actions. */
1004 for (flag = 1; flag != 0;) 962 for (flag = 1; flag != 0;)
1005 { 963 {
1006 flag = 0; 964 flag = 0;
1007 for (pl = first_player; pl != NULL; pl = plnext) 965 for (player *plnext, *pl = first_player; pl; pl = plnext)
1008 { 966 {
1009 plnext = pl->next; /* In case a player exits the game in handle_player() */ 967 plnext = pl->next; /* In case a player exits the game in handle_player() */
1010 968
1011 if (pl->ob == NULL) 969 if (!pl->ob)
1012 continue;
1013
1014 if (map != NULL && pl->ob->map != map)
1015 continue; 970 continue;
1016 971
1017 if (pl->ob->speed_left > 0) 972 if (pl->ob->speed_left > 0)
1018 { 973 {
1019 if (handle_newcs_player (pl->ob)) 974 if (handle_newcs_player (pl->ob))
1033 /* check for ST_PLAYING state so that we don't try to save off when 988 /* check for ST_PLAYING state so that we don't try to save off when
1034 * the player is logging in. 989 * the player is logging in.
1035 */ 990 */
1036 if ((pl->last_save_tick + AUTOSAVE) < (uint32) pticks && pl->state == ST_PLAYING) 991 if ((pl->last_save_tick + AUTOSAVE) < (uint32) pticks && pl->state == ST_PLAYING)
1037 { 992 {
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 */
1042// if (get_map_flags(pl->ob->map, NULL, pl->ob->x, pl->ob->y, NULL, NULL) & P_NO_CLERIC) {
1043// pl->last_save_tick += 100;
1044// } else {
1045 save_player (pl->ob, 1); 993 save_player (pl->ob, 1);
1046 pl->last_save_tick = pticks; 994 pl->last_save_tick = pticks;
1047// }
1048 } 995 }
1049#endif 996#endif
1050 } /* end of for loop for all the players */ 997 } /* end of for loop for all the players */
1051 } /* for flag */ 998 } /* for flag */
999
1052 for (pl = first_player; pl != NULL; pl = pl->next) 1000 for (player *pl = first_player; pl; pl = pl->next)
1053 { 1001 {
1054 if (map != NULL && (pl->ob == NULL || pl->ob->map != map))
1055 continue;
1056 if (settings.casting_time == TRUE) 1002 if (settings.casting_time)
1057 { 1003 {
1058 if (pl->ob->casting_time > 0) 1004 if (pl->ob->casting_time > 0)
1059 { 1005 {
1060 pl->ob->casting_time--; 1006 pl->ob->casting_time--;
1061 pl->ob->start_holding = 1; 1007 pl->ob->start_holding = 1;
1062 } 1008 }
1009
1063 /* set spell_state so we can update the range in stats field */ 1010 /* set spell_state so we can update the range in stats field */
1064 if ((pl->ob->casting_time == 0) && (pl->ob->start_holding == 1)) 1011 if ((pl->ob->casting_time == 0) && (pl->ob->start_holding == 1))
1065 {
1066 pl->ob->start_holding = 0; 1012 pl->ob->start_holding = 0;
1067 } 1013 }
1068 } 1014
1069 do_some_living (pl->ob); 1015 do_some_living (pl->ob);
1070 /* draw(pl->ob); *//* updated in socket code */
1071 } 1016 }
1072} 1017}
1073 1018
1074void 1019static void
1075process_players2 (mapstruct *map) 1020process_players2 ()
1076{ 1021{
1077 player *pl;
1078
1079 /* Then check if any players should use weapon-speed instead of speed */ 1022 /* Then check if any players should use weapon-speed instead of speed */
1080 for (pl = first_player; pl != NULL; pl = pl->next) 1023 for (player *pl = first_player; pl; pl = pl->next)
1081 { 1024 {
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 - 1025 /* The code that did weapon_sp handling here was out of place -
1093 * this isn't called until after the player has finished there 1026 * 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 1027 * actions, and is thus out of place. All we do here is bounds
1095 * checking. 1028 * checking.
1096 */ 1029 */
1102 /* This needs to be here - if the player is running, we need to 1035 /* 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 1036 * clear this each tick, but new commands are not being received
1104 * so execute_newserver_command() is never called 1037 * so execute_newserver_command() is never called
1105 */ 1038 */
1106 pl->has_hit = 0; 1039 pl->has_hit = 0;
1107
1108 } 1040 }
1109 else if (pl->ob->speed_left > pl->ob->speed) 1041 else if (pl->ob->speed_left > pl->ob->speed)
1110 pl->ob->speed_left = pl->ob->speed; 1042 pl->ob->speed_left = pl->ob->speed;
1111 } 1043 }
1112} 1044}
1113 1045
1114void 1046void
1115process_events (mapstruct *map) 1047process_events ()
1116{ 1048{
1117 object *op; 1049 object *op;
1118 object *marker = get_object ();
1119 tag_t tag;
1120 1050
1051 static object *marker;
1052
1053 if (!marker)
1054 marker = object::create ();
1055
1121 process_players1 (map); 1056 process_players1 ();
1122 1057
1123 marker->active_next = active_objects; 1058 marker->active_next = active_objects;
1124 1059
1125 if (marker->active_next) 1060 if (marker->active_next)
1126 marker->active_next->active_prev = marker; 1061 marker->active_next->active_prev = marker;
1129 active_objects = marker; 1064 active_objects = marker;
1130 1065
1131 while (marker->active_next) 1066 while (marker->active_next)
1132 { 1067 {
1133 op = marker->active_next; 1068 op = marker->active_next;
1134 tag = op->count;
1135 1069
1136 /* Move marker forward - swap op and marker */ 1070 /* Move marker forward - swap op and marker */
1137 op->active_prev = marker->active_prev; 1071 op->active_prev = marker->active_prev;
1138 1072
1139 if (op->active_prev) 1073 if (op->active_prev)
1169 * around. 1103 * around.
1170 */ 1104 */
1171 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY) 1105 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY)
1172 { 1106 {
1173 LOG (llevError, "BUG: process_events(): Removed object on list\n"); 1107 LOG (llevError, "BUG: process_events(): Removed object on list\n");
1174 dump_object (op); 1108 char *dump = dump_object (op);
1175 LOG (llevError, errmsg); 1109 LOG (llevError, dump);
1176 free_object (op); 1110 free (dump);
1111 op->destroy ();
1177 continue; 1112 continue;
1178 } 1113 }
1179 1114
1180 if (!op->speed) 1115 if (!op->speed)
1181 { 1116 {
1182 LOG (llevError, "BUG: process_events(): Object %s has no speed, " "but is on active list\n", &op->arch->name); 1117 LOG (llevError, "BUG: process_events(): Object %s has no speed, "
1118 "but is on active list\n", &op->arch->name);
1183 update_ob_speed (op); 1119 update_ob_speed (op);
1184 continue; 1120 continue;
1185 } 1121 }
1186 1122
1187 if (op->map == NULL && op->env == NULL && op->name && op->type != MAP && map == NULL) 1123 if (op->map == NULL && op->env == NULL && op->name && op->type != MAP)
1188 { 1124 {
1189 LOG (llevError, "BUG: process_events(): Object without map or " "inventory is on active list: %s (%d)\n", &op->name, op->count); 1125 LOG (llevError, "BUG: process_events(): Object without map or "
1126 "inventory is on active list: %s (%d)\n", &op->name, op->count);
1190 op->speed = 0; 1127 op->speed = 0;
1191 update_ob_speed (op); 1128 update_ob_speed (op);
1192 continue; 1129 continue;
1193 } 1130 }
1194 1131
1195 if (map != NULL && op->map != map)
1196 continue;
1197
1198 /* Animate the object. Bug of feature that andim_speed 1132 /* Animate the object. Bug or feature that anim_speed
1199 * is based on ticks, and not the creatures speed? 1133 * is based on ticks, and not the creatures speed?
1200 */ 1134 */
1201 if (op->anim_speed && op->last_anim >= op->anim_speed) 1135 if (op->anim_speed && op->last_anim >= op->anim_speed)
1202 { 1136 {
1203 if ((op->type == PLAYER) || (op->type == MONSTER)) 1137 if ((op->type == PLAYER) || (op->type == MONSTER))
1226 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null"); 1160 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null");
1227 } 1161 }
1228#endif 1162#endif
1229 --op->speed_left; 1163 --op->speed_left;
1230 process_object (op); 1164 process_object (op);
1165
1231 if (was_destroyed (op, tag)) 1166 if (op->destroyed ())
1232 continue; 1167 continue;
1233 } 1168 }
1169
1234 if (settings.casting_time == TRUE && op->casting_time > 0) 1170 if (settings.casting_time == TRUE && op->casting_time > 0)
1235 op->casting_time--; 1171 op->casting_time--;
1172
1236 if (op->speed_left <= 0) 1173 if (op->speed_left <= 0)
1237 op->speed_left += FABS (op->speed); 1174 op->speed_left += FABS (op->speed);
1238 } 1175 }
1239 1176
1240 /* Remove marker object from active list */ 1177 /* Remove marker object from active list */
1241 if (marker->active_prev != NULL) 1178 if (marker->active_prev != NULL)
1242 marker->active_prev->active_next = NULL; 1179 marker->active_prev->active_next = NULL;
1243 else 1180 else
1244 active_objects = NULL; 1181 active_objects = NULL;
1245 1182
1246 process_players2 (map); 1183 process_players2 ();
1247
1248 free_object (marker);
1249} 1184}
1250 1185
1251void 1186void
1252clean_tmp_files (void) 1187clean_tmp_files (void)
1253{ 1188{
1254 mapstruct *m, *next; 1189 maptile *m, *next;
1255 1190
1256 LOG (llevInfo, "Cleaning up...\n"); 1191 LOG (llevInfo, "Cleaning up...\n");
1257 1192
1258 /* We save the maps - it may not be intuitive why, but if there are unique 1193 /* 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 1194 * 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. 1195 * just make a special function that only saves the unique items.
1261 */ 1196 */
1262 for (m = first_map; m != NULL; m = next) 1197 for (m = first_map; m; m = next)
1263 { 1198 {
1264 next = m->next; 1199 next = m->next;
1200
1265 if (m->in_memory == MAP_IN_MEMORY) 1201 if (m->in_memory == MAP_IN_MEMORY)
1266 { 1202 {
1267 /* If we want to reuse the temp maps, swap it out (note that will also 1203 /* 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 1204 * 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 */ 1205 */
1273 1206
1274 /* XXX The above comment is dead wrong */
1275 if (settings.recycle_tmp_maps == TRUE)
1276 swap_map (m); 1207 swap_map (m);
1277 else
1278 {
1279 new_save_map (m, 0); /* note we save here into a overlay map */
1280 clean_tmp_map (m);
1281 } 1208 }
1282 }
1283 } 1209 }
1210
1284 write_todclock (); /* lets just write the clock here */ 1211 write_todclock (); /* lets just write the clock here */
1285} 1212}
1286 1213
1287/* clean up everything before exiting */ 1214/* clean up everything before exiting */
1288void 1215void
1289cleanup (void) 1216cleanup (void)
1290{ 1217{
1291 LOG (llevDebug, "Cleanup called. freeing data.\n"); 1218 LOG (llevDebug, "Cleanup called.\n");
1219
1220 for (player *pl = first_player; pl != NULL; pl = pl->next)
1221 save_player (pl->ob, 0);
1222
1223 for (player *pl = first_player; pl != NULL; pl = pl->next)
1224 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1225 leave_map (pl->ob);
1226
1292 clean_tmp_files (); 1227 clean_tmp_files ();
1293 write_book_archive (); 1228 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 1229
1308/* LOG(llevDebug, ss_dump_table(0xff));*/ 1230 INVOKE_GLOBAL (CLEANUP);
1309#endif 1231
1310 exit (0); 1232 _exit (0);
1311} 1233}
1312 1234
1313void 1235void
1314leave (player *pl, int draw_exit) 1236leave (player *pl, int draw_exit)
1315{ 1237{
1319 * cleanup. We also leave that loop to actually handle the freeing 1241 * cleanup. We also leave that loop to actually handle the freeing
1320 * of the data. 1242 * of the data.
1321 */ 1243 */
1322 if (pl->ob->type != DEAD_OBJECT) 1244 if (pl->ob->type != DEAD_OBJECT)
1323 { 1245 {
1324 pl->socket.status = Ns_Dead; 1246 pl->socket->status = Ns_Dead;
1325 1247
1326 /* If a hidden dm dropped connection do not create 1248 /* If a hidden dm dropped connection do not create
1327 * inconsistencies by showing that they have left the game 1249 * inconsistencies by showing that they have left the game
1328 */ 1250 */
1329 if (!(QUERY_FLAG (pl->ob, FLAG_WIZ) && pl->ob->contr->hidden) 1251 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)) 1252 && draw_exit && (pl->state != ST_GET_NAME && pl->state != ST_GET_PASSWORD && pl->state != ST_CONFIRM_PASSWORD))
1331 { 1253 {
1332 if (pl->ob->map) 1254 if (pl->ob->map)
1333 { 1255 {
1334 INVOKE_PLAYER (LOGOUT, pl); 1256 INVOKE_PLAYER (LOGOUT, pl);
1335 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket.host); 1257 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket->host);
1336 } 1258 }
1337 1259
1338 char buf[MAX_BUF]; 1260 char buf[MAX_BUF];
1339 1261
1340 sprintf (buf, "%s left the game.", &pl->ob->name); 1262 sprintf (buf, "%s left the game.", &pl->ob->name);
1416extern unsigned long todtick; 1338extern unsigned long todtick;
1417 1339
1418void 1340void
1419do_specials (void) 1341do_specials (void)
1420{ 1342{
1421
1422#ifdef WATCHDOG
1423 if (!(pticks % 503))
1424 watchdog ();
1425#endif
1426
1427 if (!(pticks % PTICKS_PER_CLOCK)) 1343 if (!(pticks % PTICKS_PER_CLOCK))
1428 tick_the_clock (); 1344 tick_the_clock ();
1429 1345
1430 if (!(pticks % 7)) 1346 if (!(pticks % 7))
1431 shstr::gc (); 1347 shstr::gc ();
1434 flush_old_maps (); /* Clears the tmp-files of maps which have reset */ 1350 flush_old_maps (); /* Clears the tmp-files of maps which have reset */
1435 1351
1436 if (!(pticks % 2503)) 1352 if (!(pticks % 2503))
1437 fix_weight (); /* Hack to fix weightproblems caused by bugs */ 1353 fix_weight (); /* Hack to fix weightproblems caused by bugs */
1438 1354
1439 if (!(pticks % 2521))
1440 metaserver_update (); /* 2500 ticks is about 5 minutes */
1441
1442 if (!(pticks % 5003)) 1355 if (!(pticks % 5003))
1443 write_book_archive (); 1356 write_book_archive ();
1444 1357
1445 if (!(pticks % 5009)) 1358 if (!(pticks % 5009))
1446 clean_friendly_list (); 1359 clean_friendly_list ();
1455void 1368void
1456server_tick () 1369server_tick ()
1457{ 1370{
1458 nroferrors = 0; 1371 nroferrors = 0;
1459 1372
1373 // first do the user visible stuff
1460 doeric_server (); 1374 doeric_server ();
1461 INVOKE_GLOBAL (CLOCK); 1375 INVOKE_GLOBAL (CLOCK);
1462 process_events (NULL); /* "do" something with objects with speed */ 1376 process_events (); /* "do" something with objects with speed */
1463 flush_sockets (); 1377 flush_sockets ();
1378
1379 // then do some bookkeeping, should not really be here
1464 check_active_maps (); /* Removes unused maps after a certain timeout */ 1380 check_active_maps (); /* Removes unused maps after a certain timeout */
1465 do_specials (); /* Routines called from time to time. */ 1381 do_specials (); /* Routines called from time to time. */
1466 object::free_mortals (); 1382 object::free_mortals ();
1467 1383
1468 ++pticks; 1384 ++pticks;
1472main (int argc, char **argv) 1388main (int argc, char **argv)
1473{ 1389{
1474 settings.argc = argc; 1390 settings.argc = argc;
1475 settings.argv = argv; 1391 settings.argv = argv;
1476 1392
1477 cfperl_init ();
1478
1479 init (argc, argv); 1393 init (argc, argv);
1480 1394
1481 initPlugins (); 1395 initPlugins ();
1482 1396
1483 for (;;) 1397 for (;;)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines