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.12 by root, Sat Dec 30 10:16:11 2006 UTC vs.
Revision 1.18 by root, Sun Dec 31 20:46:17 2006 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
111maptile *
112load_style_map (char *style_name)
113{
114 maptile *style_map = maptile::find_map (style_name, 0);
115 style_map->load ();
116 return style_map;
117}
118
119maptile * 97maptile *
120find_style (const char *dirname, const char *stylename, int difficulty) 98find_style (const char *dirname, const char *stylename, int difficulty)
121{ 99{
122 char style_file_path[256]; 100 char style_file_path[1024];
123 char style_file_full_path[256]; 101 char style_file_full_path[1024];
124 maptile *style_map = NULL; 102 maptile *style_map = NULL;
125 struct stat file_stat; 103 struct stat file_stat;
126 int i, only_subdirs = 0; 104 int i, only_subdirs = 0;
127 105
128 /* if stylename exists, set style_file_path to that file. */ 106 /* if stylename exists, set style_file_path to that file. */
131 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. */
132 sprintf (style_file_path, "%s", dirname); 110 sprintf (style_file_path, "%s", dirname);
133 111
134 /* is what we were given a directory, or a file? */ 112 /* is what we were given a directory, or a file? */
135 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
136 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))
137 {
138 style_map = load_style_map (style_file_path); 116 style_map = maptile::load_map_sync (style_file_path);
139 } 117
140 if (style_map == NULL) /* maybe we were given a directory! */ 118 if (!style_map) /* maybe we were given a directory! */
141 { 119 {
142 char **namelist; 120 char **namelist;
143 int n; 121 int n;
144 char style_dir_full_path[256]; 122 char style_dir_full_path[256];
145 123
166 * it properly. 144 * it properly.
167 */ 145 */
168 if (difficulty == -1) 146 if (difficulty == -1)
169 { /* pick a random style from this dir. */ 147 { /* pick a random style from this dir. */
170 if (only_subdirs) 148 if (only_subdirs)
171 style_map = NULL; 149 style_map = 0;
172 else 150 else
173 { 151 {
174 strcat (style_file_path, "/"); 152 strcat (style_file_path, "/");
175 strcat (style_file_path, namelist[RANDOM () % n]); 153 strcat (style_file_path, namelist[RANDOM () % n]);
176 style_map = load_style_map (style_file_path); 154 style_map = maptile::load_map_sync (style_file_path);
177 } 155 }
178 } 156 }
179 else 157 else
180 { /* find the map closest in difficulty */ 158 { /* find the map closest in difficulty */
181 int min_dist = 32000, min_index = -1; 159 int min_dist = 32000, min_index = -1;
204 min_dist = dist; 182 min_dist = dist;
205 min_index = i; 183 min_index = i;
206 } 184 }
207 } 185 }
208 } 186 }
187
209 /* presumably now we've found the "best" match for the 188 /* presumably now we've found the "best" match for the
210 difficulty. */ 189 difficulty. */
211 strcat (style_file_path, "/"); 190 strcat (style_file_path, "/");
212 strcat (style_file_path, namelist[min_index]); 191 strcat (style_file_path, namelist[min_index]);
213 style_map = load_style_map (style_file_path); 192 style_map = maptile::load_map_sync (style_file_path);
214 } 193 }
194
215 for (i = 0; i < n; i++) 195 for (i = 0; i < n; i++)
216 free (namelist[i]); 196 free (namelist[i]);
197
217 free (namelist); 198 free (namelist);
218 } 199 }
200
201 if (style_map)
202 style_map->deactivate ();
203
219 return style_map; 204 return style_map;
220 205
221} 206}
222 207
223/* picks a random object from a style map. 208/* picks a random object from a style map.
225 * variables to generate tables. 210 * variables to generate tables.
226 */ 211 */
227object * 212object *
228pick_random_object (maptile *style) 213pick_random_object (maptile *style)
229{ 214{
230 int x, y, limit = 0;
231 object *new_obj;
232
233 /* while returning a null object will result in a crash, that 215 /* while returning a null object will result in a crash, that
234 * is actually preferable to an infinite loop. That is because 216 * is actually preferable to an infinite loop. That is because
235 * most servers will automatically restart in case of crash. 217 * most servers will automatically restart in case of crash.
236 * Change the logic on getting the random space - shouldn't make 218 * Change the logic on getting the random space - shouldn't make
237 * any difference, but this seems clearer to me. 219 * any difference, but this seems clearer to me.
238 */ 220 */
239 do 221 for (int i = 1000; --i;)
240 { 222 {
241 limit++; 223 object *new_obj = style->at (RANDOM () % style->width, RANDOM () % style->height).bot;
242 x = RANDOM () % style->width; 224
243 y = RANDOM () % style->height; 225 if (new_obj)
244 new_obj = GET_MAP_OB (style, x, y); 226 return new_obj->head_ ();
245 } 227 }
246 while (new_obj == NULL && limit < 1000);
247 228
248 if (new_obj->head) 229 // instead of crashing in the unlikely case, try to return *something*
249 return new_obj->head; 230 return get_archetype ("blocked");
250 else
251 return new_obj;
252} 231}
253

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines