ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/wall.C
Revision: 1.23
Committed: Sun Jul 1 05:00:19 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_2, rel-2_3
Changes since 1.22: +10 -11 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

# Content
1 /*
2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 */
23
24 #include <global.h>
25 #include <random_map.h>
26 #include <rproto.h>
27
28 /* Put in the walls and autojoin them. */
29
30
31 /* given a layout and a coordinate, tell me which squares up/down/right/left
32 are occupied. */
33
34 int
35 surround_flag (char **layout, int i, int j, random_map_params *RP)
36 {
37 /* 1 = wall to left,
38 2 = wall to right,
39 4 = wall above
40 8 = wall below */
41 int surround_index = 0;
42
43 if ((i > 0) && layout[i - 1][j] != 0)
44 surround_index |= 1;
45 if ((i < RP->Xsize - 1) && layout[i + 1][j] != 0)
46 surround_index |= 2;
47 if ((j > 0) && layout[i][j - 1] != 0)
48 surround_index |= 4;
49 if ((j < RP->Ysize - 1) && layout[i][j + 1] != 0)
50 surround_index |= 8;
51 return surround_index;
52 }
53
54
55 /* like surround_flag, but only walls count.
56 */
57
58 int
59 surround_flag2 (char **layout, int i, int j, random_map_params *RP)
60 {
61 /* 1 = wall to left,
62 2 = wall to right,
63 4 = wall above
64 8 = wall below */
65 int surround_index = 0;
66
67 if ((i > 0) && layout[i - 1][j] == '#')
68 surround_index |= 1;
69 if ((i < RP->Xsize - 1) && layout[i + 1][j] == '#')
70 surround_index |= 2;
71 if ((j > 0) && layout[i][j - 1] == '#')
72 surround_index |= 4;
73 if ((j < RP->Ysize - 1) && layout[i][j + 1] == '#')
74 surround_index |= 8;
75 return surround_index;
76 }
77
78
79 /* like surround_flag, except it checks a map, not a layout.
80 * Since this is part of the random map code, presumption
81 * is that this is not a tiled map.
82 * What is considered blocking and not is somewhat hard coded.
83 */
84 int
85 surround_flag3 (maptile *map, sint16 i, sint16 j, random_map_params *RP)
86 {
87 /*
88 * 1 = blocked to left,
89 * 2 = blocked to right,
90 * 4 = blocked above
91 * 8 = blocked below
92 */
93
94 int surround_index = 0;
95
96 // don't forget to update the mapspace!
97 if (i > 0) map->at (i - 1, j ).update ();
98 if (i < RP->Xsize - 1) map->at (i + 1, j ).update ();
99 if (j > 0) map->at (i , j - 1).update ();
100 if (j < RP->Ysize - 1) map->at (i , j + 1).update ();
101
102 if ((i > 0) && (GET_MAP_MOVE_BLOCK (map, i - 1, j) & MOVE_WALK))
103 surround_index |= 1;
104 if ((i < RP->Xsize - 1) && (GET_MAP_MOVE_BLOCK (map, i + 1, j) & MOVE_WALK))
105 surround_index |= 2;
106 if ((j > 0) && (GET_MAP_MOVE_BLOCK (map, i, j - 1) & MOVE_WALK))
107 surround_index |= 4;
108 if ((j < RP->Ysize - 1) && (GET_MAP_MOVE_BLOCK (map, i, j + 1) & MOVE_WALK))
109 surround_index |= 8;
110
111 return surround_index;
112 }
113
114 /* like surround_flag2, except it checks a map, not a layout. */
115
116 int
117 surround_flag4 (maptile *map, int i, int j, random_map_params *RP)
118 {
119 /* 1 = blocked to left,
120 2 = blocked to right,
121 4 = blocked above
122 8 = blocked below */
123 int surround_index = 0;
124
125 if ((i > 0) && wall_blocked (map, i - 1, j))
126 surround_index |= 1;
127 if ((i < RP->Xsize - 1) && wall_blocked (map, i + 1, j))
128 surround_index |= 2;
129 if ((j > 0) && wall_blocked (map, i, j - 1))
130 surround_index |= 4;
131 if ((j < RP->Ysize - 1) && wall_blocked (map, i, j + 1))
132 surround_index |= 8;
133
134 return surround_index;
135 }
136
137 /* takes a map and a layout, and puts walls in the map (picked from
138 w_style) at '#' marks. */
139
140 void
141 make_map_walls (maptile *map, char **layout, char *w_style, random_map_params *RP)
142 {
143 char styledirname[1024];
144 char stylefilepath[1024];
145 maptile *style_map = 0;
146 object *the_wall;
147
148 /* get the style map */
149 if (!strcmp (w_style, "none"))
150 return;
151 sprintf (styledirname, "%s", "/styles/wallstyles");
152 sprintf (stylefilepath, "%s/%s", styledirname, w_style);
153 style_map = find_style (styledirname, w_style, -1);
154 if (!style_map)
155 return;
156
157 /* fill up the map with the given floor style */
158 if ((the_wall = style_map->pick_random_object ()))
159 {
160 int i, j;
161 char *cp;
162 int joinedwalls = 0;
163 object *thiswall;
164
165 sprintf (RP->wall_name, "%s", &the_wall->arch->archname);
166 if ((cp = strchr (RP->wall_name, '_')) != NULL)
167 {
168 *cp = 0;
169 joinedwalls = 1;
170 }
171
172 for (i = 0; i < RP->Xsize; i++)
173 for (j = 0; j < RP->Ysize; j++)
174 {
175 if (layout[i][j] == '#')
176 {
177 if (joinedwalls)
178 thiswall = pick_joined_wall (the_wall, layout, i, j, RP);
179 else
180 thiswall = arch_to_object (the_wall->arch);
181 thiswall->x = i;
182 thiswall->y = j;
183 thiswall->move_block = MOVE_ALL;
184 insert_ob_in_map (thiswall, map, thiswall, INS_NO_MERGE | INS_NO_WALK_ON);
185 }
186 }
187 }
188 }
189
190
191 /* picks the right wall type for this square, to make it look nice,
192 and have everything nicely joined. It uses the layout. */
193
194 object *
195 pick_joined_wall (object *the_wall, char **layout, int i, int j, random_map_params *RP)
196 {
197 /* 1 = wall to left,
198 2 = wall to right,
199 4 = wall above
200 8 = wall below */
201 int surround_index = 0;
202 int l;
203 char wall_name[1024];
204 archetype *wall_arch = 0;
205
206 assign (wall_name, the_wall->arch->archname);
207
208 /* conventionally, walls are named like this:
209 wallname_wallcode, where wallcode indicates
210 a joinedness, and wallname is the wall.
211 this code depends on the convention for
212 finding the right wall. */
213
214 /* extract the wall name, which is the text up to the leading _ */
215 for (l = 0; l < 64; l++)
216 {
217 if (wall_name[l] == '_')
218 {
219 wall_name[l] = 0;
220 break;
221 }
222 }
223
224 surround_index = surround_flag2 (layout, i, j, RP);
225
226 switch (surround_index)
227 {
228 case 0:
229 strcat (wall_name, "_0");
230 break;
231 case 1:
232 strcat (wall_name, "_1_3");
233 break;
234 case 2:
235 strcat (wall_name, "_1_4");
236 break;
237 case 3:
238 strcat (wall_name, "_2_1_2");
239 break;
240 case 4:
241 strcat (wall_name, "_1_2");
242 break;
243 case 5:
244 strcat (wall_name, "_2_2_4");
245 break;
246 case 6:
247 strcat (wall_name, "_2_2_1");
248 break;
249 case 7:
250 strcat (wall_name, "_3_1");
251 break;
252 case 8:
253 strcat (wall_name, "_1_1");
254 break;
255 case 9:
256 strcat (wall_name, "_2_2_3");
257 break;
258 case 10:
259 strcat (wall_name, "_2_2_2");
260 break;
261 case 11:
262 strcat (wall_name, "_3_3");
263 break;
264 case 12:
265 strcat (wall_name, "_2_1_1");
266 break;
267 case 13:
268 strcat (wall_name, "_3_4");
269 break;
270 case 14:
271 strcat (wall_name, "_3_2");
272 break;
273 case 15:
274 strcat (wall_name, "_4");
275 break;
276 }
277 wall_arch = archetype::find (wall_name);
278
279 return wall_arch ? arch_to_object (wall_arch) : arch_to_object (the_wall->arch);
280 }
281
282
283 /* this takes a map, and changes an existing wall to match what's blocked
284 * around it, counting only doors and walls as blocked. If insert_flag is
285 * 1, it will go ahead and insert the wall into the map. If not, it
286 * will only return the wall which would belong there, and doesn't
287 * remove anything. It depends on the
288 * global, previously-set variable, "wall_name"
289 */
290
291 object *
292 retrofit_joined_wall (maptile *the_map, int i, int j, int insert_flag, random_map_params *RP)
293 {
294 /* 1 = wall to left,
295 * 2 = wall to right,
296 * 4 = wall above
297 * 8 = wall below
298 */
299 int surround_index = 0;
300 int l;
301 object *the_wall = 0;
302 object *new_wall = 0;
303 archetype *wall_arch = 0;
304
305 /* first find the wall */
306 for (the_wall = GET_MAP_OB (the_map, i, j); the_wall != NULL; the_wall = the_wall->above)
307 if ((the_wall->move_type & MOVE_WALK) && the_wall->type != EXIT && the_wall->type != TELEPORTER)
308 break;
309
310
311 /* if what we found is a door, don't remove it, set the_wall to NULL to
312 * signal that later.
313 */
314 if (the_wall && (the_wall->type == DOOR || the_wall->type == LOCKED_DOOR))
315 {
316 the_wall = NULL;
317 /* if we're not supposed to insert a new wall where there wasn't one,
318 * we've gotta leave.
319 */
320 if (insert_flag == 0)
321 return 0;
322 }
323 else if (the_wall == NULL)
324 return NULL;
325
326 /* canonicalize the wall name */
327 for (l = 0; l < 64; l++)
328 {
329 if (RP->wall_name[l] == '_')
330 {
331 RP->wall_name[l] = 0;
332 break;
333 }
334 }
335
336 surround_index = surround_flag4 (the_map, i, j, RP);
337 /* This would be a lot cleaner to just us a lookup table,
338 * eg, wall_suffix[surround_index]
339 */
340 switch (surround_index)
341 {
342 case 0:
343 strcat (RP->wall_name, "_0");
344 break;
345 case 1:
346 strcat (RP->wall_name, "_1_3");
347 break;
348 case 2:
349 strcat (RP->wall_name, "_1_4");
350 break;
351 case 3:
352 strcat (RP->wall_name, "_2_1_2");
353 break;
354 case 4:
355 strcat (RP->wall_name, "_1_2");
356 break;
357 case 5:
358 strcat (RP->wall_name, "_2_2_4");
359 break;
360 case 6:
361 strcat (RP->wall_name, "_2_2_1");
362 break;
363 case 7:
364 strcat (RP->wall_name, "_3_1");
365 break;
366 case 8:
367 strcat (RP->wall_name, "_1_1");
368 break;
369 case 9:
370 strcat (RP->wall_name, "_2_2_3");
371 break;
372 case 10:
373 strcat (RP->wall_name, "_2_2_2");
374 break;
375 case 11:
376 strcat (RP->wall_name, "_3_3");
377 break;
378 case 12:
379 strcat (RP->wall_name, "_2_1_1");
380 break;
381 case 13:
382 strcat (RP->wall_name, "_3_4");
383 break;
384 case 14:
385 strcat (RP->wall_name, "_3_2");
386 break;
387 case 15:
388 strcat (RP->wall_name, "_4");
389 break;
390 }
391
392 wall_arch = archetype::find (RP->wall_name);
393
394 if (!wall_arch)
395 {
396 new_wall = arch_to_object (wall_arch);
397 new_wall->x = i;
398 new_wall->y = j;
399
400 if (the_wall && the_wall->map)
401 {
402 the_wall->remove ();
403 the_wall->destroy ();
404 }
405
406 the_wall->move_block = MOVE_ALL;
407 insert_ob_in_map (new_wall, the_map, new_wall, INS_NO_MERGE | INS_NO_WALK_ON);
408 }
409
410 return new_wall;
411 }