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

Comparing deliantra/server/server/main.C (file contents):
Revision 1.22 by root, Sat Sep 9 21:48:29 2006 UTC vs.
Revision 1.40 by root, Tue Dec 12 20:53:03 2006 UTC

1/*
2 * static char *rcsid_main_c =
3 * "$Id: main.C,v 1.22 2006/09/09 21:48:29 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2001-2003 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001-2003 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 22*/
28 23
29#include <global.h> 24#include <global.h>
30#include <object.h> 25#include <object.h>
31#include <tod.h> 26#include <tod.h>
32 27
33#ifdef HAVE_DES_H 28#ifdef HAVE_DES_H
34#include <des.h> 29# include <des.h>
35#else 30#else
36# ifdef HAVE_CRYPT_H 31# ifdef HAVE_CRYPT_H
37# include <crypt.h> 32# include <crypt.h>
38# endif 33# endif
39#endif 34#endif
40 35
41#ifndef __CEXTRACT__ 36#ifndef __CEXTRACT__
42#include <sproto.h> 37# include <sproto.h>
43#endif 38#endif
44 39
45#ifdef HAVE_TIME_H 40#ifdef HAVE_TIME_H
46#include <time.h> 41# include <time.h>
47#endif 42#endif
48 43
49#include <../random_maps/random_map.h> 44#include <../random_maps/random_map.h>
50#include <../random_maps/rproto.h> 45#include <../random_maps/rproto.h>
51#include "path.h" 46#include "path.h"
53static char days[7][4] = { 48static char days[7][4] = {
54 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 49 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
55}; 50};
56 51
57void 52void
58version (object * op) 53version (object *op)
59{ 54{
60 if (op != NULL) 55 if (op != NULL)
61 clear_win_info (op); 56 clear_win_info (op);
62 57
63 new_draw_info_format (NDI_UNIQUE, 0, op, "This is Crossfire v%s", VERSION); 58 new_draw_info_format (NDI_UNIQUE, 0, op, "This is Crossfire v%s", VERSION);
111 new_draw_info (NDI_UNIQUE, 0, op, "Images and art:"); 106 new_draw_info (NDI_UNIQUE, 0, op, "Images and art:");
112 new_draw_info (NDI_UNIQUE, 0, op, "Peter Gardner"); 107 new_draw_info (NDI_UNIQUE, 0, op, "Peter Gardner");
113 new_draw_info (NDI_UNIQUE, 0, op, "David Gervais [david_eg@mail.com]"); 108 new_draw_info (NDI_UNIQUE, 0, op, "David Gervais [david_eg@mail.com]");
114 new_draw_info (NDI_UNIQUE, 0, op, "Mitsuhiro Itakura [ita@gold.koma.jaeri.go.jp]"); 109 new_draw_info (NDI_UNIQUE, 0, op, "Mitsuhiro Itakura [ita@gold.koma.jaeri.go.jp]");
115 new_draw_info (NDI_UNIQUE, 0, op, "Hansjoerg Malthaner [hansjoerg.malthaner@danet.de]"); 110 new_draw_info (NDI_UNIQUE, 0, op, "Hansjoerg Malthaner [hansjoerg.malthaner@danet.de]");
116 new_draw_info (NDI_UNIQUE, 0, op, "Mårten Woxberg [maxmc@telia.com]"); 111 new_draw_info (NDI_UNIQUE, 0, op, "MÃ¥rten Woxberg [maxmc@telia.com]");
117 new_draw_info (NDI_UNIQUE, 0, op, "And many more!"); 112 new_draw_info (NDI_UNIQUE, 0, op, "And many more!");
118} 113}
119 114
120void 115void
121info_keys (object * op) 116info_keys (object *op)
122{ 117{
123 clear_win_info (op); 118 clear_win_info (op);
124 new_draw_info (NDI_UNIQUE, 0, op, "Push `hjklynub' to walk in a direction."); 119 new_draw_info (NDI_UNIQUE, 0, op, "Push `hjklynub' to walk in a direction.");
125 new_draw_info (NDI_UNIQUE, 0, op, "Shift + dir = fire, Ctrl + dir = run"); 120 new_draw_info (NDI_UNIQUE, 0, op, "Shift + dir = fire, Ctrl + dir = run");
126 new_draw_info (NDI_UNIQUE, 0, op, "(To fire at yourself, hit `.'"); 121 new_draw_info (NDI_UNIQUE, 0, op, "(To fire at yourself, hit `.'");
139 new_draw_info (NDI_UNIQUE, 0, op, "You can type a number before most commands."); 134 new_draw_info (NDI_UNIQUE, 0, op, "You can type a number before most commands.");
140 new_draw_info (NDI_UNIQUE, 0, op, "(For instance 3d drops 3 items.)"); 135 new_draw_info (NDI_UNIQUE, 0, op, "(For instance 3d drops 3 items.)");
141} 136}
142 137
143void 138void
144start_info (object * op) 139start_info (object *op)
145{ 140{
146 char buf[MAX_BUF]; 141 char buf[MAX_BUF];
147 142
148 sprintf (buf, "Welcome to Crossfire, v%s!", VERSION); 143 sprintf (buf, "Welcome to Crossfire, v%s!", VERSION);
149 new_draw_info (NDI_UNIQUE, 0, op, buf); 144 new_draw_info (NDI_UNIQUE, 0, op, buf);
163 * simple case at top - no encryption - makes it easier to read. 158 * simple case at top - no encryption - makes it easier to read.
164 */ 159 */
165char * 160char *
166crypt_string (char *str, char *salt) 161crypt_string (char *str, char *salt)
167{ 162{
168#if defined(WIN32) || (defined(__FreeBSD__) && !defined(HAVE_LIBDES)) 163#if (defined(__FreeBSD__) && !defined(HAVE_LIBDES))
169 return (str); 164 return (str);
170#else 165#else
171 static char *c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; 166 static char *c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
172 char s[2]; 167 char s[2];
173 168
174 if (salt == NULL) 169 if (salt == NULL)
175 s[0] = c[RANDOM () % (int) strlen (c)], s[1] = c[RANDOM () % (int) strlen (c)]; 170 s[0] = c[RANDOM () % (int) strlen (c)], s[1] = c[RANDOM () % (int) strlen (c)];
176 else 171 else
177 s[0] = salt[0], s[1] = salt[1]; 172 s[0] = salt[0], s[1] = salt[1];
178 173
179# ifdef HAVE_LIBDES 174# ifdef HAVE_LIBDES
180 return (char *) des_crypt (str, s); 175 return (char *) des_crypt (str, s);
181# endif 176# endif
182 /* Default case - just use crypt */ 177 /* Default case - just use crypt */
183 return (char *) crypt (str, s); 178 return (char *) crypt (str, s);
184#endif 179#endif
185} 180}
186 181
194 * savebed. We do some error checking - its possible that the 189 * savebed. We do some error checking - its possible that the
195 * savebed map may no longer exist, so we make sure the player 190 * savebed map may no longer exist, so we make sure the player
196 * goes someplace. 191 * goes someplace.
197 */ 192 */
198void 193void
199enter_player_savebed (object * op) 194enter_player_savebed (object *op)
200{ 195{
201 mapstruct *oldmap = op->map; 196 maptile *oldmap = op->map;
202 object *tmp; 197 object *tmp;
203 198
204 tmp = get_object (); 199 tmp = get_object ();
205 200
206 EXIT_PATH (tmp) = op->contr->savebed_map; 201 EXIT_PATH (tmp) = op->contr->savebed_map;
222 EXIT_PATH (tmp) = op->contr->savebed_map; 217 EXIT_PATH (tmp) = op->contr->savebed_map;
223 EXIT_X (tmp) = op->contr->bed_x; 218 EXIT_X (tmp) = op->contr->bed_x;
224 EXIT_Y (tmp) = op->contr->bed_y; 219 EXIT_Y (tmp) = op->contr->bed_y;
225 enter_exit (op, tmp); 220 enter_exit (op, tmp);
226 } 221 }
227 free_object (tmp); 222 tmp->destroy (0);
228} 223}
229 224
230/* All this really is is a glorified remove_object that also updates 225/* All this really is is a glorified remove_object that also updates
231 * the counts on the map if needed. 226 * the counts on the map if needed.
232 */ 227 */
233void 228void
234leave_map (object * op) 229leave_map (object *op)
235{ 230{
236 mapstruct *oldmap = op->map; 231 maptile *oldmap = op->map;
237 232
238 remove_ob (op); 233 op->remove ();
239 234
240 if (oldmap) 235 if (oldmap)
241 { 236 {
242 if (!op->contr->hidden) 237 if (!op->contr->hidden)
243 oldmap->players--; 238 oldmap->players--;
239
244 if (oldmap->players <= 0) 240 if (oldmap->players <= 0)
245 { /* can be less than zero due to errors in tracking this */ 241 /* can be less than zero due to errors in tracking this */
246 set_map_timeout (oldmap); 242 set_map_timeout (oldmap);
247 }
248 } 243 }
249} 244}
250 245
251/* 246/*
252 * enter_map(): Moves the player and pets from current map (if any) to 247 * enter_map(): Moves the player and pets from current map (if any) to
254 * player to - it could be the map he just came from if the load failed for 249 * player to - it could be the map he just came from if the load failed for
255 * whatever reason. If default map coordinates are to be used, then 250 * whatever reason. If default map coordinates are to be used, then
256 * the function that calls this should figure them out. 251 * the function that calls this should figure them out.
257 */ 252 */
258static void 253static void
259enter_map (object * op, mapstruct * newmap, int x, int y) 254enter_map (object *op, maptile *newmap, int x, int y)
260{ 255{
261 mapstruct *oldmap = op->map; 256 maptile *oldmap = op->map;
262 257
263 if (out_of_map (newmap, x, y)) 258 if (out_of_map (newmap, x, y))
264 { 259 {
265 LOG (llevError, "enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->path, x, y); 260 LOG (llevError, "enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->path, x, y);
266 x = MAP_ENTER_X (newmap); 261 x = MAP_ENTER_X (newmap);
271 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap)); 266 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap));
272 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed"); 267 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed");
273 return; 268 return;
274 } 269 }
275 } 270 }
271
276 /* try to find a spot for the player */ 272 /* try to find a spot for the player */
277 if (ob_blocked (op, newmap, x, y)) 273 if (ob_blocked (op, newmap, x, y))
278 { /* First choice blocked */ 274 { /* First choice blocked */
279 /* We try to find a spot for the player, starting closest in. 275 /* We try to find a spot for the player, starting closest in.
280 * We could use find_first_free_spot, but that doesn't randomize it at all, 276 * We could use find_first_free_spot, but that doesn't randomize it at all,
282 * if other spaces around are available. 278 * if other spaces around are available.
283 * Note that for the second and third calls, we could start at a position other 279 * Note that for the second and third calls, we could start at a position other
284 * than one, but then we could end up on the other side of walls and so forth. 280 * than one, but then we could end up on the other side of walls and so forth.
285 */ 281 */
286 int i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE1 + 1); 282 int i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE1 + 1);
283
287 if (i == -1) 284 if (i == -1)
288 { 285 {
289 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1); 286 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1);
290 if (i == -1) 287 if (i == -1)
291 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE); 288 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE);
292 } 289 }
290
293 if (i != -1) 291 if (i != -1)
294 { 292 {
295 x += freearr_x[i]; 293 x += freearr_x[i];
296 y += freearr_y[i]; 294 y += freearr_y[i];
297 } 295 }
300 /* not much we can do in this case. */ 298 /* not much we can do in this case. */
301 LOG (llevInfo, "enter_map: Could not find free spot for player - will dump on top of object (%s: %d, %d)\n", newmap->path, x, y); 299 LOG (llevInfo, "enter_map: Could not find free spot for player - will dump on top of object (%s: %d, %d)\n", newmap->path, x, y);
302 } 300 }
303 } /* end if looking for free spot */ 301 } /* end if looking for free spot */
304 302
305 if (op->map != NULL) 303 if (op->map)
306 {
307 INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (op->map), ARG_MAP (newmap));
308 INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)); 304 if (INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)))
309 } 305 return;
306
307 if (INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (newmap), ARG_INT (x), ARG_INT (y)))
308 return;
309
310 if (INVOKE_MAP (ENTER, newmap, ARG_PLAYER (op->contr), ARG_INT (x), ARG_INT (y)))
311 return;
310 312
311 /* If it is a player login, he has yet to be inserted anyplace. 313 /* If it is a player login, he has yet to be inserted anyplace.
312 * otherwise, we need to deal with removing the player here. 314 * otherwise, we need to deal with removing the player here.
313 */ 315 */
314 if (!QUERY_FLAG (op, FLAG_REMOVED)) 316 op->remove ();
315 remove_ob (op);
316 317
317 /* remove_ob clears these so they must be reset after the remove_ob call */ 318 /* remove_ob clears these so they must be reset after the remove_ob call */
318 op->x = x; 319 op->x = x;
319 op->y = y; 320 op->y = y;
320 op->map = newmap; 321 op->map = newmap;
322
321 insert_ob_in_map (op, op->map, NULL, INS_NO_WALK_ON); 323 insert_ob_in_map (op, op->map, NULL, INS_NO_WALK_ON);
322
323 INVOKE_MAP (ENTER, op->map, ARG_PLAYER (op->contr));
324 324
325 if (!op->contr->hidden) 325 if (!op->contr->hidden)
326 newmap->players++; 326 newmap->players++;
327 327
328 newmap->timeout = 0; 328 newmap->timeout = 0;
337 /* Update any golems */ 337 /* Update any golems */
338 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL) 338 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL)
339 { 339 {
340 int i = find_free_spot (op->contr->ranges[range_golem], newmap, 340 int i = find_free_spot (op->contr->ranges[range_golem], newmap,
341 x, y, 1, SIZEOFFREE); 341 x, y, 1, SIZEOFFREE);
342
342 remove_ob (op->contr->ranges[range_golem]); 343 op->contr->ranges[range_golem]->remove ();
344
343 if (i == -1) 345 if (i == -1)
344 { 346 {
345 remove_friendly_object (op->contr->ranges[range_golem]); 347 remove_friendly_object (op->contr->ranges[range_golem]);
346 free_object (op->contr->ranges[range_golem]); 348 op->contr->ranges[range_golem]->destroy (0);
347 op->contr->ranges[range_golem] = NULL; 349 op->contr->ranges[range_golem] = 0;
348 op->contr->golem_count = 0;
349 } 350 }
350 else 351 else
351 { 352 {
352 object *tmp;
353 for (tmp = op->contr->ranges[range_golem]; tmp != NULL; tmp = tmp->more) 353 for (object *tmp = op->contr->ranges[range_golem]; tmp != NULL; tmp = tmp->more)
354 { 354 {
355 tmp->x = x + freearr_x[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x); 355 tmp->x = x + freearr_x[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x);
356 tmp->y = y + freearr_y[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y); 356 tmp->y = y + freearr_y[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y);
357 tmp->map = newmap; 357 tmp->map = newmap;
358 } 358 }
359
359 insert_ob_in_map (op->contr->ranges[range_golem], newmap, NULL, 0); 360 insert_ob_in_map (op->contr->ranges[range_golem], newmap, NULL, 0);
360 op->contr->ranges[range_golem]->direction = 361 op->contr->ranges[range_golem]->direction =
361 find_dir_2 (op->x - op->contr->ranges[range_golem]->x, op->y - op->contr->ranges[range_golem]->y); 362 find_dir_2 (op->x - op->contr->ranges[range_golem]->x, op->y - op->contr->ranges[range_golem]->y);
362 } 363 }
363 } 364 }
365
364 op->direction = 0; 366 op->direction = 0;
365 367
366 /* since the players map is already loaded, we don't need to worry 368 /* since the players map is already loaded, we don't need to worry
367 * about pending objects. 369 * about pending objects.
368 */ 370 */
383 } 385 }
384 } 386 }
385} 387}
386 388
387void 389void
388set_map_timeout (mapstruct * oldmap) 390set_map_timeout (maptile *oldmap)
389{ 391{
390#if MAP_MAXTIMEOUT 392#if MAP_MAXTIMEOUT
391 oldmap->timeout = MAP_TIMEOUT (oldmap); 393 oldmap->timeout = MAP_TIMEOUT (oldmap);
392 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is 394 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is
393 * lower than the min value. 395 * lower than the min value.
394 */ 396 */
395#if MAP_MINTIMEOUT 397# if MAP_MINTIMEOUT
396 if (oldmap->timeout < MAP_MINTIMEOUT) 398 if (oldmap->timeout < MAP_MINTIMEOUT)
397 {
398 oldmap->timeout = MAP_MINTIMEOUT; 399 oldmap->timeout = MAP_MINTIMEOUT;
399 }
400#endif 400# endif
401
401 if (oldmap->timeout > MAP_MAXTIMEOUT) 402 if (oldmap->timeout > MAP_MAXTIMEOUT)
402 {
403 oldmap->timeout = MAP_MAXTIMEOUT; 403 oldmap->timeout = MAP_MAXTIMEOUT;
404 } 404
405#else 405#else
406 /* save out the map */ 406 /* save out the map */
407 swap_map (oldmap); 407 swap_map (oldmap);
408#endif /* MAP_MAXTIMEOUT */ 408#endif /* MAP_MAXTIMEOUT */
409} 409}
414 */ 414 */
415char * 415char *
416clean_path (const char *file) 416clean_path (const char *file)
417{ 417{
418 static char newpath[MAX_BUF], *cp; 418 static char newpath[MAX_BUF], *cp;
419 assign (newpath, file);
419 420
420 strncpy (newpath, file, MAX_BUF - 1);
421 newpath[MAX_BUF - 1] = '\0';
422 for (cp = newpath; *cp != '\0'; cp++) 421 for (cp = newpath; *cp != '\0'; cp++)
423 {
424 if (*cp == '/') 422 if (*cp == '/')
425 *cp = '_'; 423 *cp = '_';
426 } 424
427 return newpath; 425 return newpath;
428} 426}
429 427
430 428
431/* unclean_path takes a path and replaces all _ with / 429/* unclean_path takes a path and replaces all _ with /
439unclean_path (const char *src) 437unclean_path (const char *src)
440{ 438{
441 static char newpath[MAX_BUF], *cp; 439 static char newpath[MAX_BUF], *cp;
442 440
443 cp = strrchr (src, '/'); 441 cp = strrchr (src, '/');
444 if (cp) 442 assign (newpath, cp ? cp + 1 : src);
445 strncpy (newpath, cp + 1, MAX_BUF - 1);
446 else
447 strncpy (newpath, src, MAX_BUF - 1);
448 newpath[MAX_BUF - 1] = '\0';
449 443
450 for (cp = newpath; *cp != '\0'; cp++) 444 for (cp = newpath; *cp != '\0'; cp++)
451 {
452 if (*cp == '_') 445 if (*cp == '_')
453 *cp = '/'; 446 *cp = '/';
454 } 447
455 return newpath; 448 return newpath;
456} 449}
457 450
458 451
459/* The player is trying to enter a randomly generated map. In this case, generate the 452/* The player is trying to enter a randomly generated map. In this case, generate the
460 * random map as needed. 453 * random map as needed.
461 */ 454 */
462 455
463static void 456static void
464enter_random_map (object * pl, object * exit_ob) 457enter_random_map (object *pl, object *exit_ob)
465{ 458{
466 mapstruct *new_map; 459 maptile *new_map;
467 char newmap_name[HUGE_BUF], *cp; 460 char newmap_name[HUGE_BUF], *cp;
468 static int reference_number = 0; 461 static int reference_number = 0;
469 RMParms rp; 462 RMParms rp;
470 463
471 memset (&rp, 0, sizeof (RMParms)); 464 memset (&rp, 0, sizeof (RMParms));
515 * the exit leading to it, that the exit will no longer work. 508 * the exit leading to it, that the exit will no longer work.
516 */ 509 */
517 if (new_map) 510 if (new_map)
518 { 511 {
519 int x, y; 512 int x, y;
513
520 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map); 514 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map);
521 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map); 515 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map);
522 EXIT_PATH (exit_ob) = newmap_name; 516 EXIT_PATH (exit_ob) = newmap_name;
523 strcpy (new_map->path, newmap_name); 517 strcpy (new_map->path, newmap_name);
524 enter_map (pl, new_map, x, y); 518 enter_map (pl, new_map, x, y);
528/* The player is trying to enter a non-randomly generated template map. In this 522/* The player is trying to enter a non-randomly generated template map. In this
529 * case, use a map file for a template 523 * case, use a map file for a template
530 */ 524 */
531 525
532static void 526static void
533enter_fixed_template_map (object * pl, object * exit_ob) 527enter_fixed_template_map (object *pl, object *exit_ob)
534{ 528{
535 mapstruct *new_map; 529 maptile *new_map;
536 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap; 530 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap;
537 const char *new_map_name; 531 const char *new_map_name;
538 532
539 /* Split the exit path string into two parts, one 533 /* Split the exit path string into two parts, one
540 * for where to store the map, and one for were 534 * for where to store the map, and one for were
549 */ 543 */
550 LOG (llevError, "enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n", 544 LOG (llevError, "enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n",
551 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); 545 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
552 return; 546 return;
553 } 547 }
548
554 *sourcemap++ = '\0'; 549 *sourcemap++ = '\0';
555 550
556 /* If we are not coming from a template map, we can use relative directories 551 /* If we are not coming from a template map, we can use relative directories
557 * for the map to generate from. 552 * for the map to generate from.
558 */ 553 */
559 if (!exit_ob->map->templatemap) 554 if (!exit_ob->map->templatemap)
560 {
561 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap); 555 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap);
562 }
563 556
564 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 557 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord
565 * of the exit, and the name of the map the exit is on, respectively. 558 * of the exit, and the name of the map the exit is on, respectively.
566 */ 559 */
567 sprintf (tmpnum, "%d", exit_ob->x); 560 sprintf (tmpnum, "%d", exit_ob->x);
576 569
577 /* If we are coming from another template map, use reletive paths unless 570 /* If we are coming from another template map, use reletive paths unless
578 * indicated otherwise. 571 * indicated otherwise.
579 */ 572 */
580 if (exit_ob->map->templatemap && (resultname[0] != '/')) 573 if (exit_ob->map->templatemap && (resultname[0] != '/'))
581 {
582 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname); 574 new_map_name = path_combine_and_normalize (exit_ob->map->path, resultname);
583 }
584 else 575 else
585 {
586 new_map_name = create_template_pathname (resultname); 576 new_map_name = create_template_pathname (resultname);
587 }
588 577
589 /* Attempt to load the map, if unable to, then 578 /* Attempt to load the map, if unable to, then
590 * create the map from the template. 579 * create the map from the template.
591 */ 580 */
592 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE); 581 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE);
614 LOG (llevDebug, "enter_fixed_template_map: Exit %s (%d,%d) on map %s leads no where.\n", 603 LOG (llevDebug, "enter_fixed_template_map: Exit %s (%d,%d) on map %s leads no where.\n",
615 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path); 604 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
616 } 605 }
617} 606}
618 607
619
620/* The player is trying to enter a randomly generated template map. In this 608/* The player is trying to enter a randomly generated template map. In this
621 * case, generate the map as needed. 609 * case, generate the map as needed.
622 */ 610 */
623 611
624static void 612static void
625enter_random_template_map (object * pl, object * exit_ob) 613enter_random_template_map (object *pl, object *exit_ob)
626{ 614{
627 mapstruct *new_map; 615 maptile *new_map;
628 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF]; 616 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF];
629 const char *new_map_name; 617 const char *new_map_name;
630 RMParms rp; 618 RMParms rp;
631 619
632 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 620 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord
679 * the exit leading to it, that the exit will no longer work. 667 * the exit leading to it, that the exit will no longer work.
680 */ 668 */
681 if (new_map) 669 if (new_map)
682 { 670 {
683 int x, y; 671 int x, y;
672
684 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map); 673 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map);
685 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map); 674 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map);
686 new_map->templatemap = 1; 675 new_map->templatemap = 1;
687 enter_map (pl, new_map, x, y); 676 enter_map (pl, new_map, x, y);
688 } 677 }
690 679
691 680
692/* Code to enter/detect a character entering a unique map. 681/* Code to enter/detect a character entering a unique map.
693 */ 682 */
694static void 683static void
695enter_unique_map (object * op, object * exit_ob) 684enter_unique_map (object *op, object *exit_ob)
696{ 685{
697 char apartment[HUGE_BUF]; 686 char apartment[HUGE_BUF];
698 mapstruct *newmap; 687 maptile *newmap;
699 688
700 if (EXIT_PATH (exit_ob)[0] == '/') 689 if (EXIT_PATH (exit_ob)[0] == '/')
701 { 690 {
702 sprintf (apartment, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, clean_path (EXIT_PATH (exit_ob))); 691 sprintf (apartment, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, clean_path (EXIT_PATH (exit_ob)));
703 newmap = ready_map_name (apartment, MAP_PLAYER_UNIQUE); 692 newmap = ready_map_name (apartment, MAP_PLAYER_UNIQUE);
780 * Largely redone by MSW 2001-01-21 - this function was overly complex 769 * Largely redone by MSW 2001-01-21 - this function was overly complex
781 * and had some obscure bugs. 770 * and had some obscure bugs.
782 */ 771 */
783 772
784void 773void
785enter_exit (object * op, object * exit_ob) 774enter_exit (object *op, object *exit_ob)
786{ 775{
787#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */ 776#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */
788 object *tmp; 777 object *tmp;
778
789 /* It may be nice to support other creatures moving across 779 /* It may be nice to support other creatures moving across
790 * exits, but right now a lot of the code looks at op->contr, 780 * exits, but right now a lot of the code looks at op->contr,
791 * so thta is an RFE. 781 * so that is an RFE.
792 */ 782 */
793 if (op->type != PLAYER) 783 if (op->type != PLAYER)
794 return; 784 return;
795 785
796 /* First, lets figure out what map the player is going to go to */ 786 /* First, lets figure out what map the player is going to go to */
797 if (exit_ob) 787 if (exit_ob)
798 { 788 {
799
800 /* check to see if we make a template map */ 789 /* check to see if we make a template map */
801 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@') 790 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@')
802 { 791 {
803 if (EXIT_PATH (exit_ob)[2] == '!') 792 if (EXIT_PATH (exit_ob)[2] == '!')
804 { 793 {
821 enter_unique_map (op, exit_ob); 810 enter_unique_map (op, exit_ob);
822 } 811 }
823 else 812 else
824 { 813 {
825 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob); 814 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob);
815
826 /* 'Normal' exits that do not do anything special 816 /* 'Normal' exits that do not do anything special
827 * Simple enough we don't need another routine for it. 817 * Simple enough we don't need another routine for it.
828 */ 818 */
829 mapstruct *newmap; 819 maptile *newmap;
820
830 if (exit_ob->map) 821 if (exit_ob->map)
831 { 822 {
832 newmap = ready_map_name (path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)), 0); 823 newmap = ready_map_name (path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)), 0);
833 /* Random map was previously generated, but is no longer about. Lets generate a new 824 /* Random map was previously generated, but is no longer about. Lets generate a new
834 * map. 825 * map.
901 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME)) 892 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME))
902 break; 893 break;
903 } 894 }
904 if (tmp) 895 if (tmp)
905 { 896 {
906 remove_ob (tmp); 897 tmp->remove ();
907 free_object (tmp); 898 tmp->destroy (0);
908 } 899 }
909 900
910 strcpy (op->contr->savebed_map, path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob))); 901 strcpy (op->contr->savebed_map, path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)));
911 op->contr->bed_x = EXIT_X (exit_ob), op->contr->bed_y = EXIT_Y (exit_ob); 902 op->contr->bed_x = EXIT_X (exit_ob), op->contr->bed_y = EXIT_Y (exit_ob);
912 save_player (op, 1); 903 save_player (op, 1);
922 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1); 913 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
923 } 914 }
924 else 915 else
925 { 916 {
926 int flags = 0; 917 int flags = 0;
927 mapstruct *newmap; 918 maptile *newmap;
928
929 919
930 /* Hypothetically, I guess its possible that a standard map matches 920 /* Hypothetically, I guess its possible that a standard map matches
931 * the localdir, but that seems pretty unlikely - unlikely enough that 921 * the localdir, but that seems pretty unlikely - unlikely enough that
932 * I'm not going to attempt to try to deal with that possibility. 922 * I'm not going to attempt to try to deal with that possibility.
933 * We use the fact that when a player saves on a unique map, it prepends 923 * We use the fact that when a player saves on a unique map, it prepends
954 { 944 {
955 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n"); 945 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n");
956 abort (); 946 abort ();
957 } 947 }
958 } 948 }
949
959 enter_map (op, newmap, op->x, op->y); 950 enter_map (op, newmap, op->x, op->y);
960 } 951 }
961} 952}
962 953
963/* 954/*
968 959
969#if 0 // dead code, schmorp 960#if 0 // dead code, schmorp
970void 961void
971process_active_maps () 962process_active_maps ()
972{ 963{
973 for (mapstruct * map = first_map; map != NULL; map = map->next) 964 for (maptile *map = first_map; map != NULL; map = map->next)
974 if (map->in_memory == MAP_IN_MEMORY) 965 if (map->in_memory == MAP_IN_MEMORY)
975 if (players_on_map (map, TRUE)) 966 if (players_on_map (map, TRUE))
976 process_events (map); 967 process_events (map);
977} 968}
978#endif 969#endif
984 * objects have been updated, process_players2() does the processing that 975 * objects have been updated, process_players2() does the processing that
985 * is needed after the players have been updated. 976 * is needed after the players have been updated.
986 */ 977 */
987 978
988void 979void
989process_players1 (mapstruct * map) 980process_players1 (maptile *map)
990{ 981{
991 int flag; 982 int flag;
992 player *pl, *plnext; 983 player *pl, *plnext;
993 984
994 /* Basically, we keep looping until all the players have done their actions. */ 985 /* Basically, we keep looping until all the players have done their actions. */
1056 { 1047 {
1057 pl->ob->start_holding = 0; 1048 pl->ob->start_holding = 0;
1058 } 1049 }
1059 } 1050 }
1060 do_some_living (pl->ob); 1051 do_some_living (pl->ob);
1061 /* draw(pl->ob);*//* updated in socket code */ 1052 /* draw(pl->ob); *//* updated in socket code */
1062 } 1053 }
1063} 1054}
1064 1055
1065void 1056void
1066process_players2 (mapstruct * map) 1057process_players2 (maptile *map)
1067{ 1058{
1068 player *pl; 1059 player *pl;
1069 1060
1070 /* Then check if any players should use weapon-speed instead of speed */ 1061 /* Then check if any players should use weapon-speed instead of speed */
1071 for (pl = first_player; pl != NULL; pl = pl->next) 1062 for (pl = first_player; pl != NULL; pl = pl->next)
1101 pl->ob->speed_left = pl->ob->speed; 1092 pl->ob->speed_left = pl->ob->speed;
1102 } 1093 }
1103} 1094}
1104 1095
1105void 1096void
1106process_events (mapstruct * map) 1097process_events (maptile *map)
1107{ 1098{
1108 object *op; 1099 object *op;
1100
1101 static object *marker;
1102 if (!marker)
1109 object *marker = get_object (); 1103 marker = get_object ();
1110 tag_t tag;
1111 1104
1112 process_players1 (map); 1105 process_players1 (map);
1113 1106
1114 marker->active_next = active_objects; 1107 marker->active_next = active_objects;
1115 1108
1120 active_objects = marker; 1113 active_objects = marker;
1121 1114
1122 while (marker->active_next) 1115 while (marker->active_next)
1123 { 1116 {
1124 op = marker->active_next; 1117 op = marker->active_next;
1125 tag = op->count;
1126 1118
1127 /* Move marker forward - swap op and marker */ 1119 /* Move marker forward - swap op and marker */
1128 op->active_prev = marker->active_prev; 1120 op->active_prev = marker->active_prev;
1129 1121
1130 if (op->active_prev) 1122 if (op->active_prev)
1160 * around. 1152 * around.
1161 */ 1153 */
1162 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY) 1154 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY)
1163 { 1155 {
1164 LOG (llevError, "BUG: process_events(): Removed object on list\n"); 1156 LOG (llevError, "BUG: process_events(): Removed object on list\n");
1165 dump_object (op); 1157 char *dump = dump_object (op);
1166 LOG (llevError, errmsg); 1158 LOG (llevError, dump);
1167 free_object (op); 1159 free (dump);
1160 op->destroy (0);
1168 continue; 1161 continue;
1169 } 1162 }
1170 1163
1171 if (!op->speed) 1164 if (!op->speed)
1172 { 1165 {
1217 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null"); 1210 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null");
1218 } 1211 }
1219#endif 1212#endif
1220 --op->speed_left; 1213 --op->speed_left;
1221 process_object (op); 1214 process_object (op);
1215
1222 if (was_destroyed (op, tag)) 1216 if (op->destroyed ())
1223 continue; 1217 continue;
1224 } 1218 }
1219
1225 if (settings.casting_time == TRUE && op->casting_time > 0) 1220 if (settings.casting_time == TRUE && op->casting_time > 0)
1226 op->casting_time--; 1221 op->casting_time--;
1222
1227 if (op->speed_left <= 0) 1223 if (op->speed_left <= 0)
1228 op->speed_left += FABS (op->speed); 1224 op->speed_left += FABS (op->speed);
1229 } 1225 }
1230 1226
1231 /* Remove marker object from active list */ 1227 /* Remove marker object from active list */
1233 marker->active_prev->active_next = NULL; 1229 marker->active_prev->active_next = NULL;
1234 else 1230 else
1235 active_objects = NULL; 1231 active_objects = NULL;
1236 1232
1237 process_players2 (map); 1233 process_players2 (map);
1238
1239 free_object (marker);
1240} 1234}
1241 1235
1242void 1236void
1243clean_tmp_files (void) 1237clean_tmp_files (void)
1244{ 1238{
1245 mapstruct *m, *next; 1239 maptile *m, *next;
1246 1240
1247 LOG (llevInfo, "Cleaning up...\n"); 1241 LOG (llevInfo, "Cleaning up...\n");
1248 1242
1249 /* We save the maps - it may not be intuitive why, but if there are unique 1243 /* We save the maps - it may not be intuitive why, but if there are unique
1250 * items, we need to save the map so they get saved off. Perhaps we should 1244 * items, we need to save the map so they get saved off. Perhaps we should
1277 1271
1278/* clean up everything before exiting */ 1272/* clean up everything before exiting */
1279void 1273void
1280cleanup (void) 1274cleanup (void)
1281{ 1275{
1282 LOG (llevDebug, "Cleanup called. freeing data.\n"); 1276 LOG (llevDebug, "Cleanup called.\n");
1277
1278 for (player *pl = first_player; pl != NULL; pl = pl->next)
1279 save_player (pl->ob, 0);
1280
1281 for (player *pl = first_player; pl != NULL; pl = pl->next)
1282 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1283 leave_map (pl->ob);
1284
1283 clean_tmp_files (); 1285 clean_tmp_files ();
1284 write_book_archive (); 1286 write_book_archive ();
1285#ifdef MEMORY_DEBUG 1287
1286 free_all_maps (); 1288 INVOKE_GLOBAL (CLEANUP);
1287 free_style_maps (); 1289
1288 free_all_object_data ();
1289 free_all_archs ();
1290 free_all_treasures ();
1291 free_all_images ();
1292 free_all_newserver ();
1293 free_all_recipes ();
1294 free_all_readable ();
1295 free_all_god ();
1296 free_all_anim ();
1297 /* See what the string data that is out there that hasn't been freed. */
1298/* LOG(llevDebug, ss_dump_table(0xff));*/
1299#endif
1300 exit (0); 1290 _exit (0);
1301} 1291}
1302 1292
1303void 1293void
1304leave (player * pl, int draw_exit) 1294leave (player *pl, int draw_exit)
1305{ 1295{
1306 if (pl != NULL) 1296 if (pl != NULL)
1307 { 1297 {
1308 /* We do this so that the socket handling routine can do the final 1298 /* We do this so that the socket handling routine can do the final
1309 * cleanup. We also leave that loop to actually handle the freeing 1299 * cleanup. We also leave that loop to actually handle the freeing
1324 INVOKE_PLAYER (LOGOUT, pl); 1314 INVOKE_PLAYER (LOGOUT, pl);
1325 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket.host); 1315 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket.host);
1326 } 1316 }
1327 1317
1328 char buf[MAX_BUF]; 1318 char buf[MAX_BUF];
1319
1329 sprintf (buf, "%s left the game.", &pl->ob->name); 1320 sprintf (buf, "%s left the game.", &pl->ob->name);
1330 new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, buf); 1321 new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, buf);
1331 } 1322 }
1332 1323
1333 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED)) 1324 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1423 flush_old_maps (); /* Clears the tmp-files of maps which have reset */ 1414 flush_old_maps (); /* Clears the tmp-files of maps which have reset */
1424 1415
1425 if (!(pticks % 2503)) 1416 if (!(pticks % 2503))
1426 fix_weight (); /* Hack to fix weightproblems caused by bugs */ 1417 fix_weight (); /* Hack to fix weightproblems caused by bugs */
1427 1418
1428 if (!(pticks % 2521))
1429 metaserver_update (); /* 2500 ticks is about 5 minutes */
1430
1431 if (!(pticks % 5003)) 1419 if (!(pticks % 5003))
1432 write_book_archive (); 1420 write_book_archive ();
1433 1421
1434 if (!(pticks % 5009)) 1422 if (!(pticks % 5009))
1435 clean_friendly_list (); 1423 clean_friendly_list ();
1461main (int argc, char **argv) 1449main (int argc, char **argv)
1462{ 1450{
1463 settings.argc = argc; 1451 settings.argc = argc;
1464 settings.argv = argv; 1452 settings.argv = argv;
1465 1453
1466 cfperl_init ();
1467
1468 init (argc, argv); 1454 init (argc, argv);
1469 1455
1470 initPlugins (); 1456 initPlugins ();
1471 1457
1472 for (;;) 1458 for (;;)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines