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.10 by root, Wed Dec 27 09:28:02 2006 UTC vs.
Revision 1.20 by pippijn, Sat Jan 6 14:42:30 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines