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

Comparing deliantra/server/common/map.C (file contents):
Revision 1.56 by root, Sat Dec 30 10:16:10 2006 UTC vs.
Revision 1.66 by pippijn, Wed Jan 3 00:21:35 2007 UTC

36 * it really should be called create_mapname 36 * it really should be called create_mapname
37 */ 37 */
38const char * 38const char *
39create_pathname (const char *name) 39create_pathname (const char *name)
40{ 40{
41 static char buf[MAX_BUF]; 41 static char buf[8192];
42
43 /* Why? having extra / doesn't confuse unix anyplace? Dependancies
44 * someplace else in the code? msw 2-17-97
45 */
46 if (*name == '/')
47 sprintf (buf, "%s/%s%s", settings.datadir, settings.mapdir, name);
48 else
49 sprintf (buf, "%s/%s/%s", settings.datadir, settings.mapdir, name); 42 snprintf (buf, sizeof (buf), "%s/%s/%s", settings.datadir, settings.mapdir, name);
50 return (buf); 43 return buf;
51}
52
53/*
54 * same as create_pathname, but for the overlay maps.
55 */
56const char *
57create_overlay_pathname (const char *name)
58{
59 static char buf[MAX_BUF];
60
61 /* Why? having extra / doesn't confuse unix anyplace? Dependancies
62 * someplace else in the code? msw 2-17-97
63 */
64 if (*name == '/')
65 sprintf (buf, "%s/%s%s", settings.localdir, settings.mapdir, name);
66 else
67 sprintf (buf, "%s/%s/%s", settings.localdir, settings.mapdir, name);
68 return (buf);
69}
70
71/*
72 * same as create_pathname, but for the template maps.
73 */
74const char *
75create_template_pathname (const char *name)
76{
77 static char buf[MAX_BUF];
78
79 /* Why? having extra / doesn't confuse unix anyplace? Dependancies
80 * someplace else in the code? msw 2-17-97
81 */
82 if (*name == '/')
83 sprintf (buf, "%s/%s%s", settings.localdir, settings.templatedir, name);
84 else
85 sprintf (buf, "%s/%s/%s", settings.localdir, settings.templatedir, name);
86 return (buf);
87}
88
89/*
90 * This makes absolute path to the itemfile where unique objects
91 * will be saved. Converts '/' to '@'. I think it's essier maintain
92 * files than full directory structure, but if this is problem it can
93 * be changed.
94 */
95static const char *
96create_items_path (const char *s)
97{
98 static char buf[MAX_BUF];
99 char *t;
100
101 if (*s == '/')
102 s++;
103
104 sprintf (buf, "%s/%s/", settings.localdir, settings.uniquedir);
105
106 for (t = buf + strlen (buf); *s; s++, t++)
107 if (*s == '/')
108 *t = '@';
109 else
110 *t = *s;
111 *t = 0;
112 return (buf);
113} 44}
114 45
115/* 46/*
116 * This function checks if a file with the given path exists. 47 * This function checks if a file with the given path exists.
117 * -1 is returned if it fails, otherwise the mode of the file 48 * -1 is returned if it fails, otherwise the mode of the file
331 archetype *tmp; 262 archetype *tmp;
332 int flag; 263 int flag;
333 maptile *m1; 264 maptile *m1;
334 sint16 sx, sy; 265 sint16 sx, sy;
335 266
336 if (ob == NULL) 267 if (!ob)
337 { 268 {
338 flag = get_map_flags (m, &m1, x, y, &sx, &sy); 269 flag = get_map_flags (m, &m1, x, y, &sx, &sy);
339 if (flag & P_OUT_OF_MAP) 270 if (flag & P_OUT_OF_MAP)
340 return P_OUT_OF_MAP; 271 return P_OUT_OF_MAP;
341 272
396 327
397 /* sum_weight will go through and calculate what all the containers are 328 /* sum_weight will go through and calculate what all the containers are
398 * carrying. 329 * carrying.
399 */ 330 */
400 sum_weight (container); 331 sum_weight (container);
332}
333
334void
335maptile::set_object_flag (int flag, int value)
336{
337 if (!spaces)
338 return;
339
340 for (mapspace *ms = spaces + size (); ms-- > spaces; )
341 for (object *tmp = ms->bot; tmp; tmp = tmp->above)
342 tmp->flag [flag] = value;
401} 343}
402 344
403/* link_multipart_objects go through all the objects on the map looking 345/* link_multipart_objects go through all the objects on the map looking
404 * for objects whose arch says they are multipart yet according to the 346 * for objects whose arch says they are multipart yet according to the
405 * info we have, they only have the head (as would be expected when 347 * info we have, they only have the head (as would be expected when
528 if (!spaces) 470 if (!spaces)
529 return; 471 return;
530 472
531 for (mapspace *ms = spaces + size (); ms-- > spaces; ) 473 for (mapspace *ms = spaces + size (); ms-- > spaces; )
532 for (object *op = ms->bot; op; op = op->above) 474 for (object *op = ms->bot; op; op = op->above)
533 op->activate (1); 475 op->activate_recursive ();
534} 476}
535 477
536void 478void
537maptile::deactivate () 479maptile::deactivate ()
538{ 480{
539 if (!spaces) 481 if (!spaces)
540 return; 482 return;
541 483
542 for (mapspace *ms = spaces + size (); ms-- > spaces; ) 484 for (mapspace *ms = spaces + size (); ms-- > spaces; )
543 for (object *op = ms->bot; op; op = op->above) 485 for (object *op = ms->bot; op; op = op->above)
544 op->deactivate (1); 486 op->deactivate_recursive ();
545} 487}
546 488
547bool 489bool
548maptile::save_objects (object_freezer &freezer, int flags) 490maptile::save_objects (object_freezer &freezer, int flags)
549{ 491{
492 static int cede_count = 0;
493
550 if (flags & IO_HEADER) 494 if (flags & IO_HEADER)
551 save_header (freezer); 495 save_header (freezer);
552 496
553 if (!spaces) 497 if (!spaces)
554 return false; 498 return false;
555 499
556 for (int i = 0; i < size (); ++i) 500 for (int i = 0; i < size (); ++i)
557 { 501 {
502 if (cede_count >= 500)
503 {
504 cede_count = 0;
505 coroapi::cede ();
506 }
507
558 int unique = 0; 508 int unique = 0;
559 for (object *op = spaces [i].bot; op; op = op->above) 509 for (object *op = spaces [i].bot; op; op = op->above)
560 { 510 {
511 // count per-object, but cede only when modification-safe
512 cede_count++;
513
561 if (op->flag [FLAG_UNIQUE] && op->flag [FLAG_IS_FLOOR]) 514 if (op->flag [FLAG_UNIQUE] && op->flag [FLAG_IS_FLOOR])
562 unique = 1; 515 unique = 1;
563 516
564 if (!op->can_map_save ()) 517 if (!op->can_map_save ())
565 continue; 518 continue;
789 keyword kw = thawer.get_kv (); 742 keyword kw = thawer.get_kv ();
790 743
791 switch (kw) 744 switch (kw)
792 { 745 {
793 case KW_EOF: 746 case KW_EOF:
794 LOG (llevError, "%s: end of file while reading map header, aborting header load.", &path); 747 LOG (llevError, "%s: end of file while reading map header, aborting header load.\n", &path);
795 return false; 748 return false;
796 749
797 case KW_end: 750 case KW_end:
798 return true; 751 return true;
799 752
957 if (tile_path [0]) MAP_OUT2 (tile_path_1, tile_path [0]); 910 if (tile_path [0]) MAP_OUT2 (tile_path_1, tile_path [0]);
958 if (tile_path [1]) MAP_OUT2 (tile_path_2, tile_path [1]); 911 if (tile_path [1]) MAP_OUT2 (tile_path_2, tile_path [1]);
959 if (tile_path [2]) MAP_OUT2 (tile_path_3, tile_path [2]); 912 if (tile_path [2]) MAP_OUT2 (tile_path_3, tile_path [2]);
960 if (tile_path [3]) MAP_OUT2 (tile_path_4, tile_path [3]); 913 if (tile_path [3]) MAP_OUT2 (tile_path_4, tile_path [3]);
961 914
962 MAP_OUT2 (end, 0); 915 freezer.put (this);
916 freezer.put (KW_end);
963 917
964 return true; 918 return true;
965} 919}
966 920
967bool 921bool
1324 faces [0] = top; faces_obj [0] = top != blank_face ? top_obj : 0; 1278 faces [0] = top; faces_obj [0] = top != blank_face ? top_obj : 0;
1325 faces [1] = middle; faces_obj [1] = middle != blank_face ? middle_obj : 0; 1279 faces [1] = middle; faces_obj [1] = middle != blank_face ? middle_obj : 0;
1326 faces [2] = floor; faces_obj [2] = floor != blank_face ? floor_obj : 0; 1280 faces [2] = floor; faces_obj [2] = floor != blank_face ? floor_obj : 0;
1327} 1281}
1328 1282
1329void
1330set_map_reset_time (maptile *map)
1331{
1332 int timeout = map->reset_timeout;
1333
1334 if (timeout <= 0)
1335 timeout = MAP_DEFAULTRESET;
1336 if (timeout >= MAP_MAXRESET)
1337 timeout = MAP_MAXRESET;
1338
1339 map->reset_time = time (0) + timeout;
1340}
1341
1342/* this updates the orig_map->tile_map[tile_num] value after loading 1283/* this updates the orig_map->tile_map[tile_num] value after loading
1343 * the map. It also takes care of linking back the freshly loaded 1284 * the map. It also takes care of linking back the freshly loaded
1344 * maps tile_map values if it tiles back to this one. It returns 1285 * maps tile_map values if it tiles back to this one. It returns
1345 * the value of orig_map->tile_map[tile_num]. It really only does this 1286 * the value of orig_map->tile_map[tile_num]. It really only does this
1346 * so that it is easier for calling functions to verify success. 1287 * so that it is easier for calling functions to verify success.
1347 */ 1288 */
1348static maptile * 1289static maptile *
1349load_and_link_tiled_map (maptile *orig_map, int tile_num) 1290load_and_link_tiled_map (maptile *orig_map, int tile_num)
1350{ 1291{
1351 maptile *mp = orig_map->find_map (orig_map->tile_path[tile_num]); 1292 maptile *mp = orig_map->load_map_sync (orig_map->tile_path [tile_num], orig_map);
1352 mp->load (); 1293
1294 if (!mp || mp->in_memory != MAP_IN_MEMORY)
1295 {
1296 // emergency mode, manufacture a dummy map, this creates a memleak, but thats fine
1297 LOG (llevError, "FATAL: cannot load tiled map %s from %s, leaking memory and worse!\n",
1298 &orig_map->tile_path[tile_num], &orig_map->path);
1299 mp = new maptile (1, 1);
1300 mp->alloc ();
1301 mp->in_memory = MAP_IN_MEMORY;
1302 }
1353 1303
1354 int dest_tile = (tile_num + 2) % 4; 1304 int dest_tile = (tile_num + 2) % 4;
1355 1305
1356 orig_map->tile_map[tile_num] = mp; 1306 orig_map->tile_map[tile_num] = mp;
1357 1307
1358 /* need to do a strcmp here as the orig_map->path is not a shared string */ 1308 // optimisation: back-link map to origin map if euclidean
1359 if (orig_map->tile_map[tile_num]->tile_path[dest_tile] && orig_map->tile_map[tile_num]->tile_path[dest_tile] == orig_map->path) 1309 //TODO: non-euclidean maps MUST GO
1310 if (orig_map->tile_map[tile_num]->tile_path[dest_tile] == orig_map->path)
1360 orig_map->tile_map[tile_num]->tile_map[dest_tile] = orig_map; 1311 orig_map->tile_map[tile_num]->tile_map[dest_tile] = orig_map;
1361 1312
1362 return mp; 1313 return mp;
1363} 1314}
1364 1315
1432 1383
1433/* This is basically the same as out_of_map above, but 1384/* This is basically the same as out_of_map above, but
1434 * instead we return NULL if no map is valid (coordinates 1385 * instead we return NULL if no map is valid (coordinates
1435 * out of bounds and no tiled map), otherwise it returns 1386 * out of bounds and no tiled map), otherwise it returns
1436 * the map as that the coordinates are really on, and 1387 * the map as that the coordinates are really on, and
1437 * updates x and y to be the localized coordinates. 1388 * updates x and y to be the localised coordinates.
1438 * Using this is more efficient of calling out_of_map 1389 * Using this is more efficient of calling out_of_map
1439 * and then figuring out what the real map is 1390 * and then figuring out what the real map is
1440 */ 1391 */
1441maptile * 1392maptile *
1442get_map_from_coord (maptile *m, sint16 *x, sint16 *y) 1393get_map_from_coord (maptile *m, sint16 *x, sint16 *y)
1490 } 1441 }
1491 1442
1492 /* Simple case - coordinates are within this local 1443 /* Simple case - coordinates are within this local
1493 * map. 1444 * map.
1494 */ 1445 */
1495
1496 m->last_access = runtime;
1497 return m; 1446 return m;
1498} 1447}
1499 1448
1500/** 1449/**
1501 * Return whether map2 is adjacent to map1. If so, store the distance from 1450 * Return whether map2 is adjacent to map1. If so, store the distance from

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines