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.1.1.2 by elmex, Wed Feb 22 18:01:21 2006 UTC vs.
Revision 1.14 by elmex, Sun Aug 13 17:16:00 2006 UTC

1/* 1/*
2 * static char *rcsid_map_c = 2 * static char *rcsid_map_c =
3 * "$Id: map.c,v 1.1.1.2 2006/02/22 18:01:21 elmex Exp $"; 3 * "$Id: map.c,v 1.14 2006/08/13 17:16:00 elmex dead $";
4 */ 4 */
5 5
6/* 6/*
7 CrossFire, A Multiplayer game for X-windows 7 CrossFire, A Multiplayer game for X-windows
8 8
38#include "path.h" 38#include "path.h"
39 39
40 40
41extern int nrofallocobjects,nroffreeobjects; 41extern int nrofallocobjects,nroffreeobjects;
42 42
43void (*load_original_map_callback)(mapstruct *map);
44void (*load_temporary_map_callback)(mapstruct *map);
45void (*clean_temporary_map_callback)(mapstruct *map);
43 46
44/* 47/*
45 * Returns the mapstruct which has a name matching the given argument. 48 * Returns the mapstruct which has a name matching the given argument.
46 * return NULL if no match is found. 49 * return NULL if no match is found.
47 */ 50 */
587 * and we only save the head of multi part objects - this is needed 590 * and we only save the head of multi part objects - this is needed
588 * in order to do map tiling properly. 591 * in order to do map tiling properly.
589 */ 592 */
590void save_objects (mapstruct *m, FILE *fp, FILE *fp2, int flag) { 593void save_objects (mapstruct *m, FILE *fp, FILE *fp2, int flag) {
591 int i, j = 0,unique=0; 594 int i, j = 0,unique=0;
592 object *op, *otmp; 595 object *op;
593 /* first pass - save one-part objects */ 596 /* first pass - save one-part objects */
594 for(i = 0; i < MAP_WIDTH(m); i++) 597 for(i = 0; i < MAP_WIDTH(m); i++)
595 for (j = 0; j < MAP_HEIGHT(m); j++) { 598 for (j = 0; j < MAP_HEIGHT(m); j++) {
596 unique=0; 599 unique=0;
597 for(op = get_map_ob (m, i, j); op; op = otmp) { 600 for(op = get_map_ob (m, i, j); op; op = op->above) {
598 otmp = op->above;
599
600 if (QUERY_FLAG(op,FLAG_IS_FLOOR) && QUERY_FLAG(op, FLAG_UNIQUE)) 601 if (QUERY_FLAG(op,FLAG_IS_FLOOR) && QUERY_FLAG(op, FLAG_UNIQUE))
601 unique=1; 602 unique=1;
602 603
603 if(op->type == PLAYER) { 604 if(op->type == PLAYER) {
604 LOG(llevDebug, "Player on map that is being saved\n"); 605 LOG(llevDebug, "Player on map that is being saved\n");
676 677
677 if(m->spaces==NULL) 678 if(m->spaces==NULL)
678 fatal(OUT_OF_MEMORY); 679 fatal(OUT_OF_MEMORY);
679} 680}
680 681
681/* Creatures and returns a map of the specific size. Used 682/* Create and returns a map of the specific size. Used
682 * in random map code and the editor. 683 * in random map code and the editor.
683 */ 684 */
684mapstruct *get_empty_map(int sizex, int sizey) { 685mapstruct *get_empty_map(int sizex, int sizey) {
685 mapstruct *m = get_linked_map(); 686 mapstruct *m = get_linked_map();
686 m->width = sizex; 687 m->width = sizex;
702 int i=0, number_of_entries=0; 703 int i=0, number_of_entries=0;
703 const typedata *current_type; 704 const typedata *current_type;
704 705
705 shop_string=strdup_local(input_string); 706 shop_string=strdup_local(input_string);
706 p=shop_string; 707 p=shop_string;
707 LOG(llevDebug, "parsing %s\n", input_string);
708 /* first we'll count the entries, we'll need that for allocating the array shortly */ 708 /* first we'll count the entries, we'll need that for allocating the array shortly */
709 while (p) { 709 while (p) {
710 p=strchr(p, ';'); 710 p=strchr(p, ';');
711 number_of_entries++; 711 number_of_entries++;
712 if (p) p++; 712 if (p) p++;
1049 close_and_delete(fp, comp); 1049 close_and_delete(fp, comp);
1050 m->in_memory=MAP_IN_MEMORY; 1050 m->in_memory=MAP_IN_MEMORY;
1051 if (!MAP_DIFFICULTY(m)) 1051 if (!MAP_DIFFICULTY(m))
1052 MAP_DIFFICULTY(m)=calculate_difficulty(m); 1052 MAP_DIFFICULTY(m)=calculate_difficulty(m);
1053 set_map_reset_time(m); 1053 set_map_reset_time(m);
1054 if (load_original_map_callback)
1055 load_original_map_callback(m);
1054 return (m); 1056 return (m);
1055} 1057}
1056 1058
1057/* 1059/*
1058 * Loads a map, which has been loaded earlier, from file. 1060 * Loads a map, which has been loaded earlier, from file.
1098 1100
1099 m->in_memory=MAP_LOADING; 1101 m->in_memory=MAP_LOADING;
1100 load_objects (m, fp, 0); 1102 load_objects (m, fp, 0);
1101 close_and_delete(fp, comp); 1103 close_and_delete(fp, comp);
1102 m->in_memory=MAP_IN_MEMORY; 1104 m->in_memory=MAP_IN_MEMORY;
1105 if (load_temporary_map_callback)
1106 load_temporary_map_callback(m);
1103 return m; 1107 return m;
1104} 1108}
1105 1109
1106/* 1110/*
1107 * Loads a map, which has been loaded earlier, from file. 1111 * Loads a map, which has been loaded earlier, from file.
1143 *****************************************************************************/ 1147 *****************************************************************************/
1144 1148
1145/* This goes through map 'm' and removed any unique items on the map. */ 1149/* This goes through map 'm' and removed any unique items on the map. */
1146static void delete_unique_items(mapstruct *m) 1150static void delete_unique_items(mapstruct *m)
1147{ 1151{
1148 int i,j,unique=0; 1152 int i,j,unique;
1149 object *op, *next; 1153 object *op, *next;
1150 1154
1151 for(i=0; i<MAP_WIDTH(m); i++) 1155 for(i=0; i<MAP_WIDTH(m); i++)
1152 for(j=0; j<MAP_HEIGHT(m); j++) { 1156 for(j=0; j<MAP_HEIGHT(m); j++) {
1153 unique=0; 1157 unique=0;
1243 m->tmpname = tempnam_local(settings.tmpdir,NULL); 1247 m->tmpname = tempnam_local(settings.tmpdir,NULL);
1244 strcpy(filename, m->tmpname); 1248 strcpy(filename, m->tmpname);
1245 } 1249 }
1246 LOG(llevDebug,"Saving map %s\n",m->path); 1250 LOG(llevDebug,"Saving map %s\n",m->path);
1247 m->in_memory = MAP_SAVING; 1251 m->in_memory = MAP_SAVING;
1252
1253 unlink (filename); // do not overwrite backups if done via hardlinks
1248 1254
1249 /* Compress if it isn't a temporary save. Do compress if unique */ 1255 /* Compress if it isn't a temporary save. Do compress if unique */
1250 if (m->compressed && (m->unique || m->template || flag)) { 1256 if (m->compressed && (m->unique || m->template || flag)) {
1251 char buf[MAX_BUF]; 1257 char buf[MAX_BUF];
1252 strcpy(buf, uncomp[m->compressed][2]); 1258 strcpy(buf, uncomp[m->compressed][2]);
1611 * have a difficulty set than using this function - human calculation 1617 * have a difficulty set than using this function - human calculation
1612 * is much better than this functions guesswork. 1618 * is much better than this functions guesswork.
1613 */ 1619 */
1614 1620
1615int calculate_difficulty(mapstruct *m) { 1621int calculate_difficulty(mapstruct *m) {
1616 object *op; 1622 object *op;
1617 archetype *at; 1623 archetype *at;
1618 int x,y; 1624 int x, y, i, diff;
1619 int diff=0; 1625 long monster_cnt = 0;
1620 int i; 1626 double avgexp = 0;
1621 sint64 exp_pr_sq, total_exp=0; 1627 sint64 total_exp = 0;
1622 1628
1623 if (MAP_DIFFICULTY(m)) { 1629 if (MAP_DIFFICULTY (m))
1630 {
1624 LOG(llevDebug, "Using stored map difficulty: %d\n", MAP_DIFFICULTY(m)); 1631 LOG(llevDebug, "Using stored map difficulty: %d\n", MAP_DIFFICULTY (m));
1625 return MAP_DIFFICULTY(m); 1632 return MAP_DIFFICULTY (m);
1626 }
1627
1628 for(x=0;x<MAP_WIDTH(m);x++)
1629 for(y=0;y<MAP_HEIGHT(m);y++)
1630 for(op=get_map_ob(m,x,y);op!=NULL;op=op->above) {
1631 if(QUERY_FLAG(op,FLAG_MONSTER))
1632 total_exp+=op->stats.exp;
1633 if(QUERY_FLAG(op,FLAG_GENERATOR)) {
1634 total_exp+=op->stats.exp;
1635 at=type_to_archetype(GENERATE_TYPE(op));
1636 if(at!=NULL)
1637 total_exp+=at->clone.stats.exp*8;
1638 }
1639 } 1633 }
1640#ifdef NEWCALC 1634
1641 (int)exp_pr_sq=((double)1000*total_exp)/(m->map_object->x*m->map_object->y+1); 1635 for(x = 0; x < MAP_WIDTH(m); x++)
1642 for(i=20;i>0;i--) 1636 for(y = 0; y < MAP_HEIGHT(m); y++)
1643 if(exp_pr_sq>level_exp(i,1.0)) { 1637 for(op = get_map_ob(m, x, y); op != NULL; op = op->above)
1644 diff=i; 1638 {
1645 break; 1639 if(QUERY_FLAG (op, FLAG_MONSTER))
1646 } 1640 {
1647#else 1641 total_exp += op->stats.exp;
1648 exp_pr_sq=((double)1000*total_exp)/(MAP_WIDTH(m)*MAP_HEIGHT(m)+1); 1642 monster_cnt++;
1649 diff=20; 1643 }
1650 for(i=1;i<20;i++) 1644
1651 if(exp_pr_sq<=level_exp(i,1.0)) { 1645 if(QUERY_FLAG (op, FLAG_GENERATOR))
1652 diff=i; 1646 {
1653 break; 1647 total_exp += op->stats.exp;
1654 } 1648 at = type_to_archetype(GENERATE_TYPE (op));
1655#endif 1649
1656 return diff; 1650 if(at != NULL)
1651 total_exp += at->clone.stats.exp * 8;
1652
1653 monster_cnt++;
1654 }
1655 }
1656
1657 avgexp = (double) total_exp / monster_cnt;
1658
1659 for (i = 1; i <= settings.max_level; i++)
1660 {
1661 if ((level_exp (i, 1) - level_exp (i - 1, 1)) > (100 * avgexp))
1662 {
1663 /* LOG(llevDebug, "Calculated difficulty for map: %s: %d\n", m->name, i); */
1664 return i;
1665 }
1666 }
1657} 1667}
1658 1668
1659void clean_tmp_map(mapstruct *m) { 1669void clean_tmp_map(mapstruct *m) {
1660 if(m->tmpname == NULL) 1670 if(m->tmpname == NULL)
1661 return; 1671 return;
1672 if (clean_temporary_map_callback)
1673 clean_temporary_map_callback (m);
1662 (void) unlink(m->tmpname); 1674 (void) unlink(m->tmpname);
1663} 1675}
1664 1676
1665void free_all_maps(void) 1677void free_all_maps(void)
1666{ 1678{
1694 return 0; 1706 return 0;
1695 } 1707 }
1696 1708
1697 /* inform all players on the map */ 1709 /* inform all players on the map */
1698 if (change>0) 1710 if (change>0)
1699 new_info_map(NDI_BLACK, m,"It becomes darker."); 1711 new_info_map(NDI_BLACK|NDI_UNIQUE, m,"It becomes darker.");
1700 else 1712 else
1701 new_info_map(NDI_BLACK, m,"It becomes brighter."); 1713 new_info_map(NDI_BLACK|NDI_UNIQUE, m,"It becomes brighter.");
1702 1714
1703 /* Do extra checking. since m->darkness is a unsigned value, 1715 /* Do extra checking. since m->darkness is a unsigned value,
1704 * we need to be extra careful about negative values. 1716 * we need to be extra careful about negative values.
1705 * In general, the checks below are only needed if change 1717 * In general, the checks below are only needed if change
1706 * is not +/-1 1718 * is not +/-1
1951 * case. This generally shouldn't happen, but if the 1963 * case. This generally shouldn't happen, but if the
1952 * map loads fail below, it could happen. 1964 * map loads fail below, it could happen.
1953 */ 1965 */
1954 if (!m) return 0; 1966 if (!m) return 0;
1955 1967
1956 /* Simple case - coordinates are within this local
1957 * map.
1958 */
1959 if ( x>=0 && x<MAP_WIDTH(m) && y>=0 && y < MAP_HEIGHT(m))
1960 return 0;
1961
1962 if (x<0) { 1968 if (x<0) {
1963 if (!m->tile_path[3]) return 1; 1969 if (!m->tile_path[3]) return 1;
1964 if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) { 1970 if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) {
1965 load_and_link_tiled_map(m, 3); 1971 load_and_link_tiled_map(m, 3);
1966 } 1972 }
1985 if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) { 1991 if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) {
1986 load_and_link_tiled_map(m, 2); 1992 load_and_link_tiled_map(m, 2);
1987 } 1993 }
1988 return (out_of_map(m->tile_map[2], x, y - MAP_HEIGHT(m))); 1994 return (out_of_map(m->tile_map[2], x, y - MAP_HEIGHT(m)));
1989 } 1995 }
1996
1997 /* Simple case - coordinates are within this local
1998 * map.
1999 */
1990 return 1; 2000 return 0;
1991} 2001}
1992 2002
1993/* This is basically the same as out_of_map above, but 2003/* This is basically the same as out_of_map above, but
1994 * instead we return NULL if no map is valid (coordinates 2004 * instead we return NULL if no map is valid (coordinates
1995 * out of bounds and no tiled map), otherwise it returns 2005 * out of bounds and no tiled map), otherwise it returns
1999 * and then figuring out what the real map is 2009 * and then figuring out what the real map is
2000 */ 2010 */
2001mapstruct *get_map_from_coord(mapstruct *m, sint16 *x, sint16 *y) 2011mapstruct *get_map_from_coord(mapstruct *m, sint16 *x, sint16 *y)
2002{ 2012{
2003 2013
2004 /* Simple case - coordinates are within this local
2005 * map.
2006 */
2007
2008 if (*x>=0 && *x<MAP_WIDTH(m) && *y>=0 && *y < MAP_HEIGHT(m))
2009 return m;
2010
2011 if (*x<0) { 2014 if (*x<0) {
2012 if (!m->tile_path[3]) return NULL; 2015 if (!m->tile_path[3]) return NULL;
2013 if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) 2016 if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY)
2014 load_and_link_tiled_map(m, 3); 2017 load_and_link_tiled_map(m, 3);
2015 2018
2038 load_and_link_tiled_map(m, 2); 2041 load_and_link_tiled_map(m, 2);
2039 2042
2040 *y -= MAP_HEIGHT(m); 2043 *y -= MAP_HEIGHT(m);
2041 return (get_map_from_coord(m->tile_map[2], x, y)); 2044 return (get_map_from_coord(m->tile_map[2], x, y));
2042 } 2045 }
2043 return NULL; /* Shouldn't get here */ 2046
2047 /* Simple case - coordinates are within this local
2048 * map.
2049 */
2050
2051 return m;
2044} 2052}
2045 2053
2046/** 2054/**
2047 * Return whether map2 is adjacent to map1. If so, store the distance from 2055 * Return whether map2 is adjacent to map1. If so, store the distance from
2048 * map1 to map2 in dx/dy. 2056 * map1 to map2 in dx/dy.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines