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

# User Rev Content
1 elmex 1.1 /*
2 root 1.23 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 pippijn 1.16 *
4 root 1.23 * 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 pippijn 1.16 *
8 root 1.23 * Crossfire TRT is free software: you can redistribute it and/or modify
9 pippijn 1.16 * it under the terms of the GNU General Public License as published by
10 root 1.23 * the Free Software Foundation, either version 3 of the License, or
11 pippijn 1.16 * (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 root 1.23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 pippijn 1.16 * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19 root 1.23 * 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 pippijn 1.16 */
23 elmex 1.1
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 root 1.2 are occupied. */
33 elmex 1.1
34 root 1.4 int
35 root 1.13 surround_flag (char **layout, int i, int j, random_map_params *RP)
36 root 1.4 {
37 elmex 1.1 /* 1 = wall to left,
38 root 1.4 2 = wall to right,
39     4 = wall above
40     8 = wall below */
41 elmex 1.1 int surround_index = 0;
42 root 1.4
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 elmex 1.1 return surround_index;
52     }
53    
54    
55     /* like surround_flag, but only walls count.
56 root 1.2 */
57 elmex 1.1
58 root 1.4 int
59 root 1.13 surround_flag2 (char **layout, int i, int j, random_map_params *RP)
60 root 1.4 {
61 elmex 1.1 /* 1 = wall to left,
62 root 1.4 2 = wall to right,
63     4 = wall above
64     8 = wall below */
65 elmex 1.1 int surround_index = 0;
66 root 1.4
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 elmex 1.1 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 root 1.4 int
85 root 1.13 surround_flag3 (maptile *map, sint16 i, sint16 j, random_map_params *RP)
86 root 1.4 {
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 elmex 1.1
96 elmex 1.20 // don't forget to update the mapspace!
97 root 1.21 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 elmex 1.20
102     if ((i > 0) && (GET_MAP_MOVE_BLOCK (map, i - 1, j) & MOVE_WALK))
103 root 1.4 surround_index |= 1;
104 elmex 1.20 if ((i < RP->Xsize - 1) && (GET_MAP_MOVE_BLOCK (map, i + 1, j) & MOVE_WALK))
105 root 1.4 surround_index |= 2;
106 elmex 1.20 if ((j > 0) && (GET_MAP_MOVE_BLOCK (map, i, j - 1) & MOVE_WALK))
107 root 1.4 surround_index |= 4;
108 elmex 1.20 if ((j < RP->Ysize - 1) && (GET_MAP_MOVE_BLOCK (map, i, j + 1) & MOVE_WALK))
109 root 1.4 surround_index |= 8;
110    
111     return surround_index;
112 elmex 1.1 }
113    
114     /* like surround_flag2, except it checks a map, not a layout. */
115    
116 root 1.4 int
117 root 1.13 surround_flag4 (maptile *map, int i, int j, random_map_params *RP)
118 root 1.4 {
119 elmex 1.1 /* 1 = blocked to left,
120 root 1.4 2 = blocked to right,
121     4 = blocked above
122     8 = blocked below */
123 elmex 1.1 int surround_index = 0;
124    
125 root 1.4 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 elmex 1.1
134     return surround_index;
135     }
136    
137     /* takes a map and a layout, and puts walls in the map (picked from
138 root 1.2 w_style) at '#' marks. */
139 elmex 1.1
140 root 1.4 void
141 root 1.13 make_map_walls (maptile *map, char **layout, char *w_style, random_map_params *RP)
142 root 1.4 {
143 root 1.14 char styledirname[1024];
144     char stylefilepath[1024];
145 root 1.7 maptile *style_map = 0;
146 root 1.4 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 root 1.17 if (!style_map)
155 root 1.4 return;
156    
157     /* fill up the map with the given floor style */
158 root 1.19 if ((the_wall = style_map->pick_random_object ()))
159 root 1.4 {
160     int i, j;
161     char *cp;
162     int joinedwalls = 0;
163     object *thiswall;
164    
165 root 1.22 sprintf (RP->wall_name, "%s", &the_wall->arch->archname);
166 root 1.4 if ((cp = strchr (RP->wall_name, '_')) != NULL)
167     {
168     *cp = 0;
169     joinedwalls = 1;
170 root 1.2 }
171    
172 root 1.4 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 elmex 1.1 }
188     }
189    
190    
191     /* picks the right wall type for this square, to make it look nice,
192 root 1.2 and have everything nicely joined. It uses the layout. */
193 elmex 1.1
194 root 1.4 object *
195 root 1.13 pick_joined_wall (object *the_wall, char **layout, int i, int j, random_map_params *RP)
196 root 1.4 {
197 elmex 1.1 /* 1 = wall to left,
198 root 1.4 2 = wall to right,
199     4 = wall above
200     8 = wall below */
201     int surround_index = 0;
202 elmex 1.1 int l;
203 root 1.14 char wall_name[1024];
204 root 1.4 archetype *wall_arch = 0;
205 elmex 1.1
206 root 1.22 assign (wall_name, the_wall->arch->archname);
207 elmex 1.1
208     /* conventionally, walls are named like this:
209 root 1.4 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 elmex 1.1
214     /* extract the wall name, which is the text up to the leading _ */
215 root 1.4 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 root 1.13 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 root 1.4 }
277 root 1.5 wall_arch = archetype::find (wall_name);
278 elmex 1.1
279 root 1.13 return wall_arch ? arch_to_object (wall_arch) : arch_to_object (the_wall->arch);
280 elmex 1.1 }
281 root 1.4
282 elmex 1.1
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 root 1.4 object *
292 root 1.13 retrofit_joined_wall (maptile *the_map, int i, int j, int insert_flag, random_map_params *RP)
293 root 1.4 {
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 root 1.10 for (the_wall = GET_MAP_OB (the_map, i, j); the_wall != NULL; the_wall = the_wall->above)
307 root 1.4 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 elmex 1.1 }
323 root 1.4 else if (the_wall == NULL)
324     return NULL;
325 elmex 1.1
326 root 1.4 /* 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 root 1.2 }
334 elmex 1.1 }
335    
336 root 1.4 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 root 1.13 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 elmex 1.1 }
391 root 1.11
392 root 1.5 wall_arch = archetype::find (RP->wall_name);
393 root 1.11
394     if (!wall_arch)
395 root 1.4 {
396     new_wall = arch_to_object (wall_arch);
397     new_wall->x = i;
398     new_wall->y = j;
399 root 1.11
400 root 1.4 if (the_wall && the_wall->map)
401     {
402 root 1.8 the_wall->remove ();
403 root 1.9 the_wall->destroy ();
404 root 1.2 }
405 root 1.11
406 root 1.4 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 elmex 1.1 }
409 root 1.11
410 root 1.4 return new_wall;
411 elmex 1.1 }