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.54 by root, Sat Dec 23 06:21:02 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines