Crossfire Server, Branches 1.12  R18729
wall.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_wall_c =
3  * "$Id: wall.c 11578 2009-02-23 22:02:27Z lalo $";
4  */
5 
6 /*
7  CrossFire, A Multiplayer game for X-windows
8 
9  Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10  Copyright (C) 1992 Frank Tore Johansen
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26  The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28 
34 #include <global.h>
35 #include <random_map.h>
36 #include <rproto.h>
37 
56 int surround_flag(char **layout, int i, int j, RMParms *RP) {
57  int surround_index = 0;
58 
59  if ((i > 0) && layout[i-1][j] != 0)
60  surround_index |= 1;
61  if ((i < RP->Xsize-1) && layout[i+1][j] != 0)
62  surround_index |= 2;
63  if ((j > 0) && layout[i][j-1] != 0)
64  surround_index |= 4;
65  if ((j < RP->Ysize-1) && layout[i][j+1] != 0)
66  surround_index |= 8;
67  return surround_index;
68 }
69 
88 int surround_flag2(char **layout, int i, int j, RMParms *RP) {
89  int surround_index = 0;
90 
91  if ((i > 0) && layout[i-1][j] == '#')
92  surround_index |= 1;
93  if ((i < RP->Xsize-1) && layout[i+1][j] == '#')
94  surround_index |= 2;
95  if ((j > 0) && layout[i][j-1] == '#')
96  surround_index |= 4;
97  if ((j < RP->Ysize-1) && layout[i][j+1] == '#')
98  surround_index |= 8;
99  return surround_index;
100 }
101 
120 int surround_flag3(mapstruct *map, int i, int j, RMParms *RP) {
121  int surround_index = 0;
122 
123  if ((i > 0) && (GET_MAP_MOVE_BLOCK(map, i-1, j)&~MOVE_BLOCK_DEFAULT))
124  surround_index |= 1;
125  if ((i < RP->Xsize-1) && (GET_MAP_MOVE_BLOCK(map, i+1, j)&~MOVE_BLOCK_DEFAULT))
126  surround_index |= 2;
127  if ((j > 0) && (GET_MAP_MOVE_BLOCK(map, i, j-1)&~MOVE_BLOCK_DEFAULT))
128  surround_index |= 4;
129  if ((j < RP->Ysize-1) && (GET_MAP_MOVE_BLOCK(map, i, j+1)&~MOVE_BLOCK_DEFAULT))
130  surround_index |= 8;
131 
132  return surround_index;
133 }
134 
153 int surround_flag4(mapstruct *map, int i, int j, RMParms *RP) {
154  int surround_index = 0;
155 
156  if ((i > 0) && wall_blocked(map, i-1, j))
157  surround_index |= 1;
158  if ((i < RP->Xsize-1) && wall_blocked(map, i+1, j))
159  surround_index |= 2;
160  if ((j > 0) && wall_blocked(map, i, j-1))
161  surround_index |= 4;
162  if ((j < RP->Ysize-1) && wall_blocked(map, i, j+1))
163  surround_index |= 8;
164 
165  return surround_index;
166 }
167 
180 void make_map_walls(mapstruct *map, char **layout, char *w_style, RMParms *RP) {
181  char styledirname[256];
182  char stylefilepath[256];
183  mapstruct *style_map = NULL;
184  object *the_wall;
185 
186  /* get the style map */
187  if (!strcmp(w_style, "none"))
188  return;
189  snprintf(styledirname, sizeof(styledirname), "%s", "/styles/wallstyles");
190  snprintf(stylefilepath, sizeof(stylefilepath), "%s/%s", styledirname, w_style);
191  style_map = find_style(styledirname, w_style, -1);
192  if (style_map == NULL)
193  return;
194 
195  /* fill up the map with the given floor style */
196  if ((the_wall = pick_random_object(style_map)) != NULL) {
197  int i, j;
198  char *cp;
199  int joinedwalls = 0;
200  object *thiswall;
201 
202  snprintf(RP->wall_name, sizeof(RP->wall_name), "%s", the_wall->arch->name);
203  if ((cp = strchr(RP->wall_name, '_')) != NULL) {
204  *cp = 0;
205  joinedwalls = 1;
206  }
207 
208  for (i = 0; i < RP->Xsize; i++)
209  for (j = 0; j < RP->Ysize; j++) {
210  if (layout[i][j] == '#') {
211  if (joinedwalls)
212  thiswall = pick_joined_wall(the_wall, layout, i, j, RP);
213  else
214  thiswall = arch_to_object(the_wall->arch);
215  thiswall->x = i;
216  thiswall->y = j;
217  thiswall->move_block = MOVE_ALL;
218  thiswall->move_allow = 0;
219  insert_ob_in_map(thiswall, map, thiswall, INS_NO_MERGE|INS_NO_WALK_ON);
220  }
221  }
222  }
223 }
224 
241 object *pick_joined_wall(object *the_wall, char **layout, int i, int j, RMParms *RP) {
242  /* 1 = wall to left,
243  2 = wall to right,
244  4 = wall above
245  8 = wall below */
246  int surround_index = 0;
247  int l;
248  char wall_name[64];
249  archetype *wall_arch = NULL;
250 
251  strncpy(wall_name, the_wall->arch->name, sizeof(wall_name));
252 
253  /* conventionally, walls are named like this:
254  wallname_wallcode, where wallcode indicates
255  a joinedness, and wallname is the wall.
256  this code depends on the convention for
257  finding the right wall. */
258 
259  /* extract the wall name, which is the text up to the leading _ */
260  for (l = 0; l < 64; l++) {
261  if (wall_name[l] == '_') {
262  wall_name[l] = 0;
263  break;
264  }
265  }
266 
267  surround_index = surround_flag2(layout, i, j, RP);
268 
269  switch (surround_index) {
270  case 0:
271  strcat(wall_name, "_0");
272  break;
273 
274  case 1:
275  strcat(wall_name, "_1_3");
276  break;
277 
278  case 2:
279  strcat(wall_name, "_1_4");
280  break;
281 
282  case 3:
283  strcat(wall_name, "_2_1_2");
284  break;
285 
286  case 4:
287  strcat(wall_name, "_1_2");
288  break;
289 
290  case 5:
291  strcat(wall_name, "_2_2_4");
292  break;
293 
294  case 6:
295  strcat(wall_name, "_2_2_1");
296  break;
297 
298  case 7:
299  strcat(wall_name, "_3_1");
300  break;
301 
302  case 8:
303  strcat(wall_name, "_1_1");
304  break;
305 
306  case 9:
307  strcat(wall_name, "_2_2_3");
308  break;
309 
310  case 10:
311  strcat(wall_name, "_2_2_2");
312  break;
313 
314  case 11:
315  strcat(wall_name, "_3_3");
316  break;
317 
318  case 12:
319  strcat(wall_name, "_2_1_1");
320  break;
321 
322  case 13:
323  strcat(wall_name, "_3_4");
324  break;
325 
326  case 14:
327  strcat(wall_name, "_3_2");
328  break;
329 
330  case 15:
331  strcat(wall_name, "_4");
332  break;
333  }
334  wall_arch = try_find_archetype(wall_name);
335  if (wall_arch)
336  return arch_to_object(wall_arch);
337  else {
338  return arch_to_object(the_wall->arch);
339  }
340 }
341 
362 object *retrofit_joined_wall(mapstruct *the_map, int i, int j, int insert_flag, RMParms *RP) {
363  /* 1 = wall to left,
364  * 2 = wall to right,
365  * 4 = wall above
366  * 8 = wall below
367  */
368  int surround_index = 0;
369  int l;
370  object *the_wall = NULL;
371  object *new_wall = NULL;
372  archetype *wall_arch = NULL;
373 
374  /* first find the wall */
375  for (the_wall = GET_MAP_OB(the_map, i, j); the_wall != NULL; the_wall = the_wall->above)
376  if ((the_wall->move_type&MOVE_WALK) && the_wall->type != EXIT && the_wall->type != TELEPORTER)
377  break;
378 
379 
380  /* if what we found is a door, don't remove it, set the_wall to NULL to
381  * signal that later.
382  */
383  if (the_wall && (the_wall->type == DOOR || the_wall->type == LOCKED_DOOR)) {
384  the_wall = NULL;
385  /* if we're not supposed to insert a new wall where there wasn't one,
386  * we've gotta leave.
387  */
388  if (insert_flag == 0)
389  return NULL;
390  } else if (the_wall == NULL)
391  return NULL;
392 
393  /* canonicalize the wall name */
394  for (l = 0; l < 64; l++) {
395  if (RP->wall_name[l] == '_') {
396  RP->wall_name[l] = 0;
397  break;
398  }
399  }
400 
401  surround_index = surround_flag4(the_map, i, j, RP);
402  /* This would be a lot cleaner to just us a lookup table,
403  * eg, wall_suffix[surround_index]
404  */
405  switch (surround_index) {
406  case 0:
407  strcat(RP->wall_name, "_0");
408  break;
409 
410  case 1:
411  strcat(RP->wall_name, "_1_3");
412  break;
413 
414  case 2:
415  strcat(RP->wall_name, "_1_4");
416  break;
417 
418  case 3:
419  strcat(RP->wall_name, "_2_1_2");
420  break;
421 
422  case 4:
423  strcat(RP->wall_name, "_1_2");
424  break;
425 
426  case 5:
427  strcat(RP->wall_name, "_2_2_4");
428  break;
429 
430  case 6:
431  strcat(RP->wall_name, "_2_2_1");
432  break;
433 
434  case 7:
435  strcat(RP->wall_name, "_3_1");
436  break;
437 
438  case 8:
439  strcat(RP->wall_name, "_1_1");
440  break;
441 
442  case 9:
443  strcat(RP->wall_name, "_2_2_3");
444  break;
445 
446  case 10:
447  strcat(RP->wall_name, "_2_2_2");
448  break;
449 
450  case 11:
451  strcat(RP->wall_name, "_3_3");
452  break;
453 
454  case 12:
455  strcat(RP->wall_name, "_2_1_1");
456  break;
457 
458  case 13:
459  strcat(RP->wall_name, "_3_4");
460  break;
461 
462  case 14:
463  strcat(RP->wall_name, "_3_2");
464  break;
465 
466  case 15:
467  strcat(RP->wall_name, "_4");
468  break;
469  }
470  wall_arch = try_find_archetype(RP->wall_name);
471  if (wall_arch != NULL) {
472  new_wall = arch_to_object(wall_arch);
473  new_wall->x = i;
474  new_wall->y = j;
475  if (the_wall && the_wall->map) {
476  remove_ob(the_wall);
477  free_object(the_wall);
478  }
479  the_wall->move_block = MOVE_ALL;
480  insert_ob_in_map(new_wall, the_map, new_wall, INS_NO_MERGE|INS_NO_WALK_ON);
481  }
482  return new_wall;
483 }
#define MOVE_WALK
Definition: define.h:700
int surround_flag2(char **layout, int i, int j, RMParms *RP)
Definition: wall.c:88
MoveType move_type
Definition: object.h:277
#define TELEPORTER
Definition: define.h:155
MoveType move_allow
Definition: object.h:279
#define DOOR
Definition: define.h:135
struct obj * above
Definition: object.h:146
int surround_flag(char **layout, int i, int j, RMParms *RP)
Definition: wall.c:56
sint16 x
Definition: object.h:179
object * pick_random_object(mapstruct *style)
Definition: style.c:275
Definition: object.h:321
#define MOVE_ALL
Definition: define.h:706
void remove_ob(object *op)
Definition: object.c:1515
struct mapdef * map
Definition: object.h:155
#define INS_NO_WALK_ON
Definition: object.h:396
#define GET_MAP_MOVE_BLOCK(M, X, Y)
Definition: map.h:213
int surround_flag3(mapstruct *map, int i, int j, RMParms *RP)
Definition: wall.c:120
sint16 y
Definition: object.h:179
#define LOCKED_DOOR
Definition: define.h:132
archetype * try_find_archetype(const char *name)
Definition: arch.c:671
#define EXIT
Definition: define.h:228
object * insert_ob_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1992
int Ysize
Definition: random_map.h:60
#define MOVE_BLOCK_DEFAULT
Definition: define.h:717
object * retrofit_joined_wall(mapstruct *the_map, int i, int j, int insert_flag, RMParms *RP)
Definition: wall.c:362
int wall_blocked(mapstruct *m, int x, int y)
Definition: treasure.c:73
int Xsize
Definition: random_map.h:59
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
char wall_name[RM_SIZE]
Definition: random_map.h:44
#define INS_NO_MERGE
Definition: object.h:394
struct archt * arch
Definition: object.h:263
void make_map_walls(mapstruct *map, char **layout, char *w_style, RMParms *RP)
Definition: wall.c:180
#define GET_MAP_OB(M, X, Y)
Definition: map.h:193
object * pick_joined_wall(object *the_wall, char **layout, int i, int j, RMParms *RP)
Definition: wall.c:241
MoveType move_block
Definition: object.h:278
mapstruct * find_style(const char *dirname, const char *stylename, int difficulty)
Definition: style.c:177
void free_object(object *ob)
Definition: object.c:1238
Definition: map.h:346
object * arch_to_object(archetype *at)
Definition: arch.c:576
const char * name
Definition: object.h:322
int surround_flag4(mapstruct *map, int i, int j, RMParms *RP)
Definition: wall.c:153
uint8 type
Definition: object.h:189