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.45 by root, Thu Dec 14 21:46:34 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 = object::create ();
205 200
206 EXIT_PATH (tmp) = op->contr->savebed_map; 201 EXIT_PATH (tmp) = op->contr->savebed_map;
207 EXIT_X (tmp) = op->contr->bed_x; 202 EXIT_X (tmp) = op->contr->bed_x;
208 EXIT_Y (tmp) = op->contr->bed_y; 203 EXIT_Y (tmp) = op->contr->bed_y;
209 enter_exit (op, tmp); 204 enter_exit (op, tmp);
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
223 tmp->destroy ();
228} 224}
229 225
230/* All this really is is a glorified remove_object that also updates 226/* All this really is is a glorified remove_object that also updates
231 * the counts on the map if needed. 227 * the counts on the map if needed.
232 */ 228 */
233void 229void
234leave_map (object * op) 230leave_map (object *op)
235{ 231{
236 mapstruct *oldmap = op->map; 232 maptile *oldmap = op->map;
237 233
238 remove_ob (op); 234 op->remove ();
239 235
240 if (oldmap) 236 if (oldmap)
241 { 237 {
242 if (!op->contr->hidden) 238 if (!op->contr->hidden)
243 oldmap->players--; 239 oldmap->players--;
240
244 if (oldmap->players <= 0) 241 if (oldmap->players <= 0)
245 { /* can be less than zero due to errors in tracking this */ 242 /* can be less than zero due to errors in tracking this */
246 set_map_timeout (oldmap); 243 set_map_timeout (oldmap);
247 }
248 } 244 }
249} 245}
250 246
251/* 247/*
252 * enter_map(): Moves the player and pets from current map (if any) to 248 * 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 250 * 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 251 * whatever reason. If default map coordinates are to be used, then
256 * the function that calls this should figure them out. 252 * the function that calls this should figure them out.
257 */ 253 */
258static void 254static void
259enter_map (object * op, mapstruct * newmap, int x, int y) 255enter_map (object *op, maptile *newmap, int x, int y)
260{ 256{
261 mapstruct *oldmap = op->map; 257 maptile *oldmap = op->map;
262 258
263 if (out_of_map (newmap, x, y)) 259 if (out_of_map (newmap, x, y))
264 { 260 {
265 LOG (llevError, "enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->path, x, y); 261 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); 262 x = MAP_ENTER_X (newmap);
271 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap)); 267 newmap->path, x, y, MAP_WIDTH (newmap), MAP_HEIGHT (newmap));
272 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed"); 268 new_draw_info (NDI_UNIQUE, 0, op, "The exit is closed");
273 return; 269 return;
274 } 270 }
275 } 271 }
272
276 /* try to find a spot for the player */ 273 /* try to find a spot for the player */
277 if (ob_blocked (op, newmap, x, y)) 274 if (ob_blocked (op, newmap, x, y))
278 { /* First choice blocked */ 275 { /* First choice blocked */
279 /* We try to find a spot for the player, starting closest in. 276 /* 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, 277 * We could use find_first_free_spot, but that doesn't randomize it at all,
282 * if other spaces around are available. 279 * if other spaces around are available.
283 * Note that for the second and third calls, we could start at a position other 280 * 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. 281 * than one, but then we could end up on the other side of walls and so forth.
285 */ 282 */
286 int i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE1 + 1); 283 int i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE1 + 1);
284
287 if (i == -1) 285 if (i == -1)
288 { 286 {
289 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1); 287 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE2 + 1);
290 if (i == -1) 288 if (i == -1)
291 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE); 289 i = find_free_spot (op, newmap, x, y, 1, SIZEOFFREE);
292 } 290 }
291
293 if (i != -1) 292 if (i != -1)
294 { 293 {
295 x += freearr_x[i]; 294 x += freearr_x[i];
296 y += freearr_y[i]; 295 y += freearr_y[i];
297 } 296 }
300 /* not much we can do in this case. */ 299 /* 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); 300 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 } 301 }
303 } /* end if looking for free spot */ 302 } /* end if looking for free spot */
304 303
305 if (op->map != NULL) 304 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)); 305 if (INVOKE_MAP (LEAVE, op->map, ARG_PLAYER (op->contr)))
309 } 306 return;
307
308 if (INVOKE_PLAYER (MAP_CHANGE, op->contr, ARG_MAP (newmap), ARG_INT (x), ARG_INT (y)))
309 return;
310
311 if (INVOKE_MAP (ENTER, newmap, ARG_PLAYER (op->contr), ARG_INT (x), ARG_INT (y)))
312 return;
310 313
311 /* If it is a player login, he has yet to be inserted anyplace. 314 /* If it is a player login, he has yet to be inserted anyplace.
312 * otherwise, we need to deal with removing the player here. 315 * otherwise, we need to deal with removing the player here.
313 */ 316 */
314 if (!QUERY_FLAG (op, FLAG_REMOVED)) 317 op->remove ();
315 remove_ob (op);
316 318
317 /* remove_ob clears these so they must be reset after the remove_ob call */ 319 /* remove_ob clears these so they must be reset after the remove_ob call */
318 op->x = x; 320 op->x = x;
319 op->y = y; 321 op->y = y;
320 op->map = newmap; 322 op->map = newmap;
323
321 insert_ob_in_map (op, op->map, NULL, INS_NO_WALK_ON); 324 insert_ob_in_map (op, op->map, NULL, INS_NO_WALK_ON);
322
323 INVOKE_MAP (ENTER, op->map, ARG_PLAYER (op->contr));
324 325
325 if (!op->contr->hidden) 326 if (!op->contr->hidden)
326 newmap->players++; 327 newmap->players++;
327 328
328 newmap->timeout = 0; 329 newmap->timeout = 0;
337 /* Update any golems */ 338 /* Update any golems */
338 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL) 339 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL)
339 { 340 {
340 int i = find_free_spot (op->contr->ranges[range_golem], newmap, 341 int i = find_free_spot (op->contr->ranges[range_golem], newmap,
341 x, y, 1, SIZEOFFREE); 342 x, y, 1, SIZEOFFREE);
343
342 remove_ob (op->contr->ranges[range_golem]); 344 op->contr->ranges[range_golem]->remove ();
345
343 if (i == -1) 346 if (i == -1)
344 { 347 {
345 remove_friendly_object (op->contr->ranges[range_golem]); 348 remove_friendly_object (op->contr->ranges[range_golem]);
346 free_object (op->contr->ranges[range_golem]); 349 op->contr->ranges[range_golem]->destroy ();
347 op->contr->ranges[range_golem] = NULL; 350 op->contr->ranges[range_golem] = 0;
348 op->contr->golem_count = 0;
349 } 351 }
350 else 352 else
351 { 353 {
352 object *tmp;
353 for (tmp = op->contr->ranges[range_golem]; tmp != NULL; tmp = tmp->more) 354 for (object *tmp = op->contr->ranges[range_golem]; tmp != NULL; tmp = tmp->more)
354 { 355 {
355 tmp->x = x + freearr_x[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x); 356 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); 357 tmp->y = y + freearr_y[i] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y);
357 tmp->map = newmap; 358 tmp->map = newmap;
358 } 359 }
360
359 insert_ob_in_map (op->contr->ranges[range_golem], newmap, NULL, 0); 361 insert_ob_in_map (op->contr->ranges[range_golem], newmap, NULL, 0);
360 op->contr->ranges[range_golem]->direction = 362 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); 363 find_dir_2 (op->x - op->contr->ranges[range_golem]->x, op->y - op->contr->ranges[range_golem]->y);
362 } 364 }
363 } 365 }
366
364 op->direction = 0; 367 op->direction = 0;
365 368
366 /* since the players map is already loaded, we don't need to worry 369 /* since the players map is already loaded, we don't need to worry
367 * about pending objects. 370 * about pending objects.
368 */ 371 */
383 } 386 }
384 } 387 }
385} 388}
386 389
387void 390void
388set_map_timeout (mapstruct * oldmap) 391set_map_timeout (maptile *oldmap)
389{ 392{
390#if MAP_MAXTIMEOUT 393#if MAP_MAXTIMEOUT
391 oldmap->timeout = MAP_TIMEOUT (oldmap); 394 oldmap->timeout = MAP_TIMEOUT (oldmap);
392 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is 395 /* Do MINTIMEOUT first, so that MAXTIMEOUT is used if that is
393 * lower than the min value. 396 * lower than the min value.
394 */ 397 */
395#if MAP_MINTIMEOUT 398# if MAP_MINTIMEOUT
396 if (oldmap->timeout < MAP_MINTIMEOUT) 399 if (oldmap->timeout < MAP_MINTIMEOUT)
397 {
398 oldmap->timeout = MAP_MINTIMEOUT; 400 oldmap->timeout = MAP_MINTIMEOUT;
399 }
400#endif 401# endif
402
401 if (oldmap->timeout > MAP_MAXTIMEOUT) 403 if (oldmap->timeout > MAP_MAXTIMEOUT)
402 {
403 oldmap->timeout = MAP_MAXTIMEOUT; 404 oldmap->timeout = MAP_MAXTIMEOUT;
404 } 405
405#else 406#else
406 /* save out the map */ 407 /* save out the map */
407 swap_map (oldmap); 408 swap_map (oldmap);
408#endif /* MAP_MAXTIMEOUT */ 409#endif /* MAP_MAXTIMEOUT */
409} 410}
414 */ 415 */
415char * 416char *
416clean_path (const char *file) 417clean_path (const char *file)
417{ 418{
418 static char newpath[MAX_BUF], *cp; 419 static char newpath[MAX_BUF], *cp;
420 assign (newpath, file);
419 421
420 strncpy (newpath, file, MAX_BUF - 1);
421 newpath[MAX_BUF - 1] = '\0';
422 for (cp = newpath; *cp != '\0'; cp++) 422 for (cp = newpath; *cp != '\0'; cp++)
423 {
424 if (*cp == '/') 423 if (*cp == '/')
425 *cp = '_'; 424 *cp = '_';
426 } 425
427 return newpath; 426 return newpath;
428} 427}
429 428
430 429
431/* unclean_path takes a path and replaces all _ with / 430/* unclean_path takes a path and replaces all _ with /
439unclean_path (const char *src) 438unclean_path (const char *src)
440{ 439{
441 static char newpath[MAX_BUF], *cp; 440 static char newpath[MAX_BUF], *cp;
442 441
443 cp = strrchr (src, '/'); 442 cp = strrchr (src, '/');
444 if (cp) 443 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 444
450 for (cp = newpath; *cp != '\0'; cp++) 445 for (cp = newpath; *cp != '\0'; cp++)
451 {
452 if (*cp == '_') 446 if (*cp == '_')
453 *cp = '/'; 447 *cp = '/';
454 } 448
455 return newpath; 449 return newpath;
456} 450}
457 451
458 452
459/* The player is trying to enter a randomly generated map. In this case, generate the 453/* The player is trying to enter a randomly generated map. In this case, generate the
460 * random map as needed. 454 * random map as needed.
461 */ 455 */
462 456
463static void 457static void
464enter_random_map (object * pl, object * exit_ob) 458enter_random_map (object *pl, object *exit_ob)
465{ 459{
466 mapstruct *new_map; 460 maptile *new_map;
467 char newmap_name[HUGE_BUF], *cp; 461 char newmap_name[HUGE_BUF], *cp;
468 static int reference_number = 0; 462 static int reference_number = 0;
469 RMParms rp; 463 RMParms rp;
470 464
471 memset (&rp, 0, sizeof (RMParms)); 465 memset (&rp, 0, sizeof (RMParms));
515 * the exit leading to it, that the exit will no longer work. 509 * the exit leading to it, that the exit will no longer work.
516 */ 510 */
517 if (new_map) 511 if (new_map)
518 { 512 {
519 int x, y; 513 int x, y;
514
520 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map); 515 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map);
521 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map); 516 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map);
522 EXIT_PATH (exit_ob) = newmap_name; 517 EXIT_PATH (exit_ob) = newmap_name;
523 strcpy (new_map->path, newmap_name); 518 strcpy (new_map->path, newmap_name);
524 enter_map (pl, new_map, x, y); 519 enter_map (pl, new_map, x, y);
528/* The player is trying to enter a non-randomly generated template map. In this 523/* The player is trying to enter a non-randomly generated template map. In this
529 * case, use a map file for a template 524 * case, use a map file for a template
530 */ 525 */
531 526
532static void 527static void
533enter_fixed_template_map (object * pl, object * exit_ob) 528enter_fixed_template_map (object *pl, object *exit_ob)
534{ 529{
535 mapstruct *new_map; 530 maptile *new_map;
536 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap; 531 char tmpnum[32], exitpath[HUGE_BUF], resultname[HUGE_BUF], tmpstring[HUGE_BUF], *sourcemap;
537 const char *new_map_name; 532 const char *new_map_name;
538 533
539 /* Split the exit path string into two parts, one 534 /* Split the exit path string into two parts, one
540 * for where to store the map, and one for were 535 * for where to store the map, and one for were
549 */ 544 */
550 LOG (llevError, "enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n", 545 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); 546 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
552 return; 547 return;
553 } 548 }
549
554 *sourcemap++ = '\0'; 550 *sourcemap++ = '\0';
555 551
556 /* If we are not coming from a template map, we can use relative directories 552 /* If we are not coming from a template map, we can use relative directories
557 * for the map to generate from. 553 * for the map to generate from.
558 */ 554 */
559 if (!exit_ob->map->templatemap) 555 if (!exit_ob->map->templatemap)
560 {
561 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap); 556 sourcemap = path_combine_and_normalize (exit_ob->map->path, sourcemap);
562 }
563 557
564 /* 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
565 * of the exit, and the name of the map the exit is on, respectively. 559 * of the exit, and the name of the map the exit is on, respectively.
566 */ 560 */
567 sprintf (tmpnum, "%d", exit_ob->x); 561 sprintf (tmpnum, "%d", exit_ob->x);
576 570
577 /* 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
578 * indicated otherwise. 572 * indicated otherwise.
579 */ 573 */
580 if (exit_ob->map->templatemap && (resultname[0] != '/')) 574 if (exit_ob->map->templatemap && (resultname[0] != '/'))
581 {
582 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);
583 }
584 else 576 else
585 {
586 new_map_name = create_template_pathname (resultname); 577 new_map_name = create_template_pathname (resultname);
587 }
588 578
589 /* Attempt to load the map, if unable to, then 579 /* Attempt to load the map, if unable to, then
590 * create the map from the template. 580 * create the map from the template.
591 */ 581 */
592 new_map = ready_map_name (new_map_name, MAP_PLAYER_UNIQUE); 582 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", 604 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); 605 &exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
616 } 606 }
617} 607}
618 608
619
620/* The player is trying to enter a randomly generated template map. In this 609/* The player is trying to enter a randomly generated template map. In this
621 * case, generate the map as needed. 610 * case, generate the map as needed.
622 */ 611 */
623 612
624static void 613static void
625enter_random_template_map (object * pl, object * exit_ob) 614enter_random_template_map (object *pl, object *exit_ob)
626{ 615{
627 mapstruct *new_map; 616 maptile *new_map;
628 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF]; 617 char tmpnum[32], resultname[HUGE_BUF], tmpstring[HUGE_BUF];
629 const char *new_map_name; 618 const char *new_map_name;
630 RMParms rp; 619 RMParms rp;
631 620
632 /* Do replacement of %x, %y, and %n to the x coord of the exit, the y coord 621 /* 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. 668 * the exit leading to it, that the exit will no longer work.
680 */ 669 */
681 if (new_map) 670 if (new_map)
682 { 671 {
683 int x, y; 672 int x, y;
673
684 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map); 674 x = EXIT_X (exit_ob) = MAP_ENTER_X (new_map);
685 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map); 675 y = EXIT_Y (exit_ob) = MAP_ENTER_Y (new_map);
686 new_map->templatemap = 1; 676 new_map->templatemap = 1;
687 enter_map (pl, new_map, x, y); 677 enter_map (pl, new_map, x, y);
688 } 678 }
690 680
691 681
692/* Code to enter/detect a character entering a unique map. 682/* Code to enter/detect a character entering a unique map.
693 */ 683 */
694static void 684static void
695enter_unique_map (object * op, object * exit_ob) 685enter_unique_map (object *op, object *exit_ob)
696{ 686{
697 char apartment[HUGE_BUF]; 687 char apartment[HUGE_BUF];
698 mapstruct *newmap; 688 maptile *newmap;
699 689
700 if (EXIT_PATH (exit_ob)[0] == '/') 690 if (EXIT_PATH (exit_ob)[0] == '/')
701 { 691 {
702 sprintf (apartment, "%s/%s/%s/%s", settings.localdir, settings.playerdir, &op->name, clean_path (EXIT_PATH (exit_ob))); 692 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); 693 newmap = ready_map_name (apartment, MAP_PLAYER_UNIQUE);
780 * Largely redone by MSW 2001-01-21 - this function was overly complex 770 * Largely redone by MSW 2001-01-21 - this function was overly complex
781 * and had some obscure bugs. 771 * and had some obscure bugs.
782 */ 772 */
783 773
784void 774void
785enter_exit (object * op, object * exit_ob) 775enter_exit (object *op, object *exit_ob)
786{ 776{
787#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */ 777#define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */
788 object *tmp; 778 object *tmp;
779
789 /* It may be nice to support other creatures moving across 780 /* It may be nice to support other creatures moving across
790 * exits, but right now a lot of the code looks at op->contr, 781 * exits, but right now a lot of the code looks at op->contr,
791 * so thta is an RFE. 782 * so that is an RFE.
792 */ 783 */
793 if (op->type != PLAYER) 784 if (op->type != PLAYER)
794 return; 785 return;
795 786
796 /* First, lets figure out what map the player is going to go to */ 787 /* First, lets figure out what map the player is going to go to */
797 if (exit_ob) 788 if (exit_ob)
798 { 789 {
799
800 /* check to see if we make a template map */ 790 /* check to see if we make a template map */
801 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@') 791 if (EXIT_PATH (exit_ob) && EXIT_PATH (exit_ob)[1] == '@')
802 { 792 {
803 if (EXIT_PATH (exit_ob)[2] == '!') 793 if (EXIT_PATH (exit_ob)[2] == '!')
804 { 794 {
821 enter_unique_map (op, exit_ob); 811 enter_unique_map (op, exit_ob);
822 } 812 }
823 else 813 else
824 { 814 {
825 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob); 815 int x = EXIT_X (exit_ob), y = EXIT_Y (exit_ob);
816
826 /* 'Normal' exits that do not do anything special 817 /* 'Normal' exits that do not do anything special
827 * Simple enough we don't need another routine for it. 818 * Simple enough we don't need another routine for it.
828 */ 819 */
829 mapstruct *newmap; 820 maptile *newmap;
821
830 if (exit_ob->map) 822 if (exit_ob->map)
831 { 823 {
832 newmap = ready_map_name (path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob)), 0); 824 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 825 /* Random map was previously generated, but is no longer about. Lets generate a new
834 * map. 826 * map.
901 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME)) 893 if (tmp->type == FORCE && tmp->slaying && !strcmp (tmp->slaying, PORTAL_DESTINATION_NAME))
902 break; 894 break;
903 } 895 }
904 if (tmp) 896 if (tmp)
905 { 897 {
906 remove_ob (tmp); 898 tmp->remove ();
907 free_object (tmp); 899 tmp->destroy ();
908 } 900 }
909 901
910 strcpy (op->contr->savebed_map, path_combine_and_normalize (exit_ob->map->path, EXIT_PATH (exit_ob))); 902 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); 903 op->contr->bed_x = EXIT_X (exit_ob), op->contr->bed_y = EXIT_Y (exit_ob);
912 save_player (op, 1); 904 save_player (op, 1);
922 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1); 914 hit_player (op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
923 } 915 }
924 else 916 else
925 { 917 {
926 int flags = 0; 918 int flags = 0;
927 mapstruct *newmap; 919 maptile *newmap;
928
929 920
930 /* Hypothetically, I guess its possible that a standard map matches 921 /* Hypothetically, I guess its possible that a standard map matches
931 * the localdir, but that seems pretty unlikely - unlikely enough that 922 * the localdir, but that seems pretty unlikely - unlikely enough that
932 * I'm not going to attempt to try to deal with that possibility. 923 * 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 924 * We use the fact that when a player saves on a unique map, it prepends
954 { 945 {
955 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n"); 946 LOG (llevError, "enter_exit: could not load emergency map? Fatal error\n");
956 abort (); 947 abort ();
957 } 948 }
958 } 949 }
950
959 enter_map (op, newmap, op->x, op->y); 951 enter_map (op, newmap, op->x, op->y);
960 } 952 }
961} 953}
962 954
963/* 955/*
968 960
969#if 0 // dead code, schmorp 961#if 0 // dead code, schmorp
970void 962void
971process_active_maps () 963process_active_maps ()
972{ 964{
973 for (mapstruct * map = first_map; map != NULL; map = map->next) 965 for (maptile *map = first_map; map != NULL; map = map->next)
974 if (map->in_memory == MAP_IN_MEMORY) 966 if (map->in_memory == MAP_IN_MEMORY)
975 if (players_on_map (map, TRUE)) 967 if (players_on_map (map, TRUE))
976 process_events (map); 968 process_events (map);
977} 969}
978#endif 970#endif
984 * objects have been updated, process_players2() does the processing that 976 * objects have been updated, process_players2() does the processing that
985 * is needed after the players have been updated. 977 * is needed after the players have been updated.
986 */ 978 */
987 979
988void 980void
989process_players1 (mapstruct * map) 981process_players1 (maptile *map)
990{ 982{
991 int flag; 983 int flag;
992 player *pl, *plnext; 984 player *pl, *plnext;
993 985
994 /* Basically, we keep looping until all the players have done their actions. */ 986 /* Basically, we keep looping until all the players have done their actions. */
1056 { 1048 {
1057 pl->ob->start_holding = 0; 1049 pl->ob->start_holding = 0;
1058 } 1050 }
1059 } 1051 }
1060 do_some_living (pl->ob); 1052 do_some_living (pl->ob);
1061 /* draw(pl->ob);*//* updated in socket code */ 1053 /* draw(pl->ob); *//* updated in socket code */
1062 } 1054 }
1063} 1055}
1064 1056
1065void 1057void
1066process_players2 (mapstruct * map) 1058process_players2 (maptile *map)
1067{ 1059{
1068 player *pl; 1060 player *pl;
1069 1061
1070 /* Then check if any players should use weapon-speed instead of speed */ 1062 /* Then check if any players should use weapon-speed instead of speed */
1071 for (pl = first_player; pl != NULL; pl = pl->next) 1063 for (pl = first_player; pl != NULL; pl = pl->next)
1101 pl->ob->speed_left = pl->ob->speed; 1093 pl->ob->speed_left = pl->ob->speed;
1102 } 1094 }
1103} 1095}
1104 1096
1105void 1097void
1106process_events (mapstruct * map) 1098process_events (maptile *map)
1107{ 1099{
1108 object *op; 1100 object *op;
1109 object *marker = get_object (); 1101
1110 tag_t tag; 1102 static object *marker;
1103
1104 if (!marker)
1105 marker = object::create ();
1111 1106
1112 process_players1 (map); 1107 process_players1 (map);
1113 1108
1114 marker->active_next = active_objects; 1109 marker->active_next = active_objects;
1115 1110
1120 active_objects = marker; 1115 active_objects = marker;
1121 1116
1122 while (marker->active_next) 1117 while (marker->active_next)
1123 { 1118 {
1124 op = marker->active_next; 1119 op = marker->active_next;
1125 tag = op->count;
1126 1120
1127 /* Move marker forward - swap op and marker */ 1121 /* Move marker forward - swap op and marker */
1128 op->active_prev = marker->active_prev; 1122 op->active_prev = marker->active_prev;
1129 1123
1130 if (op->active_prev) 1124 if (op->active_prev)
1160 * around. 1154 * around.
1161 */ 1155 */
1162 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY) 1156 if (QUERY_FLAG (op, FLAG_REMOVED) && op->type != PLAYER && op->map && op->map->in_memory != MAP_IN_MEMORY)
1163 { 1157 {
1164 LOG (llevError, "BUG: process_events(): Removed object on list\n"); 1158 LOG (llevError, "BUG: process_events(): Removed object on list\n");
1165 dump_object (op); 1159 char *dump = dump_object (op);
1166 LOG (llevError, errmsg); 1160 LOG (llevError, dump);
1167 free_object (op); 1161 free (dump);
1162 op->destroy ();
1168 continue; 1163 continue;
1169 } 1164 }
1170 1165
1171 if (!op->speed) 1166 if (!op->speed)
1172 { 1167 {
1217 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null"); 1212 LOG (llevDebug, "process_events: calling process_object with removed object %s\n", op->name ? op->name : "null");
1218 } 1213 }
1219#endif 1214#endif
1220 --op->speed_left; 1215 --op->speed_left;
1221 process_object (op); 1216 process_object (op);
1217
1222 if (was_destroyed (op, tag)) 1218 if (op->destroyed ())
1223 continue; 1219 continue;
1224 } 1220 }
1221
1225 if (settings.casting_time == TRUE && op->casting_time > 0) 1222 if (settings.casting_time == TRUE && op->casting_time > 0)
1226 op->casting_time--; 1223 op->casting_time--;
1224
1227 if (op->speed_left <= 0) 1225 if (op->speed_left <= 0)
1228 op->speed_left += FABS (op->speed); 1226 op->speed_left += FABS (op->speed);
1229 } 1227 }
1230 1228
1231 /* Remove marker object from active list */ 1229 /* Remove marker object from active list */
1233 marker->active_prev->active_next = NULL; 1231 marker->active_prev->active_next = NULL;
1234 else 1232 else
1235 active_objects = NULL; 1233 active_objects = NULL;
1236 1234
1237 process_players2 (map); 1235 process_players2 (map);
1238
1239 free_object (marker);
1240} 1236}
1241 1237
1242void 1238void
1243clean_tmp_files (void) 1239clean_tmp_files (void)
1244{ 1240{
1245 mapstruct *m, *next; 1241 maptile *m, *next;
1246 1242
1247 LOG (llevInfo, "Cleaning up...\n"); 1243 LOG (llevInfo, "Cleaning up...\n");
1248 1244
1249 /* We save the maps - it may not be intuitive why, but if there are unique 1245 /* 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 1246 * items, we need to save the map so they get saved off. Perhaps we should
1277 1273
1278/* clean up everything before exiting */ 1274/* clean up everything before exiting */
1279void 1275void
1280cleanup (void) 1276cleanup (void)
1281{ 1277{
1282 LOG (llevDebug, "Cleanup called. freeing data.\n"); 1278 LOG (llevDebug, "Cleanup called.\n");
1279
1280 for (player *pl = first_player; pl != NULL; pl = pl->next)
1281 save_player (pl->ob, 0);
1282
1283 for (player *pl = first_player; pl != NULL; pl = pl->next)
1284 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1285 leave_map (pl->ob);
1286
1283 clean_tmp_files (); 1287 clean_tmp_files ();
1284 write_book_archive (); 1288 write_book_archive ();
1285#ifdef MEMORY_DEBUG 1289
1286 free_all_maps (); 1290 INVOKE_GLOBAL (CLEANUP);
1287 free_style_maps (); 1291
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); 1292 _exit (0);
1301} 1293}
1302 1294
1303void 1295void
1304leave (player * pl, int draw_exit) 1296leave (player *pl, int draw_exit)
1305{ 1297{
1306 if (pl != NULL) 1298 if (pl != NULL)
1307 { 1299 {
1308 /* We do this so that the socket handling routine can do the final 1300 /* 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 1301 * cleanup. We also leave that loop to actually handle the freeing
1310 * of the data. 1302 * of the data.
1311 */ 1303 */
1312 if (pl->ob->type != DEAD_OBJECT) 1304 if (pl->ob->type != DEAD_OBJECT)
1313 { 1305 {
1314 pl->socket.status = Ns_Dead; 1306 pl->socket->status = Ns_Dead;
1315 1307
1316 /* If a hidden dm dropped connection do not create 1308 /* If a hidden dm dropped connection do not create
1317 * inconsistencies by showing that they have left the game 1309 * inconsistencies by showing that they have left the game
1318 */ 1310 */
1319 if (!(QUERY_FLAG (pl->ob, FLAG_WIZ) && pl->ob->contr->hidden) 1311 if (!(QUERY_FLAG (pl->ob, FLAG_WIZ) && pl->ob->contr->hidden)
1320 && draw_exit && (pl->state != ST_GET_NAME && pl->state != ST_GET_PASSWORD && pl->state != ST_CONFIRM_PASSWORD)) 1312 && draw_exit && (pl->state != ST_GET_NAME && pl->state != ST_GET_PASSWORD && pl->state != ST_CONFIRM_PASSWORD))
1321 { 1313 {
1322 if (pl->ob->map) 1314 if (pl->ob->map)
1323 { 1315 {
1324 INVOKE_PLAYER (LOGOUT, pl); 1316 INVOKE_PLAYER (LOGOUT, pl);
1325 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket.host); 1317 LOG (llevInfo, "LOGOUT: Player named %s from ip %s\n", &pl->ob->name, pl->socket->host);
1326 } 1318 }
1327 1319
1328 char buf[MAX_BUF]; 1320 char buf[MAX_BUF];
1321
1329 sprintf (buf, "%s left the game.", &pl->ob->name); 1322 sprintf (buf, "%s left the game.", &pl->ob->name);
1330 new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, buf); 1323 new_draw_info (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, buf);
1331 } 1324 }
1332 1325
1333 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED)) 1326 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
1405extern unsigned long todtick; 1398extern unsigned long todtick;
1406 1399
1407void 1400void
1408do_specials (void) 1401do_specials (void)
1409{ 1402{
1410
1411#ifdef WATCHDOG
1412 if (!(pticks % 503))
1413 watchdog ();
1414#endif
1415
1416 if (!(pticks % PTICKS_PER_CLOCK)) 1403 if (!(pticks % PTICKS_PER_CLOCK))
1417 tick_the_clock (); 1404 tick_the_clock ();
1418 1405
1419 if (!(pticks % 7)) 1406 if (!(pticks % 7))
1420 shstr::gc (); 1407 shstr::gc ();
1423 flush_old_maps (); /* Clears the tmp-files of maps which have reset */ 1410 flush_old_maps (); /* Clears the tmp-files of maps which have reset */
1424 1411
1425 if (!(pticks % 2503)) 1412 if (!(pticks % 2503))
1426 fix_weight (); /* Hack to fix weightproblems caused by bugs */ 1413 fix_weight (); /* Hack to fix weightproblems caused by bugs */
1427 1414
1428 if (!(pticks % 2521))
1429 metaserver_update (); /* 2500 ticks is about 5 minutes */
1430
1431 if (!(pticks % 5003)) 1415 if (!(pticks % 5003))
1432 write_book_archive (); 1416 write_book_archive ();
1433 1417
1434 if (!(pticks % 5009)) 1418 if (!(pticks % 5009))
1435 clean_friendly_list (); 1419 clean_friendly_list ();
1444void 1428void
1445server_tick () 1429server_tick ()
1446{ 1430{
1447 nroferrors = 0; 1431 nroferrors = 0;
1448 1432
1433 // first do the user visible stuff
1449 doeric_server (); 1434 doeric_server ();
1450 INVOKE_GLOBAL (CLOCK); 1435 INVOKE_GLOBAL (CLOCK);
1451 process_events (NULL); /* "do" something with objects with speed */ 1436 process_events (NULL); /* "do" something with objects with speed */
1452 flush_sockets (); 1437 flush_sockets ();
1438
1439 // then do some bookkeeping, should not really be here
1453 check_active_maps (); /* Removes unused maps after a certain timeout */ 1440 check_active_maps (); /* Removes unused maps after a certain timeout */
1454 do_specials (); /* Routines called from time to time. */ 1441 do_specials (); /* Routines called from time to time. */
1455 object::free_mortals (); 1442 object::free_mortals ();
1456 1443
1457 ++pticks; 1444 ++pticks;
1461main (int argc, char **argv) 1448main (int argc, char **argv)
1462{ 1449{
1463 settings.argc = argc; 1450 settings.argc = argc;
1464 settings.argv = argv; 1451 settings.argv = argv;
1465 1452
1466 cfperl_init ();
1467
1468 init (argc, argv); 1453 init (argc, argv);
1469 1454
1470 initPlugins (); 1455 initPlugins ();
1471 1456
1472 for (;;) 1457 for (;;)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines