Atrinik Server  4.0
wall.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program 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 2 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, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
30 #include <global.h>
31 #include <arch.h>
32 
45 int surround_flag(char **layout, int i, int j, RMParms *RP)
46 {
47  int surround_index = 0;
48 
49  if ((i > 0) && layout[i - 1][j] != '\0') {
50  surround_index |= 1;
51  }
52 
53  if ((i < RP->Xsize - 1) && layout[i + 1][j] != '\0') {
54  surround_index |= 2;
55  }
56 
57  if ((j > 0) && layout[i][j - 1] != '\0') {
58  surround_index |= 4;
59  }
60 
61  if ((j < RP->Ysize - 1) && layout[i][j + 1] != '\0') {
62  surround_index |= 8;
63  }
64 
65  return surround_index;
66 }
67 
80 int surround_flag2(char **layout, int i, int j, RMParms *RP)
81 {
82  int surround_index = 0;
83 
84  if ((i > 0) && (layout[i - 1][j] == '#' || layout[i - 1][j] == 'D')) {
85  surround_index |= 1;
86  }
87 
88  if ((i < RP->Xsize - 1) && (layout[i + 1][j] == '#' || layout[i + 1][j] == 'D')) {
89  surround_index |= 2;
90  }
91 
92  if ((j > 0) && (layout[i][j - 1] == '#' || layout[i][j - 1] == 'D')) {
93  surround_index |= 4;
94  }
95 
96  if ((j < RP->Ysize - 1) && (layout[i][j + 1] == '#' || layout[i][j + 1] == 'D')) {
97  surround_index |= 8;
98  }
99 
100  return surround_index;
101 }
102 
119 int surround_flag3(mapstruct *map, int i, int j, RMParms *RP)
120 {
121  int surround_index = 0;
122 
123  if ((i > 0) && blocked(NULL, map, i - 1, j, TERRAIN_ALL)) {
124  surround_index |= 1;
125  }
126 
127  if ((i < RP->Xsize - 1) && blocked(NULL, map, i + 1, j, TERRAIN_ALL)) {
128  surround_index |= 2;
129  }
130 
131  if ((j > 0) && blocked(NULL, map, i, j - 1, TERRAIN_ALL)) {
132  surround_index |= 4;
133  }
134 
135  if ((j < RP->Ysize - 1) && blocked(NULL, map, i, j + 1, TERRAIN_ALL)) {
136  surround_index |= 8;
137  }
138 
139  return surround_index;
140 }
141 
158 int surround_flag4(mapstruct *map, int i, int j, RMParms *RP)
159 {
160  int surround_index = 0;
161 
162  if ((i > 0) && wall_blocked(map, i - 1, j)) {
163  surround_index |= 1;
164  }
165 
166  if ((i < RP->Xsize - 1) && wall_blocked(map, i + 1, j)) {
167  surround_index |= 2;
168  }
169 
170  if ((j > 0) && wall_blocked(map, i, j - 1)) {
171  surround_index |= 4;
172  }
173 
174  if ((j < RP->Ysize - 1) && wall_blocked(map, i, j + 1)) {
175  surround_index |= 8;
176  }
177 
178  return surround_index;
179 }
180 
193 void make_map_walls(mapstruct *map, char **layout, char *w_style, RMParms *RP)
194 {
195  char styledirname[256], stylefilepath[256];
196  mapstruct *style_map = NULL;
197  object *the_wall;
198 
199  /* get the style map */
200  if (!strcmp(w_style, "none")) {
201  return;
202  }
203 
204  strncpy(styledirname, "/styles/wallstyles", sizeof(styledirname) - 1);
205 
206  snprintf(stylefilepath, sizeof(stylefilepath), "%s/%s", styledirname, w_style);
207  style_map = find_style(styledirname, w_style, -1);
208 
209  if (style_map == 0) {
210  return;
211  }
212 
213  /* Fill up the map with the given wall style */
214  if ((the_wall = pick_random_object(style_map)) != NULL) {
215  int i, j;
216  char *cp;
217 
218  snprintf(RP->wall_name, sizeof(RP->wall_name), "%s", the_wall->arch->name);
219 
220  if ((cp = strchr(RP->wall_name, '_')) != NULL) {
221  *cp = '\0';
222  }
223 
224  for (i = 0; i < RP->Xsize; i++) {
225  for (j = 0; j < RP->Ysize; j++) {
226  if (layout[i][j] == '#') {
227  object *thiswall = pick_joined_wall(the_wall, layout, i, j, RP);
228 
229  thiswall->x = i;
230  thiswall->y = j;
231 
232  /* Make SURE it's a wall */
233  SET_FLAG(thiswall, FLAG_NO_PASS);
234 
235  object_insert_map(thiswall, map, thiswall, INS_NO_MERGE | INS_NO_WALK_ON);
236  }
237  }
238  }
239  }
240 }
241 
254 object *pick_joined_wall(object *the_wall, char **layout, int i, int j, RMParms *RP)
255 {
256  int surround_index = 0, l;
257  char wall_name[MAX_BUF];
258  archetype_t *wall_arch = 0;
259 
260  strncpy(wall_name, the_wall->arch->name, sizeof(wall_name) - 1);
261  wall_name[sizeof(wall_name) - 1] = '\0';
262 
263  /* conventionally, walls are named like this:
264  * wallname_wallcode, where wallcode indicates
265  * a joinedness, and wallname is the wall.
266  * this code depends on the convention for
267  * finding the right wall. */
268 
269  /* extract the wall name, which is the text up to the leading _ */
270  for (l = sizeof(wall_name) - 1; l >= 0; l--) {
271  if (wall_name[l] == '_') {
272  wall_name[l] = '\0';
273  break;
274  }
275  }
276 
277  surround_index = surround_flag2(layout, i, j, RP);
278 
279  switch (surround_index) {
280  case 0:
281  strcat(wall_name, "_0");
282  break;
283 
284  case 10:
285  case 8:
286  case 2:
287  strcat(wall_name, "_8");
288  break;
289 
290  case 11:
291  case 9:
292  case 3:
293  strcat(wall_name, "_1");
294  break;
295 
296  case 12:
297  case 4:
298  case 14:
299  case 6:
300  strcat(wall_name, "_3");
301  break;
302 
303  case 1:
304  case 5:
305  case 7:
306  case 13:
307  case 15:
308  strcat(wall_name, "_4");
309  break;
310  }
311 
312  wall_arch = arch_find(wall_name);
313 
314  if (wall_arch) {
315  return arch_to_object(wall_arch);
316  } else {
317  return arch_to_object(the_wall->arch);
318  }
319 }
320 
333 object *retrofit_joined_wall(mapstruct *the_map, int i, int j, int insert_flag, RMParms *RP)
334 {
335  int surround_index = 0, l;
336  object *the_wall = NULL, *new_wall = NULL;
337  archetype_t *wall_arch = NULL;
338 
339  /* First find the wall */
340  for (the_wall = GET_MAP_OB(the_map, i, j); the_wall != NULL; the_wall = the_wall->above) {
341  if (QUERY_FLAG(the_wall, FLAG_NO_PASS) && the_wall->type != EXIT) {
342  break;
343  }
344  }
345 
346  /* if what we found is a door, don't remove it, set the_wall to NULL to
347  * signal that later. */
348  if (the_wall && the_wall->type == DOOR) {
349  the_wall = NULL;
350 
351  /* if we're not supposed to insert a new wall where there wasn't one,
352  * we've gotta leave. */
353  if (insert_flag == 0) {
354  return NULL;
355  }
356  } else if (the_wall == NULL) {
357  return NULL;
358  }
359 
360  /* Canonicalize the wall name */
361  for (l = 0; l < 64; l++) {
362  if (RP->wall_name[l] == '_') {
363  RP->wall_name[l] = 0;
364  break;
365  }
366  }
367 
368  surround_index = surround_flag4(the_map, i, j, RP);
369 
370  switch (surround_index) {
371  case 0:
372  strcat(RP->wall_name, "_0");
373  break;
374 
375  case 10:
376  case 8:
377  case 2:
378  strcat(RP->wall_name, "_8");
379  break;
380 
381  case 11:
382  case 9:
383  case 3:
384  strcat(RP->wall_name, "_1");
385  break;
386 
387  case 12:
388  case 4:
389  case 14:
390  case 6:
391  strcat(RP->wall_name, "_3");
392  break;
393 
394  case 1:
395  case 5:
396  case 7:
397  case 13:
398  case 15:
399  strcat(RP->wall_name, "_4");
400  break;
401  }
402 
403  wall_arch = arch_find(RP->wall_name);
404 
405  if (wall_arch != NULL) {
406  new_wall = arch_to_object(wall_arch);
407  new_wall->x = i;
408  new_wall->y = j;
409 
410  if (the_wall && the_wall->map) {
411  object_remove(the_wall, 0);
412  object_destroy(the_wall);
413  }
414 
415  /* Make SURE it's a wall */
416  SET_FLAG(new_wall, FLAG_NO_PASS);
417  object_insert_map(new_wall, the_map, new_wall, INS_NO_MERGE | INS_NO_WALK_ON);
418  }
419 
420  return new_wall;
421 }
void object_destroy(object *ob)
Definition: object.c:1441
#define EXIT
Definition: define.h:312
int blocked(object *op, mapstruct *m, int x, int y, int terrain)
Definition: map.c:598
struct obj * above
Definition: object.h:120
#define QUERY_FLAG(xyz, p)
Definition: define.h:761
struct archetype * arch
Definition: object.h:225
void object_remove(object *op, int flags)
Definition: object.c:1623
void make_map_walls(mapstruct *map, char **layout, char *w_style, RMParms *RP)
Definition: wall.c:193
int16_t y
Definition: object.h:276
int surround_flag3(mapstruct *map, int i, int j, RMParms *RP)
Definition: wall.c:119
Definition: arch.h:40
struct mapdef * map
Definition: object.h:139
mapstruct * find_style(const char *dirname, const char *stylename, int difficulty)
Definition: style.c:169
object * pick_joined_wall(object *the_wall, char **layout, int i, int j, RMParms *RP)
Definition: wall.c:254
#define SET_FLAG(xyz, p)
Definition: define.h:741
int surround_flag2(char **layout, int i, int j, RMParms *RP)
Definition: wall.c:80
object * arch_to_object(archetype_t *at)
Definition: arch.c:446
#define INS_NO_WALK_ON
Definition: object.h:570
object * pick_random_object(mapstruct *style)
Definition: style.c:286
int16_t x
Definition: object.h:273
int Ysize
Definition: random_map.h:77
object * object_insert_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1741
int Xsize
Definition: random_map.h:74
char wall_name[RM_SIZE]
Definition: random_map.h:41
#define INS_NO_MERGE
Definition: object.h:564
int wall_blocked(mapstruct *m, int x, int y)
Definition: map.c:2479
uint8_t type
Definition: object.h:360
int surround_flag(char **layout, int i, int j, RMParms *RP)
Definition: wall.c:45
shstr * name
More definite name, like "kobold".
Definition: arch.h:46
int surround_flag4(mapstruct *map, int i, int j, RMParms *RP)
Definition: wall.c:158
#define DOOR
Definition: define.h:194
#define FLAG_NO_PASS
Definition: define.h:908
object * retrofit_joined_wall(mapstruct *the_map, int i, int j, int insert_flag, RMParms *RP)
Definition: wall.c:333
Definition: map.h:536
#define TERRAIN_ALL
Definition: define.h:692
archetype_t * arch_find(const char *name)
Definition: arch.c:407