Atrinik Server  4.0
construction.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 #include <player.h>
33 #include <object.h>
34 
48 static int can_build_over(mapstruct *m, object *new_item, int x, int y)
49 {
50  object *tmp;
51 
52  for (tmp = GET_MAP_OB(m, x, y); tmp; tmp = tmp->above) {
53  tmp = HEAD(tmp);
54 
56  continue;
57  }
58 
59  switch (new_item->type) {
60  case SIGN:
61 
62  /* Allow signs to be built on books. */
63  if (tmp->type != BOOK) {
64  return 0;
65  }
66 
67  break;
68 
69  default:
70  return 0;
71  }
72  }
73 
74  /* If item being built is multi-tile, need to check other parts too. */
75  if (new_item->more) {
76  return can_build_over(m, new_item->more, x + new_item->more->arch->clone.x - new_item->arch->clone.x, y + new_item->more->arch->clone.y - new_item->arch->clone.y);
77  }
78 
79  return 1;
80 }
81 
93 static object *get_wall(mapstruct *m, int x, int y)
94 {
95  object *tmp;
96 
97  for (tmp = GET_MAP_OB_LAYER(m, x, y, LAYER_WALL, 0); tmp && tmp->layer == LAYER_WALL; tmp = tmp->above) {
98  if (tmp->type == WALL) {
99  return tmp;
100  }
101  }
102 
103  return NULL;
104 }
105 
119 static int builder_floor(object *op, object *new_floor, int x, int y)
120 {
121  object *tmp;
122  FOR_MAP_LAYER_BEGIN(op->map, x, y, LAYER_FLOOR, -1, tmp) {
123  if (tmp->type != FLOOR && !QUERY_FLAG(tmp, FLAG_IS_FLOOR)) {
124  continue;
125  }
126 
127  if (tmp->arch == new_floor->arch) {
128  draw_info(COLOR_WHITE, op,
129  "You feel too lazy to redo the exact same floor.");
130  return 0;
131  }
132 
133  if (QUERY_FLAG(tmp, FLAG_UNIQUE)) {
134  SET_FLAG(new_floor, FLAG_UNIQUE);
135  }
136 
137  object_remove(tmp, 0);
138  object_destroy(tmp);
140 
141  SET_FLAG(new_floor, FLAG_IS_FLOOR);
142  new_floor->type = FLOOR;
143  new_floor->x = x;
144  new_floor->y = y;
145  object_insert_map(new_floor, op->map, NULL, 0);
146  draw_info(COLOR_WHITE, op, "You change the floor to better suit your tastes.");
147 
148  return 1;
149 }
150 
164 static int builder_item(object *op, object *new_item, int x, int y)
165 {
166  object *floor_ob;
167  int w = wall_blocked(op->map, x, y);
168 
169  /* If it's not a wallmask, don't allow building on top of blocked squares.
170  * */
171  if (new_item->type != WALL && w) {
172  char *name = object_get_name_s(new_item, op);
173  draw_info_format(COLOR_WHITE, op, "Something is blocking you from "
174  "building the %s on that square.", name);
175  efree(name);
176  return 0;
177  } else if (new_item->type == WALL) {
178  object *wall_ob = get_wall(op->map, x, y);
179 
180  /* Wallmask, only allow building on top of blocked square that only
181  * contains a wall. */
182 
183  if (!w || !wall_ob) {
184  char *name = object_get_name_s(new_item, op);
185  draw_info_format(COLOR_WHITE, op, "The %s can only be built on "
186  "top of a wall.", name);
187  efree(name);
188  return 0;
189  } else if (wall_ob->above && wall_ob->above->type == WALL) {
190  char *name = object_get_name_s(wall_ob->above, op);
191  draw_info_format(COLOR_WHITE, op, "You first need to remove the %s "
192  "before building on top of that wall again.", name);
193  efree(name);
194  return 0;
195  }
196  }
197 
198  /* Only allow building if there is a floor. */
199  for (floor_ob = GET_MAP_OB_LAYER(op->map, x, y, LAYER_FLOOR, 0); floor_ob && floor_ob->layer == LAYER_FLOOR; floor_ob = floor_ob->above) {
200  if (floor_ob->type == FLOOR || QUERY_FLAG(floor_ob, FLAG_IS_FLOOR)) {
201  break;
202  }
203  }
204 
205  if (!floor_ob) {
206  draw_info(COLOR_WHITE, op, "This square has no floor, you can't build here.");
207  return 0;
208  }
209 
210  /* For signs, take the msg from a book on the square. */
211  if (new_item->type == SIGN) {
212  object *book;
213 
214  for (book = GET_MAP_OB(op->map, x, y); book; book = book->above) {
215  if (book->type == BOOK) {
216  break;
217  }
218  }
219 
220  if (!book || (!book->msg && !book->custom_name)) {
221  draw_info(COLOR_WHITE, op, "You need to put a book with your message (or custom name) on the floor.");
222  return 0;
223  }
224 
225  /* If the book has a custom name, copy it to the sign's name. */
226  if (book->custom_name) {
227  FREE_AND_COPY_HASH(new_item->name, book->custom_name);
228  }
229 
230  /* Copy the message. */
231  if (book->msg) {
232  FREE_AND_COPY_HASH(new_item->msg, book->msg);
233  }
234 
235  object_remove(book, 0);
236  object_destroy(book);
237  }
238 
239  /* If the item is turnable, adjust direction. */
240  if (QUERY_FLAG(new_item, FLAG_IS_TURNABLE) && op->direction) {
241  new_item->direction = op->direction;
242  SET_ANIMATION(new_item, (NUM_ANIMATIONS(new_item) / NUM_FACINGS(new_item)) * new_item->direction);
243  }
244 
245  SET_FLAG(new_item, FLAG_NO_PICK);
246  new_item->x = x;
247  new_item->y = y;
248  object_insert_map(new_item, op->map, NULL, 0);
249  char *name = object_get_name_s(new_item, op);
250  draw_info_format(COLOR_WHITE, op, "You build the %s.", name);
251  efree(name);
252 
253  return 1;
254 }
255 
271 static int wall_split_orientation(const object *wall_ob, char *wall_name, size_t wall_name_size, char *orientation, size_t orientation_size)
272 {
273  int l;
274 
275  strncpy(wall_name, wall_ob->arch->name, wall_name_size - 1);
276 
277  /* Extract the wall name, which is the text up to the last '_'. */
278  for (l = wall_name_size; l >= 0; l--) {
279  if (wall_name[l] == '_') {
280  /* Copy over orientation. */
281  strncpy(orientation, wall_name + l, orientation_size - 1);
282  wall_name[l] = '\0';
283  return 1;
284  }
285  }
286 
287  return 0;
288 }
289 
302 static void fix_walls(mapstruct *map, int x, int y)
303 {
304  int connect_val;
305  object *wall_ob;
306  char wall_name[MAX_BUF], orientation[MAX_BUF];
307  uint32_t old_flags[NUM_FLAGS_32];
308  archetype_t *new_arch;
309  int flag;
310 
311  /* First, find the wall on that spot */
312  wall_ob = get_wall(map, x, y);
313 
314  if (!wall_ob || !wall_split_orientation(wall_ob, wall_name, sizeof(wall_name), orientation, sizeof(orientation))) {
315  return;
316  }
317 
318  connect_val = 0;
319 
320  if (x > 0 && get_wall(map, x - 1, y)) {
321  connect_val |= 1;
322  }
323 
324  if (x < MAP_WIDTH(map) - 1 && get_wall(map, x + 1, y)) {
325  connect_val |= 2;
326  }
327 
328  if (y > 0 && get_wall(map, x, y - 1)) {
329  connect_val |= 4;
330  }
331 
332  if (y < MAP_HEIGHT(map) - 1 && get_wall(map, x, y + 1)) {
333  connect_val |= 8;
334  }
335 
336  switch (connect_val) {
337  case 0:
338  return;
339 
340  case 10:
341  case 8:
342  case 2:
343  strncat(wall_name, "_8", sizeof(wall_name) - strlen(wall_name) - 1);
344  break;
345 
346  case 11:
347  case 9:
348  case 3:
349  case 1:
350  strncat(wall_name, "_1", sizeof(wall_name) - strlen(wall_name) - 1);
351  break;
352 
353  case 12:
354  case 4:
355  case 14:
356  case 6:
357  strncat(wall_name, "_3", sizeof(wall_name) - strlen(wall_name) - 1);
358  break;
359 
360  case 5:
361  case 7:
362  case 13:
363  case 15:
364  strncat(wall_name, "_4", sizeof(wall_name) - strlen(wall_name) - 1);
365  break;
366  }
367 
368  /* No need to change anything if the old and new names are identical. */
369  if (!strncmp(wall_name, wall_ob->arch->name, sizeof(wall_name))) {
370  return;
371  }
372 
373  /* Before anything, make sure the archetype does in fact exist... */
374  new_arch = arch_find(wall_name);
375 
376  if (!new_arch) {
377  return;
378  }
379 
380  /* Now delete current wall, and insert new one
381  * We save flags to avoid any trouble with buildable/non buildable, etc. */
382  for (flag = 0; flag < NUM_FLAGS_32; flag++) {
383  old_flags[flag] = wall_ob->flags[flag];
384  }
385 
386  object_remove(wall_ob, 0);
387  object_destroy(wall_ob);
388 
389  wall_ob = arch_to_object(new_arch);
390  wall_ob->type = WALL;
391  wall_ob->x = x;
392  wall_ob->y = y;
393  object_insert_map(wall_ob, map, NULL, 0);
394 
395  for (flag = 0; flag < NUM_FLAGS_32; flag++) {
396  wall_ob->flags[flag] = old_flags[flag];
397  }
398 }
399 
413 static int builder_wall(object *op, object *new_wall, int x, int y)
414 {
415  object *wall_ob = get_wall(op->map, x, y);
416 
417  if (wall_ob) {
418  char wall_name[MAX_BUF], orientation[MAX_BUF];
419 
420  if (!wall_split_orientation(wall_ob, wall_name, sizeof(wall_name), orientation, sizeof(orientation))) {
421  draw_info(COLOR_WHITE, op, "You don't see a way to redecorate that wall.");
422  return 0;
423  }
424 
425  if (!strncmp(wall_ob->arch->name, wall_name, strlen(wall_name))) {
426  draw_info(COLOR_WHITE, op, "You feel too lazy to redo the exact same wall.");
427  return 0;
428  }
429  }
430 
431  new_wall->type = WALL;
432 
433  /* If existing wall, replace it, no need to fix other walls */
434  if (wall_ob) {
435  object_remove(wall_ob, 0);
436  object_destroy(wall_ob);
437  new_wall->x = x;
438  new_wall->y = y;
439  object_insert_map(new_wall, op->map, NULL, 0);
440  fix_walls(op->map, x, y);
441  draw_info(COLOR_WHITE, op, "You redecorate the wall to better suit your tastes.");
442  } else {
443  int xt, yt;
444 
445  /* Else insert new wall and fix all walls around */
446 
447  new_wall->x = x;
448  new_wall->y = y;
449  object_insert_map(new_wall, op->map, NULL, 0);
450 
451  for (xt = x - 1; xt < x + 1 + 1; xt++) {
452  for (yt = y - 1; yt < y + 1 + 1; yt++) {
453  if (OUT_OF_MAP(op->map, xt, yt)) {
454  continue;
455  }
456 
457  fix_walls(op->map, xt, yt);
458  }
459  }
460 
461  draw_info(COLOR_WHITE, op, "You build a wall.");
462  }
463 
464  return 1;
465 }
466 
478 static int builder_window(object *op, int x, int y)
479 {
480  object *wall_ob;
481  char wall_name[MAX_BUF], orientation[MAX_BUF];
482  archetype_t *new_arch;
483  object *window;
484  uint32_t old_flags[NUM_FLAGS_32];
485  int flag;
486 
487  wall_ob = get_wall(op->map, x, y);
488 
489  if (!wall_ob) {
490  draw_info(COLOR_WHITE, op, "There is no wall there.");
491  return 0;
492  }
493 
494  if (!wall_split_orientation(wall_ob, wall_name, sizeof(wall_name), orientation, sizeof(orientation))) {
495  draw_info(COLOR_WHITE, op, "You don't see a way to build a window in that wall.");
496  return 0;
497  } else if (strcmp(orientation, "_1") != 0 &&
498  strcmp(orientation, "_3") != 0) {
499  draw_info(COLOR_WHITE, op, "You cannot build a window in that wall.");
500  return 0;
501  }
502 
503  strncat(wall_name, "_w", sizeof(wall_name) - strlen(wall_name) - 1);
504  strncat(wall_name, orientation, sizeof(wall_name) - strlen(wall_name) - 1);
505 
506  new_arch = arch_find(wall_name);
507 
508  /* That type of wall doesn't have corresponding window archetype. */
509  if (!new_arch) {
510  draw_info(COLOR_WHITE, op, "You cannot build a window in that wall.");
511  return 0;
512  }
513 
514  /* Now delete current wall, and insert new one with a window.
515  * We save flags to avoid any trouble with buildable/non buildable, etc. */
516  for (flag = 0; flag < NUM_FLAGS_32; flag++) {
517  old_flags[flag] = wall_ob->flags[flag];
518  }
519 
520  object_remove(wall_ob, 0);
521  object_destroy(wall_ob);
522 
523  window = arch_to_object(new_arch);
524  window->type = WALL;
525  window->x = x;
526  window->y = y;
527  object_insert_map(window, op->map, NULL, 0);
528 
529  for (flag = 0; flag < NUM_FLAGS_32; flag++) {
530  window->flags[flag] = old_flags[flag];
531  }
532 
533  CLEAR_FLAG(window, FLAG_BLOCKSVIEW);
534  draw_info(COLOR_WHITE, op, "You build a window in the wall.");
535  return 1;
536 }
537 
547 static void construction_builder(object *op, int x, int y)
548 {
549  object *material, *new_item;
550  archetype_t *new_arch;
551  int built = 0;
552 
553  material = find_marked_object(op);
554 
555  if (!material) {
556  draw_info(COLOR_WHITE, op, "You need to mark raw materials to use.");
557  return;
558  }
559 
560  if (material->type != MATERIAL) {
561  draw_info(COLOR_WHITE, op, "You can't use the marked item to build.");
562  return;
563  }
564 
565  /* Create a new object from the raw materials. */
566  new_arch = arch_find(material->slaying);
567 
568  if (!new_arch) {
569  LOG(BUG, "Unable to find archetype %s.", material->slaying);
570  draw_info(COLOR_WHITE, op, "You can't use this strange material.");
571  return;
572  }
573 
574  new_item = arch_to_object(new_arch);
575  SET_FLAG(new_item, FLAG_IS_BUILDABLE);
576 
577  if (!can_build_over(op->map, new_item, x, y)) {
578  draw_info(COLOR_WHITE, op, "You can't build there.");
579  object_destroy(new_item);
580  return;
581  }
582 
583  /* Insert the new object in the map. */
584  switch (material->sub_type) {
585  case ST_MAT_FLOOR:
586  built = builder_floor(op, new_item, x, y);
587  break;
588 
589  case ST_MAT_WALL:
590  built = builder_wall(op, new_item, x, y);
591  break;
592 
593  case ST_MAT_ITEM:
594  built = builder_item(op, new_item, x, y);
595  break;
596 
597  case ST_MAT_WIN:
598  built = builder_window(op, x, y);
599  object_destroy(new_item);
600  break;
601 
602  default:
603  LOG(BUG, "Invalid material subtype %d.", material->sub_type);
604  draw_info(COLOR_WHITE, op, "Don't know how to apply this material, sorry.");
605  break;
606  }
607 
608  if (built) {
609  decrease_ob(material);
610  living_update(op);
611  }
612 }
613 
625 static void construction_destroyer(object *op, int x, int y)
626 {
627  object *item;
628 
629  for (item = GET_MAP_OB_LAST(op->map, x, y); item; item = item->below) {
630  if (QUERY_FLAG(item, FLAG_SYS_OBJECT)) {
631  continue;
632  }
633 
634  if (item->type != FLOOR && QUERY_FLAG(item, FLAG_IS_BUILDABLE)) {
635  break;
636  }
637  }
638 
639  if (!item) {
640  draw_info(COLOR_WHITE, op, "Nothing to remove.");
641  return;
642  }
643 
644  /* Do not allow destroying containers with inventory. */
645  if (item->type == CONTAINER && item->inv) {
646  char *name = object_get_name_s(item, op);
647  draw_info_format(COLOR_WHITE, op, "You cannot remove the %s, since it "
648  "contains items.", name);
649  efree(name);
650  return;
651  }
652 
653  object_remove(item, 0);
654 
655  /* Fix walls around the one that was removed. */
656  if (item->type == WALL) {
657  int xt, yt;
658 
659  for (xt = x - 1; xt < x + 1 + 1; xt++) {
660  for (yt = y - 1; yt < y + 1 + 1; yt++) {
661  if (!OUT_OF_MAP(op->map, xt, yt)) {
662  fix_walls(op->map, xt, yt);
663  }
664  }
665  }
666  }
667 
668  char *name = object_get_name_s(item, op);
669  draw_info_format(COLOR_WHITE, op, "You remove the %s.", name);
670  efree(name);
671 
672  object_destroy(item);
673 }
674 
681 void construction_do(object *op, int dir)
682 {
683  object *skill_item, *floor_ob, *tmp;
684  int x, y;
685 
686  if (op->type != PLAYER) {
687  return;
688  }
689 
690  skill_item = CONTR(op)->equipment[PLAYER_EQUIP_SKILL_ITEM];
691 
692  if (!skill_item) {
693  draw_info(COLOR_WHITE, op, "You need to apply a skill item to use this skill.");
694  return;
695  }
696 
697  if (skill_item->stats.sp != SK_CONSTRUCTION) {
698  char *name = object_get_name_s(skill_item, op);
699  draw_info_format(COLOR_WHITE, op, "The %s cannot be used with the "
700  "construction skill.", name);
701  efree(name);
702  return;
703  }
704 
705  if (!dir) {
706  draw_info(COLOR_WHITE, op, "You can't build or destroy under yourself.");
707  return;
708  }
709 
710  x = op->x + freearr_x[dir];
711  y = op->y + freearr_y[dir];
712 
713  if ((1 > x) || (1 > y) || ((MAP_WIDTH(op->map) - 2) < x) || ((MAP_HEIGHT(op->map) - 2) < y)) {
714  draw_info(COLOR_WHITE, op, "Can't build on map edge.");
715  return;
716  }
717 
718  /* Check specified square
719  * The square must have only buildable items. */
720  floor_ob = GET_MAP_OB(op->map, x, y);
721 
722  if (!floor_ob) {
723  LOG(BUG, "Undefined square on map %s (%d, %d)", op->map->path, x, y);
724  draw_info(COLOR_WHITE, op, "You'd better not build here, it looks weird.");
725  return;
726  }
727 
728  if (skill_item->sub_type != ST_BD_BUILD) {
729  for (tmp = floor_ob; tmp; tmp = tmp->above) {
730  if (QUERY_FLAG(tmp, FLAG_SYS_OBJECT)) {
731  continue;
732  }
733 
734  if (!QUERY_FLAG(tmp, FLAG_IS_BUILDABLE)) {
735  draw_info(COLOR_WHITE, op, "You can't build there.");
736  return;
737  }
738  }
739  }
740 
741  /* Prevent players without destroyer from getting themselves stuck. */
742  if (skill_item->sub_type != ST_BD_REMOVE) {
743  int found_destroyer = 0;
744 
745  for (tmp = op->inv; tmp; tmp = tmp->below) {
746  if (tmp->type == SKILL_ITEM && tmp->sub_type == ST_BD_REMOVE) {
747  found_destroyer = 1;
748  break;
749  }
750  }
751 
752  if (!found_destroyer) {
753  draw_info(COLOR_WHITE, op, "You cannot build without having a destroyer at hand.");
754  return;
755  }
756  }
757 
758  switch (skill_item->sub_type) {
759  case ST_BD_REMOVE:
760  construction_destroyer(op, x, y);
761  break;
762 
763  case ST_BD_BUILD:
764  construction_builder(op, x, y);
765  break;
766 
767  default:
768  LOG(ERROR, "Skill item %s has invalid subtype.",
769  object_get_str(skill_item));
770  draw_info(COLOR_WHITE, op, "Don't know how to apply this tool, sorry.");
771  break;
772  }
773 }
#define FREE_AND_COPY_HASH(_sv_, _nv_)
Definition: global.h:100
void object_destroy(object *ob)
Definition: object.c:1441
#define FLAG_SYS_OBJECT
Definition: define.h:1243
#define BOOK
Definition: define.h:150
#define NUM_FACINGS(ob)
Definition: global.h:300
#define FLAG_UNIQUE
Definition: define.h:1066
#define MAP_WIDTH(m)
Definition: map.h:120
shstr * path
Definition: map.h:568
#define SET_ANIMATION(ob, newanim)
Definition: global.h:282
static int can_build_over(mapstruct *m, object *new_item, int x, int y)
Definition: construction.c:48
const char * slaying
Definition: object.h:180
#define LAYER_FLOOR
Definition: map.h:49
uint8_t layer
Definition: object.h:405
struct obj * above
Definition: object.h:120
#define OUT_OF_MAP(M, X, Y)
Definition: map.h:240
#define PLAYER
Definition: define.h:122
int16_t sp
Definition: living.h:78
#define FLAG_IS_TURNABLE
Definition: define.h:960
#define FLAG_IS_FLOOR
Definition: define.h:1118
#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
#define WALL
Definition: define.h:340
uint32_t flags[NUM_FLAGS_32]
Definition: object.h:270
char * object_get_name_s(const object *op, const object *caller)
Definition: item.c:398
#define ST_MAT_ITEM
Definition: define.h:614
#define decrease_ob(xyz)
Definition: object.h:624
static int builder_window(object *op, int x, int y)
Definition: construction.c:478
int16_t y
Definition: object.h:276
const char * object_get_str(const object *op)
Definition: object.c:3151
int8_t direction
Definition: object.h:350
Definition: arch.h:40
#define ST_MAT_FLOOR
Definition: define.h:610
#define FLAG_NO_PICK
Definition: define.h:900
struct mapdef * map
Definition: object.h:139
void construction_do(object *op, int dir)
Definition: construction.c:681
const char * name
Definition: object.h:168
#define SET_FLAG(xyz, p)
Definition: define.h:741
object * arch_to_object(archetype_t *at)
Definition: arch.c:446
struct obj * below
Definition: object.h:114
#define CONTAINER
Definition: define.h:493
#define MAP_HEIGHT(m)
Definition: map.h:122
static void construction_destroyer(object *op, int x, int y)
Definition: construction.c:625
#define FOR_MAP_LAYER_END
Definition: define.h:1657
#define FLAG_IS_BUILDABLE
Definition: define.h:1162
#define SIGN
Definition: define.h:409
#define HEAD(op)
Definition: object.h:657
#define ST_BD_REMOVE
Definition: define.h:600
#define ST_BD_BUILD
Definition: define.h:602
int16_t x
Definition: object.h:273
static object * get_wall(mapstruct *m, int x, int y)
Definition: construction.c:93
static int builder_floor(object *op, object *new_floor, int x, int y)
Definition: construction.c:119
#define FOR_MAP_LAYER_BEGIN(_m, _x, _y, _layer, _sub_layer, _obj)
Definition: define.h:1630
static int wall_split_orientation(const object *wall_ob, char *wall_name, size_t wall_name_size, char *orientation, size_t orientation_size)
Definition: construction.c:271
object * object_insert_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1741
static void construction_builder(object *op, int x, int y)
Definition: construction.c:547
#define FLAG_BLOCKSVIEW
Definition: define.h:1008
#define MATERIAL
Definition: define.h:158
#define FLOOR
Definition: define.h:324
#define NUM_ANIMATIONS(ob)
Definition: global.h:298
living stats
Definition: object.h:481
#define NUM_FLAGS_32
Definition: define.h:1349
int wall_blocked(mapstruct *m, int x, int y)
Definition: map.c:2479
int freearr_x[SIZEOFFREE]
Definition: object.c:84
uint8_t type
Definition: object.h:360
#define CLEAR_FLAG(xyz, p)
Definition: define.h:751
shstr * name
More definite name, like "kobold".
Definition: arch.h:46
const char * msg
Definition: object.h:183
int living_update(object *op)
Definition: living.c:1661
#define ST_MAT_WIN
Definition: define.h:616
struct obj * inv
Definition: object.h:123
shstr * custom_name
Definition: object.h:190
static void fix_walls(mapstruct *map, int x, int y)
Definition: construction.c:302
Definition: map.h:536
int freearr_y[SIZEOFFREE]
Definition: object.c:99
#define ST_MAT_WALL
Definition: define.h:612
struct obj * more
Definition: object.h:133
static int builder_wall(object *op, object *new_wall, int x, int y)
Definition: construction.c:413
object clone
An object from which to do object_copy().
Definition: arch.h:47
archetype_t * arch_find(const char *name)
Definition: arch.c:407
#define LAYER_WALL
Definition: map.h:57
#define SKILL_ITEM
Definition: define.h:271
object * find_marked_object(object *op)
Definition: player.c:1393
uint8_t sub_type
Definition: object.h:363
static int builder_item(object *op, object *new_item, int x, int y)
Definition: construction.c:164