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.3 by root, Sun Sep 10 16:06:37 2006 UTC vs.
Revision 1.16 by root, Sun Dec 31 18:13:27 2006 UTC

1
2/*
3 * static char *rcsid_style_c =
4 * "$Id: style.C,v 1.3 2006/09/10 16:06:37 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 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
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 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>
28*/ 22*/
29
30 23
31#include <global.h> 24#include <global.h>
32#include <random_map.h> 25#include <random_map.h>
33#ifndef WIN32 /* ---win32 exclude headers */
34# include <dirent.h> 26#include <dirent.h>
35# include <sys/stat.h> 27#include <sys/stat.h>
36# include <unistd.h> 28#include <unistd.h>
37# include "../include/autoconf.h" 29#include "../include/autoconf.h"
38#endif /* win32 */
39
40 30
41static int 31static int
42pointer_strcmp (const void *p1, const void *p2) 32pointer_strcmp (const void *p1, const void *p2)
43{ 33{
44 const char *s1 = *(const char **) p1; 34 const char *s1 = *(const char **) p1;
89 if (entries == entry_size) 79 if (entries == entry_size)
90 { 80 {
91 entry_size += 10; 81 entry_size += 10;
92 rn = (char **) realloc (rn, sizeof (char *) * entry_size); 82 rn = (char **) realloc (rn, sizeof (char *) * entry_size);
93 } 83 }
94 rn[entries] = strdup_local (d->d_name); 84 rn[entries] = strdup (d->d_name);
95 entries++; 85 entries++;
96 86
97 } 87 }
98 (void) closedir (dp); 88 (void) closedir (dp);
99 89
101 91
102 *namelist = rn; 92 *namelist = rn;
103 return entries; 93 return entries;
104} 94}
105 95
106 96maptile *
107
108
109
110/* this function loads and returns the map requested.
111 * dirname, for example, is "/styles/wallstyles", stylename, is,
112 * for example, "castle", difficulty is -1 when difficulty is
113 * irrelevant to the style. If dirname is given, but stylename
114 * isn't, and difficult is -1, it returns a random style map.
115 * Otherwise, it tries to match the difficulty given with a style
116 * file, named style_name_# where # is an integer
117 */
118
119/* remove extern, so visible to command_style_map_info function */
120mapstruct *styles = NULL;
121
122
123mapstruct *
124load_style_map (char *style_name)
125{
126 mapstruct *style_map;
127
128 /* Given a file. See if its in memory */
129 for (style_map = styles; style_map != NULL; style_map = style_map->next)
130 {
131 if (!strcmp (style_name, style_map->path))
132 return style_map;
133 }
134 style_map = load_original_map (style_name, MAP_STYLE);
135 /* Remove it from global list, put it on our local list */
136 if (style_map)
137 {
138 mapstruct *tmp;
139
140 if (style_map == first_map)
141 first_map = style_map->next;
142 else
143 {
144 for (tmp = first_map; tmp && tmp->next != style_map; tmp = tmp->next);
145 if (tmp)
146 tmp->next = style_map->next;
147 }
148 style_map->next = styles;
149 styles = style_map;
150 }
151 return style_map;
152}
153
154mapstruct *
155find_style (const char *dirname, const char *stylename, int difficulty) 97find_style (const char *dirname, const char *stylename, int difficulty)
156{ 98{
157 char style_file_path[256]; 99 char style_file_path[256];
158 char style_file_full_path[256]; 100 char style_file_full_path[256];
159 mapstruct *style_map = NULL; 101 maptile *style_map = NULL;
160 struct stat file_stat; 102 struct stat file_stat;
161 int i, only_subdirs = 0; 103 int i, only_subdirs = 0;
162 104
163 /* if stylename exists, set style_file_path to that file. */ 105 /* if stylename exists, set style_file_path to that file. */
164 if (stylename && strlen (stylename) > 0) 106 if (stylename && strlen (stylename) > 0)
166 else /* otherwise, just use the dirname. We'll pick a random stylefile. */ 108 else /* otherwise, just use the dirname. We'll pick a random stylefile. */
167 sprintf (style_file_path, "%s", dirname); 109 sprintf (style_file_path, "%s", dirname);
168 110
169 /* is what we were given a directory, or a file? */ 111 /* is what we were given a directory, or a file? */
170 sprintf (style_file_full_path, "%s/maps%s", settings.datadir, style_file_path); 112 sprintf (style_file_full_path, "%s/maps%s", settings.datadir, style_file_path);
113
171 if (stat (style_file_full_path, &file_stat) == 0 && !S_ISDIR (file_stat.st_mode)) 114 if (stat (style_file_full_path, &file_stat) == 0 && !S_ISDIR (file_stat.st_mode))
172 {
173 style_map = load_style_map (style_file_path); 115 style_map = maptile::load_map_sync (style_file_path);
174 } 116
175 if (style_map == NULL) /* maybe we were given a directory! */ 117 if (!style_map) /* maybe we were given a directory! */
176 { 118 {
177 char **namelist; 119 char **namelist;
178 int n; 120 int n;
179 char style_dir_full_path[256]; 121 char style_dir_full_path[256];
180 122
201 * it properly. 143 * it properly.
202 */ 144 */
203 if (difficulty == -1) 145 if (difficulty == -1)
204 { /* pick a random style from this dir. */ 146 { /* pick a random style from this dir. */
205 if (only_subdirs) 147 if (only_subdirs)
206 style_map = NULL; 148 style_map = 0;
207 else 149 else
208 { 150 {
209 strcat (style_file_path, "/"); 151 strcat (style_file_path, "/");
210 strcat (style_file_path, namelist[RANDOM () % n]); 152 strcat (style_file_path, namelist[RANDOM () % n]);
211 style_map = load_style_map (style_file_path); 153 style_map = maptile::load_map_sync (style_file_path);
212 } 154 }
213 } 155 }
214 else 156 else
215 { /* find the map closest in difficulty */ 157 { /* find the map closest in difficulty */
216 int min_dist = 32000, min_index = -1; 158 int min_dist = 32000, min_index = -1;
239 min_dist = dist; 181 min_dist = dist;
240 min_index = i; 182 min_index = i;
241 } 183 }
242 } 184 }
243 } 185 }
186
244 /* presumably now we've found the "best" match for the 187 /* presumably now we've found the "best" match for the
245 difficulty. */ 188 difficulty. */
246 strcat (style_file_path, "/"); 189 strcat (style_file_path, "/");
247 strcat (style_file_path, namelist[min_index]); 190 strcat (style_file_path, namelist[min_index]);
248 style_map = load_style_map (style_file_path); 191 style_map = maptile::load_map_sync (style_file_path);
249 } 192 }
193
250 for (i = 0; i < n; i++) 194 for (i = 0; i < n; i++)
251 free (namelist[i]); 195 free (namelist[i]);
196
252 free (namelist); 197 free (namelist);
253 } 198 }
199
200 if (style_map)
201 style_map->deactivate ();
202
254 return style_map; 203 return style_map;
255 204
256} 205}
257
258 206
259/* picks a random object from a style map. 207/* picks a random object from a style map.
260 * Redone by MSW so it should be faster and not use static 208 * Redone by MSW so it should be faster and not use static
261 * variables to generate tables. 209 * variables to generate tables.
262 */ 210 */
263object * 211object *
264pick_random_object (mapstruct *style) 212pick_random_object (maptile *style)
265{ 213{
266 int x, y, limit = 0;
267 object *new_obj;
268
269 /* while returning a null object will result in a crash, that 214 /* while returning a null object will result in a crash, that
270 * is actually preferable to an infinite loop. That is because 215 * is actually preferable to an infinite loop. That is because
271 * most servers will automatically restart in case of crash. 216 * most servers will automatically restart in case of crash.
272 * Change the logic on getting the random space - shouldn't make 217 * Change the logic on getting the random space - shouldn't make
273 * any difference, but this seems clearer to me. 218 * any difference, but this seems clearer to me.
274 */ 219 */
275 do 220 for (int i = 1000; --i; )
276 { 221 {
277 limit++; 222 object *new_obj = style->at (RANDOM () % style->width, RANDOM () % style->height).bot;
278 x = RANDOM () % MAP_WIDTH (style); 223
279 y = RANDOM () % MAP_HEIGHT (style); 224 if (new_obj)
280 new_obj = get_map_ob (style, x, y); 225 return new_obj->head_ ();
281 } 226 }
282 while (new_obj == NULL && limit < 1000);
283 if (new_obj->head)
284 return new_obj->head;
285 else
286 return new_obj;
287}
288 227
289 228 // instead of crashing in the unlikely case, try to return *something*
290void 229 return get_archetype ("blocked");
291free_style_maps (void)
292{
293 mapstruct *next;
294 int style_maps = 0;
295
296 /* delete_map will try to free it from the linked list,
297 * but won't find it, so we need to do it ourselves
298 */
299 while (styles)
300 {
301 next = styles->next;
302 delete_map (styles);
303 styles = next;
304 style_maps++;
305 }
306 LOG (llevDebug, "free_style_maps: Freed %d maps\n", style_maps);
307} 230}
231

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines