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.7 by root, Thu Dec 14 22:45:40 2006 UTC vs.
Revision 1.16 by root, Sun Dec 31 18:13:27 2006 UTC

18 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 20
21 The authors can be reached via e-mail at <crossfire@schmorp.de> 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 22*/
23
24 23
25#include <global.h> 24#include <global.h>
26#include <random_map.h> 25#include <random_map.h>
27#include <dirent.h> 26#include <dirent.h>
28#include <sys/stat.h> 27#include <sys/stat.h>
29#include <unistd.h> 28#include <unistd.h>
30#include "../include/autoconf.h" 29#include "../include/autoconf.h"
31
32 30
33static int 31static int
34pointer_strcmp (const void *p1, const void *p2) 32pointer_strcmp (const void *p1, const void *p2)
35{ 33{
36 const char *s1 = *(const char **) p1; 34 const char *s1 = *(const char **) p1;
93 91
94 *namelist = rn; 92 *namelist = rn;
95 return entries; 93 return entries;
96} 94}
97 95
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 {
123 if (!strcmp (style_name, style_map->path))
124 return style_map;
125 }
126 style_map = load_original_map (style_name, MAP_STYLE);
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 style_map->next = styles;
141 styles = style_map;
142 }
143 return style_map;
144}
145
146maptile * 96maptile *
147find_style (const char *dirname, const char *stylename, int difficulty) 97find_style (const char *dirname, const char *stylename, int difficulty)
148{ 98{
149 char style_file_path[256]; 99 char style_file_path[256];
150 char style_file_full_path[256]; 100 char style_file_full_path[256];
158 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. */
159 sprintf (style_file_path, "%s", dirname); 109 sprintf (style_file_path, "%s", dirname);
160 110
161 /* is what we were given a directory, or a file? */ 111 /* is what we were given a directory, or a file? */
162 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
163 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))
164 {
165 style_map = load_style_map (style_file_path); 115 style_map = maptile::load_map_sync (style_file_path);
166 } 116
167 if (style_map == NULL) /* maybe we were given a directory! */ 117 if (!style_map) /* maybe we were given a directory! */
168 { 118 {
169 char **namelist; 119 char **namelist;
170 int n; 120 int n;
171 char style_dir_full_path[256]; 121 char style_dir_full_path[256];
172 122
193 * it properly. 143 * it properly.
194 */ 144 */
195 if (difficulty == -1) 145 if (difficulty == -1)
196 { /* pick a random style from this dir. */ 146 { /* pick a random style from this dir. */
197 if (only_subdirs) 147 if (only_subdirs)
198 style_map = NULL; 148 style_map = 0;
199 else 149 else
200 { 150 {
201 strcat (style_file_path, "/"); 151 strcat (style_file_path, "/");
202 strcat (style_file_path, namelist[RANDOM () % n]); 152 strcat (style_file_path, namelist[RANDOM () % n]);
203 style_map = load_style_map (style_file_path); 153 style_map = maptile::load_map_sync (style_file_path);
204 } 154 }
205 } 155 }
206 else 156 else
207 { /* find the map closest in difficulty */ 157 { /* find the map closest in difficulty */
208 int min_dist = 32000, min_index = -1; 158 int min_dist = 32000, min_index = -1;
231 min_dist = dist; 181 min_dist = dist;
232 min_index = i; 182 min_index = i;
233 } 183 }
234 } 184 }
235 } 185 }
186
236 /* presumably now we've found the "best" match for the 187 /* presumably now we've found the "best" match for the
237 difficulty. */ 188 difficulty. */
238 strcat (style_file_path, "/"); 189 strcat (style_file_path, "/");
239 strcat (style_file_path, namelist[min_index]); 190 strcat (style_file_path, namelist[min_index]);
240 style_map = load_style_map (style_file_path); 191 style_map = maptile::load_map_sync (style_file_path);
241 } 192 }
193
242 for (i = 0; i < n; i++) 194 for (i = 0; i < n; i++)
243 free (namelist[i]); 195 free (namelist[i]);
196
244 free (namelist); 197 free (namelist);
245 } 198 }
199
200 if (style_map)
201 style_map->deactivate ();
202
246 return style_map; 203 return style_map;
247 204
248} 205}
249
250 206
251/* picks a random object from a style map. 207/* picks a random object from a style map.
252 * 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
253 * variables to generate tables. 209 * variables to generate tables.
254 */ 210 */
255object * 211object *
256pick_random_object (maptile *style) 212pick_random_object (maptile *style)
257{ 213{
258 int x, y, limit = 0;
259 object *new_obj;
260
261 /* while returning a null object will result in a crash, that 214 /* while returning a null object will result in a crash, that
262 * is actually preferable to an infinite loop. That is because 215 * is actually preferable to an infinite loop. That is because
263 * most servers will automatically restart in case of crash. 216 * most servers will automatically restart in case of crash.
264 * Change the logic on getting the random space - shouldn't make 217 * Change the logic on getting the random space - shouldn't make
265 * any difference, but this seems clearer to me. 218 * any difference, but this seems clearer to me.
266 */ 219 */
267 do 220 for (int i = 1000; --i; )
268 { 221 {
269 limit++; 222 object *new_obj = style->at (RANDOM () % style->width, RANDOM () % style->height).bot;
270 x = RANDOM () % MAP_WIDTH (style); 223
271 y = RANDOM () % MAP_HEIGHT (style); 224 if (new_obj)
272 new_obj = get_map_ob (style, x, y); 225 return new_obj->head_ ();
273 } 226 }
274 while (new_obj == NULL && limit < 1000);
275 if (new_obj->head)
276 return new_obj->head;
277 else
278 return new_obj;
279}
280 227
281 228 // instead of crashing in the unlikely case, try to return *something*
282void 229 return get_archetype ("blocked");
283free_style_maps (void)
284{
285 maptile *next;
286 int style_maps = 0;
287
288 /* delete_map will try to free it from the linked list,
289 * but won't find it, so we need to do it ourselves
290 */
291 while (styles)
292 {
293 next = styles->next;
294 delete_map (styles);
295 styles = next;
296 style_maps++;
297 }
298 LOG (llevDebug, "free_style_maps: Freed %d maps\n", style_maps);
299} 230}
231

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines