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

Comparing deliantra/server/random_maps/style.C (file contents):
Revision 1.11 by root, Wed Dec 27 13:13:47 2006 UTC vs.
Revision 1.19 by root, Thu Jan 4 16:19:32 2007 UTC

1
1/* 2/*
2 CrossFire, A Multiplayer game for X-windows 3 CrossFire, A Multiplayer game for X-windows
3 4
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
18 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21
21 The authors can be reached via e-mail at <crossfire@schmorp.de> 22 The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 23*/
23
24 24
25#include <global.h> 25#include <global.h>
26#include <random_map.h> 26#include <random_map.h>
27#include <dirent.h> 27#include <dirent.h>
28#include <sys/stat.h> 28#include <sys/stat.h>
29#include <unistd.h> 29#include <unistd.h>
30#include "../include/autoconf.h" 30#include "../include/autoconf.h"
31
32 31
33static int 32static int
34pointer_strcmp (const void *p1, const void *p2) 33pointer_strcmp (const void *p1, const void *p2)
35{ 34{
36 const char *s1 = *(const char **) p1; 35 const char *s1 = *(const char **) p1;
93 92
94 *namelist = rn; 93 *namelist = rn;
95 return entries; 94 return entries;
96} 95}
97 96
98
99
100
101
102/* this function loads and returns the map requested.
103 * dirname, for example, is "/styles/wallstyles", stylename, is,
104 * for example, "castle", difficulty is -1 when difficulty is
105 * irrelevant to the style. If dirname is given, but stylename
106 * isn't, and difficult is -1, it returns a random style map.
107 * Otherwise, it tries to match the difficulty given with a style
108 * file, named style_name_# where # is an integer
109 */
110
111/* remove extern, so visible to command_style_map_info function */
112maptile *styles = NULL;
113
114
115maptile *
116load_style_map (char *style_name)
117{
118 maptile *style_map;
119
120 /* Given a file. See if its in memory */
121 for (style_map = styles; style_map; style_map = style_map->next)
122 if (!strcmp (style_name, style_map->path))
123 return style_map;
124
125 style_map = load_original_map (style_name, MAP_STYLE);
126
127 /* Remove it from global list, put it on our local list */
128 if (style_map)
129 {
130 style_map->unlink ();
131
132 style_map->next = styles;
133 styles = style_map;
134 }
135
136 return style_map;
137}
138
139maptile * 97maptile *
140find_style (const char *dirname, const char *stylename, int difficulty) 98find_style (const char *dirname, const char *stylename, int difficulty)
141{ 99{
142 char style_file_path[256]; 100 char style_file_path[1024];
143 char style_file_full_path[256]; 101 char style_file_full_path[1024];
144 maptile *style_map = NULL; 102 maptile *style_map = NULL;
145 struct stat file_stat; 103 struct stat file_stat;
146 int i, only_subdirs = 0; 104 int i, only_subdirs = 0;
147 105
148 /* if stylename exists, set style_file_path to that file. */ 106 /* if stylename exists, set style_file_path to that file. */
151 else /* otherwise, just use the dirname. We'll pick a random stylefile. */ 109 else /* otherwise, just use the dirname. We'll pick a random stylefile. */
152 sprintf (style_file_path, "%s", dirname); 110 sprintf (style_file_path, "%s", dirname);
153 111
154 /* is what we were given a directory, or a file? */ 112 /* is what we were given a directory, or a file? */
155 sprintf (style_file_full_path, "%s/maps%s", settings.datadir, style_file_path); 113 sprintf (style_file_full_path, "%s/maps%s", settings.datadir, style_file_path);
114
156 if (stat (style_file_full_path, &file_stat) == 0 && !S_ISDIR (file_stat.st_mode)) 115 if (stat (style_file_full_path, &file_stat) == 0 && !S_ISDIR (file_stat.st_mode))
157 {
158 style_map = load_style_map (style_file_path); 116 style_map = maptile::find_sync (style_file_path);
159 } 117
160 if (style_map == NULL) /* maybe we were given a directory! */ 118 if (!style_map) /* maybe we were given a directory! */
161 { 119 {
162 char **namelist; 120 char **namelist;
163 int n; 121 int n;
164 char style_dir_full_path[256]; 122 char style_dir_full_path[256];
165 123
186 * it properly. 144 * it properly.
187 */ 145 */
188 if (difficulty == -1) 146 if (difficulty == -1)
189 { /* pick a random style from this dir. */ 147 { /* pick a random style from this dir. */
190 if (only_subdirs) 148 if (only_subdirs)
191 style_map = NULL; 149 style_map = 0;
192 else 150 else
193 { 151 {
194 strcat (style_file_path, "/"); 152 strcat (style_file_path, "/");
195 strcat (style_file_path, namelist[RANDOM () % n]); 153 strcat (style_file_path, namelist[RANDOM () % n]);
196 style_map = load_style_map (style_file_path); 154 style_map = maptile::find_sync (style_file_path);
197 } 155 }
198 } 156 }
199 else 157 else
200 { /* find the map closest in difficulty */ 158 { /* find the map closest in difficulty */
201 int min_dist = 32000, min_index = -1; 159 int min_dist = 32000, min_index = -1;
224 min_dist = dist; 182 min_dist = dist;
225 min_index = i; 183 min_index = i;
226 } 184 }
227 } 185 }
228 } 186 }
187
229 /* presumably now we've found the "best" match for the 188 /* presumably now we've found the "best" match for the
230 difficulty. */ 189 difficulty. */
231 strcat (style_file_path, "/"); 190 strcat (style_file_path, "/");
232 strcat (style_file_path, namelist[min_index]); 191 strcat (style_file_path, namelist[min_index]);
233 style_map = load_style_map (style_file_path); 192 style_map = maptile::find_sync (style_file_path);
234 } 193 }
194
235 for (i = 0; i < n; i++) 195 for (i = 0; i < n; i++)
236 free (namelist[i]); 196 free (namelist[i]);
197
237 free (namelist); 198 free (namelist);
238 } 199 }
200
201 if (style_map)
202 {
203 style_map->load_sync ();
204 style_map->deactivate ();
205 }
206
239 return style_map; 207 return style_map;
240 208
241} 209}
242
243 210
244/* picks a random object from a style map. 211/* picks a random object from a style map.
245 * Redone by MSW so it should be faster and not use static 212 * Redone by MSW so it should be faster and not use static
246 * variables to generate tables. 213 * variables to generate tables.
247 */ 214 */
248object * 215object *
249pick_random_object (maptile *style) 216pick_random_object (maptile *style)
250{ 217{
251 int x, y, limit = 0;
252 object *new_obj;
253
254 /* while returning a null object will result in a crash, that 218 /* while returning a null object will result in a crash, that
255 * is actually preferable to an infinite loop. That is because 219 * is actually preferable to an infinite loop. That is because
256 * most servers will automatically restart in case of crash. 220 * most servers will automatically restart in case of crash.
257 * Change the logic on getting the random space - shouldn't make 221 * Change the logic on getting the random space - shouldn't make
258 * any difference, but this seems clearer to me. 222 * any difference, but this seems clearer to me.
259 */ 223 */
260 do 224 for (int i = 1000; --i;)
261 {
262 limit++;
263 x = RANDOM () % style->width;
264 y = RANDOM () % style->height;
265 new_obj = GET_MAP_OB (style, x, y);
266 } 225 {
267 while (new_obj == NULL && limit < 1000); 226 object *new_obj = style->at (RANDOM () % style->width, RANDOM () % style->height).bot;
268 if (new_obj->head) 227
228 if (new_obj)
269 return new_obj->head; 229 return new_obj->head_ ();
270 else
271 return new_obj;
272}
273
274
275void
276free_style_maps (void)
277{
278 maptile *next;
279 int style_maps = 0;
280
281 /* delete_map will try to free it from the linked list,
282 * but won't find it, so we need to do it ourselves
283 */
284 while (styles)
285 { 230 }
286 next = styles->next; 231
287 delete_map (styles); 232 // instead of crashing in the unlikely case, try to return *something*
288 styles = next; 233 return get_archetype ("blocked");
289 style_maps++;
290 }
291 LOG (llevDebug, "free_style_maps: Freed %d maps\n", style_maps);
292} 234}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines