1  /**
2  * \file cave-square.c
3  * \brief functions for dealing with individual squares
4  *
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 
19 #include "angband.h"
20 #include "cave.h"
21 #include "game-world.h"
22 #include "init.h"
23 #include "monster.h"
24 #include "obj-knowledge.h"
25 #include "obj-pile.h"
26 #include "obj-util.h"
27 #include "object.h"
28 #include "player-timed.h"
29 #include "trap.h"
30 
31 
32 /**
33  * FEATURE PREDICATES
34  *
35  * These functions test a terrain feature index for the obviously described
36  * type.  They are used in the square feature predicates below, and
37  * occasionally on their own
38  */
39 
40 /**
41  * True if the square is a magma wall.
42  */
feat_is_magma(int feat)43 bool feat_is_magma(int feat)
44 {
45 	return tf_has(f_info[feat].flags, TF_MAGMA);
46 }
47 
48 /**
49  * True if the square is a quartz wall.
50  */
feat_is_quartz(int feat)51 bool feat_is_quartz(int feat)
52 {
53 	return tf_has(f_info[feat].flags, TF_QUARTZ);
54 }
55 
56 /**
57  * True if the square is a granite wall.
58  */
feat_is_granite(int feat)59 bool feat_is_granite(int feat)
60 {
61 	return tf_has(f_info[feat].flags, TF_GRANITE);
62 }
63 
64 /**
65  * True if the square is a mineral wall with treasure (magma/quartz).
66  */
feat_is_treasure(int feat)67 bool feat_is_treasure(int feat)
68 {
69 	return (tf_has(f_info[feat].flags, TF_GOLD));
70 }
71 
72 /**
73  * True if the feature is a solid wall (not rubble).
74  */
feat_is_wall(int feat)75 bool feat_is_wall(int feat)
76 {
77 	return tf_has(f_info[feat].flags, TF_WALL);
78 }
79 
80 /**
81  * True if the feature is a floor.
82  */
feat_is_floor(int feat)83 bool feat_is_floor(int feat)
84 {
85 	return tf_has(f_info[feat].flags, TF_FLOOR);
86 }
87 
88 /**
89  * True if the feature can hold a trap.
90  */
feat_is_trap_holding(int feat)91 bool feat_is_trap_holding(int feat)
92 {
93 	return tf_has(f_info[feat].flags, TF_TRAP);
94 }
95 
96 /**
97  * True if the feature can hold an object.
98  */
feat_is_object_holding(int feat)99 bool feat_is_object_holding(int feat)
100 {
101 	return tf_has(f_info[feat].flags, TF_OBJECT);
102 }
103 
104 /**
105  * True if a monster can walk through the feature.
106  */
feat_is_monster_walkable(int feat)107 bool feat_is_monster_walkable(int feat)
108 {
109 	return tf_has(f_info[feat].flags, TF_PASSABLE);
110 }
111 
112 /**
113  * True if the feature is a shop entrance.
114  */
feat_is_shop(int feat)115 bool feat_is_shop(int feat)
116 {
117 	return tf_has(f_info[feat].flags, TF_SHOP);
118 }
119 
120 /**
121  * True if the feature is passable by the player.
122  */
feat_is_passable(int feat)123 bool feat_is_passable(int feat)
124 {
125 	return tf_has(f_info[feat].flags, TF_PASSABLE);
126 }
127 
128 /**
129  * True if any projectable can pass through the feature.
130  */
feat_is_projectable(int feat)131 bool feat_is_projectable(int feat)
132 {
133 	return tf_has(f_info[feat].flags, TF_PROJECT);
134 }
135 
136 /**
137  * True if the feature can be lit by light sources.
138  */
feat_is_torch(int feat)139 bool feat_is_torch(int feat)
140 {
141 	return tf_has(f_info[feat].flags, TF_TORCH);
142 }
143 
144 /**
145  * True if the feature is internally lit.
146  */
feat_is_bright(int feat)147 bool feat_is_bright(int feat)
148 {
149 	return tf_has(f_info[feat].flags, TF_BRIGHT);
150 }
151 
152 /**
153  * True if the feature is internally lit.
154  */
feat_is_fiery(int feat)155 bool feat_is_fiery(int feat)
156 {
157 	return tf_has(f_info[feat].flags, TF_FIERY);
158 }
159 
160 /**
161  * True if the feature doesn't carry monster flow information.
162  */
feat_is_no_flow(int feat)163 bool feat_is_no_flow(int feat)
164 {
165 	return tf_has(f_info[feat].flags, TF_NO_FLOW);
166 }
167 
168 /**
169  * True if the feature doesn't carry player scent.
170  */
feat_is_no_scent(int feat)171 bool feat_is_no_scent(int feat)
172 {
173 	return tf_has(f_info[feat].flags, TF_NO_SCENT);
174 }
175 
176 /**
177  * True if the feature should have smooth boundaries (for dungeon generation).
178  */
feat_is_smooth(int feat)179 bool feat_is_smooth(int feat)
180 {
181 	return tf_has(f_info[feat].flags, TF_SMOOTH);
182 }
183 
184 /**
185  * SQUARE FEATURE PREDICATES
186  *
187  * These functions are used to figure out what kind of square something is,
188  * via c->squares[y][x].feat (preferably accessed via square(c, grid)).
189  * All direct testing of square(c, grid)->feat should be rewritten
190  * in terms of these functions.
191  *
192  * It's often better to use square behavior predicates (written in terms of
193  * these functions) instead of these functions directly. For instance,
194  * square_isrock() will return false for a secret door, even though it will
195  * behave like a rock wall until the player determines it's a door.
196  *
197  * Use functions like square_isdiggable, square_iswall, etc. in these cases.
198  */
199 
200 /**
201  * True if the square is normal open floor.
202  */
square_isfloor(struct chunk * c,struct loc grid)203 bool square_isfloor(struct chunk *c, struct loc grid)
204 {
205 	return feat_is_floor(square(c, grid)->feat);
206 }
207 
208 /**
209  * True if the square can hold a trap.
210  */
square_istrappable(struct chunk * c,struct loc grid)211 bool square_istrappable(struct chunk *c, struct loc grid)
212 {
213 	return feat_is_trap_holding(square(c, grid)->feat);
214 }
215 
216 /**
217  * True if the square can hold an object.
218  */
square_isobjectholding(struct chunk * c,struct loc grid)219 bool square_isobjectholding(struct chunk *c, struct loc grid)
220 {
221 	return feat_is_object_holding(square(c, grid)->feat);
222 }
223 
224 /**
225  * True if the square is a normal granite rock wall.
226  */
square_isrock(struct chunk * c,struct loc grid)227 bool square_isrock(struct chunk *c, struct loc grid)
228 {
229 	return (tf_has(f_info[square(c, grid)->feat].flags, TF_GRANITE) &&
230 			!tf_has(f_info[square(c, grid)->feat].flags, TF_DOOR_ANY));
231 }
232 
233 /**
234  * True if the square is granite.
235  */
square_isgranite(struct chunk * c,struct loc grid)236 bool square_isgranite(struct chunk *c, struct loc grid)
237 {
238 	return feat_is_granite(square(c, grid)->feat);
239 }
240 
241 /**
242  * True if the square is a permanent wall.
243  */
square_isperm(struct chunk * c,struct loc grid)244 bool square_isperm(struct chunk *c, struct loc grid)
245 {
246 	return (tf_has(f_info[square(c, grid)->feat].flags, TF_PERMANENT) &&
247 			tf_has(f_info[square(c, grid)->feat].flags, TF_ROCK));
248 }
249 
250 /**
251  * True if the square is a magma wall.
252  */
square_ismagma(struct chunk * c,struct loc grid)253 bool square_ismagma(struct chunk *c, struct loc grid)
254 {
255 	return feat_is_magma(square(c, grid)->feat);
256 }
257 
258 /**
259  * True if the square is a quartz wall.
260  */
square_isquartz(struct chunk * c,struct loc grid)261 bool square_isquartz(struct chunk *c, struct loc grid)
262 {
263 	return feat_is_quartz(square(c, grid)->feat);
264 }
265 
266 /**
267  * True if the square is a mineral wall (magma/quartz/granite).
268  */
square_ismineral(struct chunk * c,struct loc grid)269 bool square_ismineral(struct chunk *c, struct loc grid)
270 {
271 	return square_isrock(c, grid) || square_ismagma(c, grid) ||
272 		square_isquartz(c, grid);
273 }
274 
square_hasgoldvein(struct chunk * c,struct loc grid)275 bool square_hasgoldvein(struct chunk *c, struct loc grid)
276 {
277 	return tf_has(f_info[square(c, grid)->feat].flags, TF_GOLD);
278 }
279 
280 /**
281  * True if the square is rubble.
282  */
square_isrubble(struct chunk * c,struct loc grid)283 bool square_isrubble(struct chunk *c, struct loc grid)
284 {
285     return (!tf_has(f_info[square(c, grid)->feat].flags, TF_WALL) &&
286 			tf_has(f_info[square(c, grid)->feat].flags, TF_ROCK));
287 }
288 
289 /**
290  * True if the square is a hidden secret door.
291  *
292  * These squares appear as if they were granite--when detected a secret door
293  * is replaced by a closed door.
294  */
square_issecretdoor(struct chunk * c,struct loc grid)295 bool square_issecretdoor(struct chunk *c, struct loc grid)
296 {
297     return (tf_has(f_info[square(c, grid)->feat].flags, TF_DOOR_ANY) &&
298 			tf_has(f_info[square(c, grid)->feat].flags, TF_ROCK));
299 }
300 
301 /**
302  * True if the square is an open door.
303  */
square_isopendoor(struct chunk * c,struct loc grid)304 bool square_isopendoor(struct chunk *c, struct loc grid)
305 {
306     return (tf_has(f_info[square(c, grid)->feat].flags, TF_CLOSABLE));
307 }
308 
309 /**
310  * True if the square is a closed door (possibly locked or jammed).
311  */
square_iscloseddoor(struct chunk * c,struct loc grid)312 bool square_iscloseddoor(struct chunk *c, struct loc grid)
313 {
314 	int feat = square(c, grid)->feat;
315 	return tf_has(f_info[feat].flags, TF_DOOR_CLOSED);
316 }
317 
square_isbrokendoor(struct chunk * c,struct loc grid)318 bool square_isbrokendoor(struct chunk *c, struct loc grid)
319 {
320 	int feat = square(c, grid)->feat;
321     return (tf_has(f_info[feat].flags, TF_DOOR_ANY) &&
322 			tf_has(f_info[feat].flags, TF_PASSABLE) &&
323 			!tf_has(f_info[feat].flags, TF_CLOSABLE));
324 }
325 
326 /**
327  * True if the square is a door.
328  *
329  * This includes open, closed, and hidden doors.
330  */
square_isdoor(struct chunk * c,struct loc grid)331 bool square_isdoor(struct chunk *c, struct loc grid)
332 {
333 	int feat = square(c, grid)->feat;
334 	return tf_has(f_info[feat].flags, TF_DOOR_ANY);
335 }
336 
337 /**
338  * True if square is any stair
339  */
square_isstairs(struct chunk * c,struct loc grid)340 bool square_isstairs(struct chunk *c, struct loc grid)
341 {
342 	int feat = square(c, grid)->feat;
343 	return tf_has(f_info[feat].flags, TF_STAIR);
344 }
345 
346 /**
347  * True if square is an up stair.
348  */
square_isupstairs(struct chunk * c,struct loc grid)349 bool square_isupstairs(struct chunk*c, struct loc grid)
350 {
351 	int feat = square(c, grid)->feat;
352 	return tf_has(f_info[feat].flags, TF_UPSTAIR);
353 }
354 
355 /**
356  * True if square is a down stair.
357  */
square_isdownstairs(struct chunk * c,struct loc grid)358 bool square_isdownstairs(struct chunk *c, struct loc grid)
359 {
360 	int feat = square(c, grid)->feat;
361 	return tf_has(f_info[feat].flags, TF_DOWNSTAIR);
362 }
363 
364 /**
365  * True if the square is a shop entrance.
366  */
square_isshop(struct chunk * c,struct loc grid)367 bool square_isshop(struct chunk *c, struct loc grid)
368 {
369 	return feat_is_shop(square(c, grid)->feat);
370 }
371 
372 /**
373  * True if the square contains the player
374  */
square_isplayer(struct chunk * c,struct loc grid)375 bool square_isplayer(struct chunk *c, struct loc grid) {
376 	return square(c, grid)->mon < 0 ? true : false;
377 }
378 
379 /**
380  * True if the square contains the player or a monster
381  */
square_isoccupied(struct chunk * c,struct loc grid)382 bool square_isoccupied(struct chunk *c, struct loc grid) {
383 	return square(c, grid)->mon != 0 ? true : false;
384 }
385 
386 /**
387  * True if the the player knows the terrain of the square
388  */
square_isknown(struct chunk * c,struct loc grid)389 bool square_isknown(struct chunk *c, struct loc grid) {
390 	if (c != cave) return false;
391 	if (player->cave == NULL) return false;
392 	return square(player->cave, grid)->feat == FEAT_NONE ? false : true;
393 }
394 
395 /**
396  * True if the the player's knowledge of the terrain of the square is wrong
397  * or missing
398  */
square_isnotknown(struct chunk * c,struct loc grid)399 bool square_isnotknown(struct chunk *c, struct loc grid) {
400 	if (c != cave) return false;
401 	if (player->cave == NULL) return true;
402 	return square(player->cave, grid)->feat != square(c, grid)->feat;
403 }
404 
405 /**
406  * SQUARE INFO PREDICATES
407  *
408  * These functions tell whether a square is marked with one of the SQUARE_*
409  * flags.  These flags are mostly used to mark a square with some information
410  * about its location or status.
411  */
412 
413 /**
414  * True if the square is marked
415  */
square_ismark(struct chunk * c,struct loc grid)416 bool square_ismark(struct chunk *c, struct loc grid) {
417 	assert(square_in_bounds(c, grid));
418 	return sqinfo_has(square(c, grid)->info, SQUARE_MARK);
419 }
420 
421 /**
422  * True if the square is lit
423  */
square_isglow(struct chunk * c,struct loc grid)424 bool square_isglow(struct chunk *c, struct loc grid) {
425 	assert(square_in_bounds(c, grid));
426 	return sqinfo_has(square(c, grid)->info, SQUARE_GLOW);
427 }
428 
429 /**
430  * True if the square is part of a vault.
431  *
432  * This doesn't say what kind of square it is, just that it is part of a vault.
433  */
square_isvault(struct chunk * c,struct loc grid)434 bool square_isvault(struct chunk *c, struct loc grid) {
435 	assert(square_in_bounds(c, grid));
436 	return sqinfo_has(square(c, grid)->info, SQUARE_VAULT);
437 }
438 
439 /**
440  * True if the square is part of a room.
441  */
square_isroom(struct chunk * c,struct loc grid)442 bool square_isroom(struct chunk *c, struct loc grid) {
443 	assert(square_in_bounds(c, grid));
444 	return sqinfo_has(square(c, grid)->info, SQUARE_ROOM);
445 }
446 
447 /**
448  * True if the square has been seen by the player
449  */
square_isseen(struct chunk * c,struct loc grid)450 bool square_isseen(struct chunk *c, struct loc grid) {
451 	assert(square_in_bounds(c, grid));
452 	return sqinfo_has(square(c, grid)->info, SQUARE_SEEN);
453 }
454 
455 /**
456  * True if the cave square is currently viewable by the player
457  */
square_isview(struct chunk * c,struct loc grid)458 bool square_isview(struct chunk *c, struct loc grid) {
459 	assert(square_in_bounds(c, grid));
460 	return sqinfo_has(square(c, grid)->info, SQUARE_VIEW);
461 }
462 
463 /**
464  * True if the cave square was seen before the current update
465  */
square_wasseen(struct chunk * c,struct loc grid)466 bool square_wasseen(struct chunk *c, struct loc grid) {
467 	assert(square_in_bounds(c, grid));
468 	return sqinfo_has(square(c, grid)->info, SQUARE_WASSEEN);
469 }
470 
471 /**
472  * True if cave square is a feeling trigger square
473  */
square_isfeel(struct chunk * c,struct loc grid)474 bool square_isfeel(struct chunk *c, struct loc grid) {
475 	assert(square_in_bounds(c, grid));
476 	return sqinfo_has(square(c, grid)->info, SQUARE_FEEL);
477 }
478 
479 /**
480  * True if the square has a known trap
481  */
square_istrap(struct chunk * c,struct loc grid)482 bool square_istrap(struct chunk *c, struct loc grid) {
483 	assert(square_in_bounds(c, grid));
484 	return sqinfo_has(square(c, grid)->info, SQUARE_TRAP);
485 }
486 
487 /**
488  * True if the square has an unknown trap
489  */
square_isinvis(struct chunk * c,struct loc grid)490 bool square_isinvis(struct chunk *c, struct loc grid) {
491 	assert(square_in_bounds(c, grid));
492 	return sqinfo_has(square(c, grid)->info, SQUARE_INVIS);
493 }
494 
495 /**
496  * True if cave square is an inner wall (generation)
497  */
square_iswall_inner(struct chunk * c,struct loc grid)498 bool square_iswall_inner(struct chunk *c, struct loc grid) {
499 	assert(square_in_bounds(c, grid));
500 	return sqinfo_has(square(c, grid)->info, SQUARE_WALL_INNER);
501 }
502 
503 /**
504  * True if cave square is an outer wall (generation)
505  */
square_iswall_outer(struct chunk * c,struct loc grid)506 bool square_iswall_outer(struct chunk *c, struct loc grid) {
507 	assert(square_in_bounds(c, grid));
508 	return sqinfo_has(square(c, grid)->info, SQUARE_WALL_OUTER);
509 }
510 
511 /**
512  * True if cave square is a solid wall (generation)
513  */
square_iswall_solid(struct chunk * c,struct loc grid)514 bool square_iswall_solid(struct chunk *c, struct loc grid) {
515 	assert(square_in_bounds(c, grid));
516 	return sqinfo_has(square(c, grid)->info, SQUARE_WALL_SOLID);
517 }
518 
519 /**
520  * True if cave square has monster restrictions (generation)
521  */
square_ismon_restrict(struct chunk * c,struct loc grid)522 bool square_ismon_restrict(struct chunk *c, struct loc grid) {
523 	assert(square_in_bounds(c, grid));
524 	return sqinfo_has(square(c, grid)->info, SQUARE_MON_RESTRICT);
525 }
526 
527 /**
528  * True if cave square can't be teleported from by the player
529  */
square_isno_teleport(struct chunk * c,struct loc grid)530 bool square_isno_teleport(struct chunk *c, struct loc grid) {
531 	assert(square_in_bounds(c, grid));
532 	return sqinfo_has(square(c, grid)->info, SQUARE_NO_TELEPORT);
533 }
534 
535 /**
536  * True if cave square can't be magically mapped by the player
537  */
square_isno_map(struct chunk * c,struct loc grid)538 bool square_isno_map(struct chunk *c, struct loc grid) {
539 	assert(square_in_bounds(c, grid));
540 	return sqinfo_has(square(c, grid)->info, SQUARE_NO_MAP);
541 }
542 
543 /**
544  * True if cave square can't be detected by player ESP
545  */
square_isno_esp(struct chunk * c,struct loc grid)546 bool square_isno_esp(struct chunk *c, struct loc grid) {
547 	assert(square_in_bounds(c, grid));
548 	return sqinfo_has(square(c, grid)->info, SQUARE_NO_ESP);
549 }
550 
551 /**
552  * True if cave square is marked for projection processing
553  */
square_isproject(struct chunk * c,struct loc grid)554 bool square_isproject(struct chunk *c, struct loc grid) {
555 	assert(square_in_bounds(c, grid));
556 	return sqinfo_has(square(c, grid)->info, SQUARE_PROJECT);
557 }
558 
559 /**
560  * True if cave square has been detected for traps
561  */
square_isdtrap(struct chunk * c,struct loc grid)562 bool square_isdtrap(struct chunk *c, struct loc grid) {
563 	assert(square_in_bounds(c, grid));
564 	return sqinfo_has(square(c, grid)->info, SQUARE_DTRAP);
565 }
566 
567 /**
568  * True if cave square is inappropriate to place stairs
569  */
square_isno_stairs(struct chunk * c,struct loc grid)570 bool square_isno_stairs(struct chunk *c, struct loc grid) {
571 	assert(square_in_bounds(c, grid));
572 	return sqinfo_has(square(c, grid)->info, SQUARE_NO_STAIRS);
573 }
574 
575 
576 /**
577  * SQUARE BEHAVIOR PREDICATES
578  *
579  * These functions define how a given square behaves, e.g. whether it is
580  * passable by the player, whether it is diggable, contains items, etc.
581  *
582  * These functions use the SQUARE FEATURE PREDICATES (among other info) to
583  * make the determination.
584  */
585 
586 /**
587  * True if the square is open (a floor square not occupied by a monster).
588  */
square_isopen(struct chunk * c,struct loc grid)589 bool square_isopen(struct chunk *c, struct loc grid) {
590 	return square_isfloor(c, grid) && !square(c, grid)->mon;
591 }
592 
593 /**
594  * True if the square is empty (an open square without any items).
595  */
square_isempty(struct chunk * c,struct loc grid)596 bool square_isempty(struct chunk *c, struct loc grid) {
597 	if (square_isplayertrap(c, grid)) return false;
598 	if (square_iswebbed(c, grid)) return false;
599 	return square_isopen(c, grid) && !square_object(c, grid);
600 }
601 
602 /**
603  * True if the square is empty (an open square without any items).
604  */
square_isarrivable(struct chunk * c,struct loc grid)605 bool square_isarrivable(struct chunk *c, struct loc grid) {
606 	if (square(c, grid)->mon) return false;
607 	if (square_isplayertrap(c, grid)) return false;
608 	if (square_iswebbed(c, grid)) return false;
609 	if (square_isfloor(c, grid)) return true;
610 	if (square_isstairs(c, grid)) return true;
611 	// maybe allow open doors or suchlike?
612 	return false;
613 }
614 
615 /**
616  * True if the square is an untrapped floor square without items.
617  */
square_canputitem(struct chunk * c,struct loc grid)618 bool square_canputitem(struct chunk *c, struct loc grid) {
619 	if (!square_isobjectholding(c, grid)) return false;
620 	if (square_istrap(c, grid)) return false;
621 	return !square_object(c, grid);
622 }
623 
624 /**
625  * True if the square can be dug: this includes rubble and non-permanent walls.
626  */
square_isdiggable(struct chunk * c,struct loc grid)627 bool square_isdiggable(struct chunk *c, struct loc grid) {
628 	return (square_ismineral(c, grid) ||
629 			square_issecretdoor(c, grid) ||
630 			square_isrubble(c, grid));
631 }
632 
633 /**
634  * True if the square is a floor with no traps.
635  */
square_iswebbable(struct chunk * c,struct loc grid)636 bool square_iswebbable(struct chunk *c, struct loc grid) {
637 	if (square_trap(c, grid)) return false;
638 	return square_isfloor(c, grid);
639 }
640 
641 /**
642  * True if a monster can walk through the tile.
643  *
644  * This is needed for polymorphing. A monster may be on a feature that isn't
645  * an empty space, causing problems when it is replaced with a new monster.
646  */
square_is_monster_walkable(struct chunk * c,struct loc grid)647 bool square_is_monster_walkable(struct chunk *c, struct loc grid)
648 {
649 	assert(square_in_bounds(c, grid));
650 	return feat_is_monster_walkable(square(c, grid)->feat);
651 }
652 
653 /**
654  * True if the square is passable by the player.
655  */
square_ispassable(struct chunk * c,struct loc grid)656 bool square_ispassable(struct chunk *c, struct loc grid) {
657 	assert(square_in_bounds(c, grid));
658 	return feat_is_passable(square(c, grid)->feat);
659 }
660 
661 /**
662  * True if any projectable can pass through the square.
663  *
664  * This function is the logical negation of square_iswall().
665  */
square_isprojectable(struct chunk * c,struct loc grid)666 bool square_isprojectable(struct chunk *c, struct loc grid) {
667 	if (!square_in_bounds(c, grid)) return false;
668 	return feat_is_projectable(square(c, grid)->feat);
669 }
670 
671 /**
672  * True if the square is a wall square (impedes the player).
673  *
674  * This function is the logical negation of square_isprojectable().
675  */
square_iswall(struct chunk * c,struct loc grid)676 bool square_iswall(struct chunk *c, struct loc grid) {
677 	assert(square_in_bounds(c, grid));
678 	return !square_isprojectable(c, grid);
679 }
680 
681 /**
682  * True if the square is a permanent wall or one of the "stronger" walls.
683  *
684  * The stronger walls are granite, magma and quartz. This excludes things like
685  * secret doors and rubble.
686  */
square_isstrongwall(struct chunk * c,struct loc grid)687 bool square_isstrongwall(struct chunk *c, struct loc grid) {
688 	assert(square_in_bounds(c, grid));
689 	return square_ismineral(c, grid) || square_isperm(c, grid);
690 }
691 
692 /**
693  * True if the cave square is internally lit.
694  */
square_isbright(struct chunk * c,struct loc grid)695 bool square_isbright(struct chunk *c, struct loc grid) {
696 	assert(square_in_bounds(c, grid));
697 	return feat_is_bright(square(c, grid)->feat);
698 }
699 
700 /**
701  * True if the cave square is fire-based.
702  */
square_isfiery(struct chunk * c,struct loc grid)703 bool square_isfiery(struct chunk *c, struct loc grid) {
704 	assert(square_in_bounds(c, grid));
705 	return feat_is_fiery(square(c, grid)->feat);
706 }
707 
708 /**
709  * True if the cave square is lit.
710  */
square_islit(struct chunk * c,struct loc grid)711 bool square_islit(struct chunk *c, struct loc grid) {
712 	assert(square_in_bounds(c, grid));
713 	return square_light(c, grid) > 0 ? true : false;
714 }
715 
716 /**
717  * True if a lit wall should appear lit.
718  */
square_islitwall(struct chunk * c,struct loc grid)719 bool square_islitwall(struct chunk *c, struct loc grid) {
720 	int d;
721 	assert(square_in_bounds(c, grid));
722 	for (d = 0; d < 8; d++) {
723 		struct loc adj = loc_sum(grid, ddgrid_ddd[d]);
724 		if (!square_in_bounds(c, adj)) continue;
725 		if (!square_isfloor(c, adj)) continue;
726 		if (!square_isroom(c, adj)) continue;
727 		if (!square_isglow(c, adj)) continue;
728 		if (!square_isseen(c, adj)) continue;
729 		return true;
730 	}
731 
732 	return false;
733 }
734 
735 /**
736  * True if the cave square can damage the inhabitant - only lava so far
737  */
square_isdamaging(struct chunk * c,struct loc grid)738 bool square_isdamaging(struct chunk *c, struct loc grid) {
739 	assert(square_in_bounds(c, grid));
740 	return feat_is_fiery(square(c, grid)->feat);
741 }
742 
743 /**
744  * True if the cave square doesn't allow monster flow information.
745  */
square_isnoflow(struct chunk * c,struct loc grid)746 bool square_isnoflow(struct chunk *c, struct loc grid) {
747 	assert(square_in_bounds(c, grid));
748 	return feat_is_no_flow(square(c, grid)->feat);
749 }
750 
751 /**
752  * True if the cave square doesn't carry player scent.
753  */
square_isnoscent(struct chunk * c,struct loc grid)754 bool square_isnoscent(struct chunk *c, struct loc grid) {
755 	assert(square_in_bounds(c, grid));
756 	return feat_is_no_scent(square(c, grid)->feat);
757 }
758 
square_iswarded(struct chunk * c,struct loc grid)759 bool square_iswarded(struct chunk *c, struct loc grid)
760 {
761 	struct trap_kind *rune = lookup_trap("glyph of warding");
762 	return square_trap_specific(c, grid, rune->tidx);
763 }
764 
square_isdecoyed(struct chunk * c,struct loc grid)765 bool square_isdecoyed(struct chunk *c, struct loc grid)
766 {
767 	struct trap_kind *glyph = lookup_trap("decoy");
768 	return square_trap_specific(c, grid, glyph->tidx);
769 }
770 
square_iswebbed(struct chunk * c,struct loc grid)771 bool square_iswebbed(struct chunk *c, struct loc grid)
772 {
773 	struct trap_kind *web = lookup_trap("web");
774 	return square_trap_specific(c, grid, web->tidx);
775 }
776 
square_seemslikewall(struct chunk * c,struct loc grid)777 bool square_seemslikewall(struct chunk *c, struct loc grid)
778 {
779 	return tf_has(f_info[square(c, grid)->feat].flags, TF_ROCK);
780 }
781 
square_isinteresting(struct chunk * c,struct loc grid)782 bool square_isinteresting(struct chunk *c, struct loc grid)
783 {
784 	int f = square(c, grid)->feat;
785 	return tf_has(f_info[f].flags, TF_INTERESTING);
786 }
787 
788 /**
789  * True if the square is a closed, locked door.
790  */
square_islockeddoor(struct chunk * c,struct loc grid)791 bool square_islockeddoor(struct chunk *c, struct loc grid)
792 {
793 	return square_door_power(c, grid) > 0;
794 }
795 
796 /**
797  * True if there is a player trap (known or unknown) in this square.
798  */
square_isplayertrap(struct chunk * c,struct loc grid)799 bool square_isplayertrap(struct chunk *c, struct loc grid)
800 {
801     return square_trap_flag(c, grid, TRF_TRAP);
802 }
803 
804 /**
805  * True if there is a visible trap in this square.
806  */
square_isvisibletrap(struct chunk * c,struct loc grid)807 bool square_isvisibletrap(struct chunk *c, struct loc grid)
808 {
809     /* Look for a visible trap */
810     return square_trap_flag(c, grid, TRF_VISIBLE);
811 }
812 /**
813  * True if the square is an unknown player trap (it will appear as a floor tile)
814  */
square_issecrettrap(struct chunk * c,struct loc grid)815 bool square_issecrettrap(struct chunk *c, struct loc grid)
816 {
817     return !square_isvisibletrap(c, grid) && square_isplayertrap(c, grid);
818 }
819 
820 /**
821  * True if the square is a known, disabled player trap.
822  */
square_isdisabledtrap(struct chunk * c,struct loc grid)823 bool square_isdisabledtrap(struct chunk *c, struct loc grid)
824 {
825 	return square_isvisibletrap(c, grid) &&
826 		(square_trap_timeout(c, grid, -1) > 0);
827 }
828 
829 /**
830  * True if the square is a known, disarmable player trap.
831  */
square_isdisarmabletrap(struct chunk * c,struct loc grid)832 bool square_isdisarmabletrap(struct chunk *c, struct loc grid)
833 {
834 	if (square_isdisabledtrap(c, grid)) return false;
835 	return square_isvisibletrap(c, grid) && square_isplayertrap(c, grid);
836 }
837 
838 /**
839  * Checks if a square is at the (inner) edge of a trap detect area
840  */
square_dtrap_edge(struct chunk * c,struct loc grid)841 bool square_dtrap_edge(struct chunk *c, struct loc grid)
842 {
843 	/* Check if the square is a dtrap in the first place */
844 	if (!square_isdtrap(c, grid)) return false;
845 
846 	/* Check for non-dtrap adjacent grids */
847 	if (square_in_bounds_fully(c, next_grid(grid, DIR_S)) &&
848 		(!square_isdtrap(c, next_grid(grid, DIR_S))))
849 		return true;
850 	if (square_in_bounds_fully(c, next_grid(grid, DIR_E)) &&
851 		(!square_isdtrap(c, next_grid(grid, DIR_E))))
852 		return true;
853 	if (square_in_bounds_fully(c, next_grid(grid, DIR_N)) &&
854 		(!square_isdtrap(c, next_grid(grid, DIR_N))))
855 		return true;
856 	if (square_in_bounds_fully(c, next_grid(grid, DIR_W)) &&
857 		(!square_isdtrap(c, next_grid(grid, DIR_W))))
858 		return true;
859 
860 	return false;
861 }
862 
863 /**
864  * Determine if a given location may be "destroyed"
865  *
866  * Used by destruction spells, and for placing stairs, etc.
867  */
square_changeable(struct chunk * c,struct loc grid)868 bool square_changeable(struct chunk *c, struct loc grid)
869 {
870 	struct object *obj;
871 
872 	/* Forbid perma-grids */
873 	if (square_isperm(c, grid) || square_isshop(c, grid) ||
874 		square_isstairs(c, grid))
875 		return (false);
876 
877 	/* Check objects */
878 	for (obj = square_object(c, grid); obj; obj = obj->next)
879 		/* Forbid artifact grids */
880 		if (obj->artifact) return (false);
881 
882 	/* Accept */
883 	return (true);
884 }
885 
886 
square_in_bounds(struct chunk * c,struct loc grid)887 bool square_in_bounds(struct chunk *c, struct loc grid)
888 {
889 	assert(c);
890 	return grid.x >= 0 && grid.x < c->width &&
891 		grid.y >= 0 && grid.y < c->height;
892 }
893 
square_in_bounds_fully(struct chunk * c,struct loc grid)894 bool square_in_bounds_fully(struct chunk *c, struct loc grid)
895 {
896 	assert(c);
897 	return grid.x > 0 && grid.x < c->width - 1 &&
898 		grid.y > 0 && grid.y < c->height - 1;
899 }
900 
901 /**
902  * Checks if a square is thought by the player to block projections
903  */
square_isbelievedwall(struct chunk * c,struct loc grid)904 bool square_isbelievedwall(struct chunk *c, struct loc grid)
905 {
906 	// the edge of the world is definitely gonna block things
907 	if (!square_in_bounds_fully(c, grid)) return true;
908 	// if we dont know assume its projectable
909 	if (!square_isknown(c, grid)) return false;
910 	// report what we think (we may be wrong)
911 	return !square_isprojectable(player->cave, grid);
912 }
913 
914 /**
915  * Checks if a square is in a cul-de-sac
916  */
square_suits_stairs_well(struct chunk * c,struct loc grid)917 bool square_suits_stairs_well(struct chunk *c, struct loc grid)
918 {
919 	if (square_isvault(c, grid) || square_isno_stairs(c, grid)) return false;
920 	return (square_num_walls_adjacent(c, grid) == 3) &&
921 		(square_num_walls_diagonal(c, grid) == 4) && square_isempty(c, grid);
922 }
923 
924 /**
925  * Checks if a square is in a corridor
926  */
square_suits_stairs_ok(struct chunk * c,struct loc grid)927 bool square_suits_stairs_ok(struct chunk *c, struct loc grid)
928 {
929 	if (square_isvault(c, grid) || square_isno_stairs(c, grid)) return false;
930 	return (square_num_walls_adjacent(c, grid) == 2) &&
931 		(square_num_walls_diagonal(c, grid) == 4) && square_isempty(c, grid);
932 }
933 
934 
935 
936 /**
937  * OTHER SQUARE FUNCTIONS
938  *
939  * Below are various square-specific functions which are not predicates
940  */
941 
square(struct chunk * c,struct loc grid)942 const struct square *square(struct chunk *c, struct loc grid)
943 {
944 	assert(square_in_bounds(c, grid));
945 	return &c->squares[grid.y][grid.x];
946 }
947 
square_feat(struct chunk * c,struct loc grid)948 struct feature *square_feat(struct chunk *c, struct loc grid)
949 {
950 	assert(square_in_bounds(c, grid));
951 	return &f_info[square(c, grid)->feat];
952 }
953 
square_light(struct chunk * c,struct loc grid)954 int square_light(struct chunk *c, struct loc grid)
955 {
956 	assert(square_in_bounds(c, grid));
957 	return square(c, grid)->light;
958 }
959 
960 /**
961  * Get a monster on the current level by its position.
962  */
square_monster(struct chunk * c,struct loc grid)963 struct monster *square_monster(struct chunk *c, struct loc grid)
964 {
965 	if (!square_in_bounds(c, grid)) return NULL;
966 	if (square(c, grid)->mon > 0) {
967 		struct monster *mon = cave_monster(c, square(c, grid)->mon);
968 		return mon && mon->race ? mon : NULL;
969 	}
970 
971 	return NULL;
972 }
973 
974 /**
975  * Get the top object of a pile on the current level by its position.
976  */
square_object(struct chunk * c,struct loc grid)977 struct object *square_object(struct chunk *c, struct loc grid) {
978 	if (!square_in_bounds(c, grid)) return NULL;
979 	return square(c, grid)->obj;
980 }
981 
982 /**
983  * Get the first (and currently only) trap in a position on the current level.
984  */
square_trap(struct chunk * c,struct loc grid)985 struct trap *square_trap(struct chunk *c, struct loc grid)
986 {
987 	if (!square_in_bounds(c, grid)) return NULL;
988     return square(c, grid)->trap;
989 }
990 
991 /**
992  * Return true if the given object is on the floor at this grid
993  */
square_holds_object(struct chunk * c,struct loc grid,struct object * obj)994 bool square_holds_object(struct chunk *c, struct loc grid, struct object *obj) {
995 	assert(square_in_bounds(c, grid));
996 	return pile_contains(square_object(c, grid), obj);
997 }
998 
999 /**
1000  * Excise an object from a floor pile, leaving it orphaned.
1001  */
square_excise_object(struct chunk * c,struct loc grid,struct object * obj)1002 void square_excise_object(struct chunk *c, struct loc grid, struct object *obj){
1003 	assert(square_in_bounds(c, grid));
1004 	pile_excise(&c->squares[grid.y][grid.x].obj, obj);
1005 }
1006 
1007 /**
1008  * Excise an entire floor pile.
1009  */
square_excise_pile(struct chunk * c,struct loc grid)1010 void square_excise_pile(struct chunk *c, struct loc grid) {
1011 	assert(square_in_bounds(c, grid));
1012 	object_pile_free(square_object(c, grid));
1013 	square_set_obj(c, grid, NULL);
1014 }
1015 
1016 /**
1017  * Excise an object from a floor pile and delete it while doing the other
1018  * necessary bookkeeping.  Normally, this is only called for the chunk
1019  * representing the true nature of the environment and not the one
1020  * representing the player's view of it.  If do_note is true, call
1021  * square_note_spot().  If do_light is true, call square_light_spot().
1022  * Unless calling this on the player's view, those both would be true
1023  * except as an optimization/simplification when the caller would call
1024  * square_note_spot()/square_light_spot() anyways or knows that those aren't
1025  * necessary.
1026  */
square_delete_object(struct chunk * c,struct loc grid,struct object * obj,bool do_note,bool do_light)1027 void square_delete_object(struct chunk *c, struct loc grid, struct object *obj, bool do_note, bool do_light)
1028 {
1029 	square_excise_object(c, grid, obj);
1030 	delist_object(c, obj);
1031 	object_delete(&obj);
1032 	if (do_note) {
1033 		square_note_spot(c, grid);
1034 	}
1035 	if (do_light) {
1036 		square_light_spot(c, grid);
1037 	}
1038 }
1039 
1040 /**
1041  * Sense the existence of objects on a grid in the current level
1042  */
square_sense_pile(struct chunk * c,struct loc grid)1043 void square_sense_pile(struct chunk *c, struct loc grid)
1044 {
1045 	struct object *obj;
1046 
1047 	if (c != cave) return;
1048 
1049 	/* Sense every item on this grid */
1050 	for (obj = square_object(c, grid); obj; obj = obj->next) {
1051 		object_sense(player, obj);
1052 	}
1053 }
1054 
1055 /**
1056  * Update the player's knowledge of the objects on a grid in the current level
1057  */
square_know_pile(struct chunk * c,struct loc grid)1058 void square_know_pile(struct chunk *c, struct loc grid)
1059 {
1060 	struct object *obj;
1061 
1062 	if (c != cave) return;
1063 
1064 	object_lists_check_integrity(c, player->cave);
1065 
1066 	/* Know every item on this grid, greater knowledge for the player grid */
1067 	for (obj = square_object(c, grid); obj; obj = obj->next) {
1068 		object_see(player, obj);
1069 		if (loc_eq(grid, player->grid)) {
1070 			object_touch(player, obj);
1071 		}
1072 	}
1073 
1074 	/* Remove known location of anything not on this grid */
1075 	obj = square_object(player->cave, grid);
1076 	while (obj) {
1077 		struct object *next = obj->next;
1078 		assert(c->objects[obj->oidx]);
1079 		if (!square_holds_object(c, grid, c->objects[obj->oidx])) {
1080 			struct object *original = c->objects[obj->oidx];
1081 			square_excise_object(player->cave, grid, obj);
1082 			obj->grid = loc(0, 0);
1083 
1084 			/* Delete objects which no longer exist anywhere */
1085 			if (obj->notice & OBJ_NOTICE_IMAGINED) {
1086 				delist_object(player->cave, obj);
1087 				object_delete(&obj);
1088 				original->known = NULL;
1089 				delist_object(c, original);
1090 				object_delete(&original);
1091 			}
1092 		}
1093 		obj = next;
1094 	}
1095 }
1096 
1097 
1098 /**
1099  * Return how many cardinal directions around (x, y) contain walls.
1100  * \param c current chunk
1101  * \param y co-ordinates
1102  * \param x co-ordinates
1103  * \return the number of walls
1104  */
square_num_walls_adjacent(struct chunk * c,struct loc grid)1105 int square_num_walls_adjacent(struct chunk *c, struct loc grid)
1106 {
1107     int k = 0;
1108     assert(square_in_bounds(c, grid));
1109 
1110     if (feat_is_wall(square(c, next_grid(grid, DIR_S))->feat)) k++;
1111 	if (feat_is_wall(square(c, next_grid(grid, DIR_N))->feat)) k++;
1112     if (feat_is_wall(square(c, next_grid(grid, DIR_E))->feat)) k++;
1113     if (feat_is_wall(square(c, next_grid(grid, DIR_W))->feat)) k++;
1114 
1115     return k;
1116 }
1117 
1118 /**
1119  * Return how many diagonal directions around (x, y) contain walls.
1120  * \param c current chunk
1121  * \param y co-ordinates
1122  * \param x co-ordinates
1123  * \return the number of walls
1124  */
square_num_walls_diagonal(struct chunk * c,struct loc grid)1125 int square_num_walls_diagonal(struct chunk *c, struct loc grid)
1126 {
1127     int k = 0;
1128     assert(square_in_bounds(c, grid));
1129 
1130     if (feat_is_wall(square(c, next_grid(grid, DIR_SE))->feat)) k++;
1131     if (feat_is_wall(square(c, next_grid(grid, DIR_NW))->feat)) k++;
1132     if (feat_is_wall(square(c, next_grid(grid, DIR_NE))->feat)) k++;
1133     if (feat_is_wall(square(c, next_grid(grid, DIR_SW))->feat)) k++;
1134 
1135     return k;
1136 }
1137 
1138 
1139 /**
1140  * Set the terrain type for a square.
1141  *
1142  * This should be the only function that sets terrain, apart from the savefile
1143  * loading code.
1144  */
square_set_feat(struct chunk * c,struct loc grid,int feat)1145 void square_set_feat(struct chunk *c, struct loc grid, int feat)
1146 {
1147 	int current_feat;
1148 
1149 	assert(square_in_bounds(c, grid));
1150 	current_feat = square(c, grid)->feat;
1151 
1152 	/* Track changes */
1153 	if (current_feat) c->feat_count[current_feat]--;
1154 	if (feat) c->feat_count[feat]++;
1155 
1156 	/* Make the change */
1157 	c->squares[grid.y][grid.x].feat = feat;
1158 
1159 	/* Light bright terrain */
1160 	if (feat_is_bright(feat)) {
1161 		sqinfo_on(square(c, grid)->info, SQUARE_GLOW);
1162 	}
1163 
1164 	/* Make the new terrain feel at home */
1165 	if (character_dungeon) {
1166 		/* Remove traps if necessary */
1167 		if (!square_player_trap_allowed(c, grid))
1168 			square_destroy_trap(c, grid);
1169 
1170 		square_note_spot(c, grid);
1171 		square_light_spot(c, grid);
1172 	} else {
1173 		/* Make sure no incorrect wall flags set for dungeon generation */
1174 		sqinfo_off(square(c, grid)->info, SQUARE_WALL_INNER);
1175 		sqinfo_off(square(c, grid)->info, SQUARE_WALL_OUTER);
1176 		sqinfo_off(square(c, grid)->info, SQUARE_WALL_SOLID);
1177 	}
1178 }
1179 
1180 /**
1181  * Set the player-"known" terrain type for a square.
1182  */
square_set_known_feat(struct chunk * c,struct loc grid,int feat)1183 static void square_set_known_feat(struct chunk *c, struct loc grid, int feat)
1184 {
1185 	if (c != cave) return;
1186 	player->cave->squares[grid.y][grid.x].feat = feat;
1187 }
1188 
1189 /**
1190  * Set the occupying monster for a square.
1191  */
square_set_mon(struct chunk * c,struct loc grid,int midx)1192 void square_set_mon(struct chunk *c, struct loc grid, int midx)
1193 {
1194 	c->squares[grid.y][grid.x].mon = midx;
1195 }
1196 
1197 /**
1198  * Set the (first) object for a square.
1199  */
square_set_obj(struct chunk * c,struct loc grid,struct object * obj)1200 void square_set_obj(struct chunk *c, struct loc grid, struct object *obj)
1201 {
1202 	c->squares[grid.y][grid.x].obj = obj;
1203 }
1204 
1205 /**
1206  * Set the (first) trap for a square.
1207  */
square_set_trap(struct chunk * c,struct loc grid,struct trap * trap)1208 void square_set_trap(struct chunk *c, struct loc grid, struct trap *trap)
1209 {
1210 	c->squares[grid.y][grid.x].trap = trap;
1211 }
1212 
square_add_trap(struct chunk * c,struct loc grid)1213 void square_add_trap(struct chunk *c, struct loc grid)
1214 {
1215 	assert(square_in_bounds_fully(c, grid));
1216 	place_trap(c, grid, -1, c->depth);
1217 }
1218 
square_add_glyph(struct chunk * c,struct loc grid,int type)1219 void square_add_glyph(struct chunk *c, struct loc grid, int type)
1220 {
1221 	struct trap_kind *glyph = NULL;
1222 	switch (type) {
1223 		case GLYPH_WARDING: {
1224 			glyph = lookup_trap("glyph of warding");
1225 			break;
1226 		}
1227 		case GLYPH_DECOY: {
1228 			glyph = lookup_trap("decoy");
1229 			c->decoy = grid;
1230 			break;
1231 		}
1232 		default: {
1233 			msg("Non-existent glyph requested. Please report this bug.");
1234 			return;
1235 		}
1236 	}
1237 	place_trap(c, grid, glyph->tidx, 0);
1238 }
1239 
square_add_web(struct chunk * c,struct loc grid)1240 void square_add_web(struct chunk *c, struct loc grid)
1241 {
1242 	struct trap_kind *web = lookup_trap("web");
1243 	place_trap(c, grid, web->tidx, 0);
1244 }
1245 
square_add_stairs(struct chunk * c,struct loc grid,int depth)1246 void square_add_stairs(struct chunk *c, struct loc grid, int depth) {
1247 	int down = randint0(100) < 50;
1248 	if (depth == 0)
1249 		down = 1;
1250 	else if (is_quest(depth) || depth >= z_info->max_depth - 1)
1251 		down = 0;
1252 
1253 	square_set_feat(c, grid, down ? FEAT_MORE : FEAT_LESS);
1254 }
1255 
square_add_door(struct chunk * c,struct loc grid,bool closed)1256 void square_add_door(struct chunk *c, struct loc grid, bool closed) {
1257 	square_set_feat(c, grid, closed ? FEAT_CLOSED : FEAT_OPEN);
1258 }
1259 
square_open_door(struct chunk * c,struct loc grid)1260 void square_open_door(struct chunk *c, struct loc grid)
1261 {
1262 	square_remove_all_traps(c, grid);
1263 	square_set_feat(c, grid, FEAT_OPEN);
1264 }
1265 
square_close_door(struct chunk * c,struct loc grid)1266 void square_close_door(struct chunk *c, struct loc grid)
1267 {
1268 	square_set_feat(c, grid, FEAT_CLOSED);
1269 }
1270 
square_smash_door(struct chunk * c,struct loc grid)1271 void square_smash_door(struct chunk *c, struct loc grid)
1272 {
1273 	square_remove_all_traps(c, grid);
1274 	square_set_feat(c, grid, FEAT_BROKEN);
1275 }
1276 
square_unlock_door(struct chunk * c,struct loc grid)1277 void square_unlock_door(struct chunk *c, struct loc grid) {
1278 	assert(square_islockeddoor(c, grid));
1279 	square_set_door_lock(c, grid, 0);
1280 }
1281 
square_destroy_door(struct chunk * c,struct loc grid)1282 void square_destroy_door(struct chunk *c, struct loc grid) {
1283 	assert(square_isdoor(c, grid));
1284 	square_remove_all_traps(c, grid);
1285 	square_set_feat(c, grid, FEAT_FLOOR);
1286 }
1287 
square_destroy_trap(struct chunk * c,struct loc grid)1288 void square_destroy_trap(struct chunk *c, struct loc grid)
1289 {
1290 	square_remove_all_traps(c, grid);
1291 }
1292 
square_disable_trap(struct chunk * c,struct loc grid)1293 void square_disable_trap(struct chunk *c, struct loc grid)
1294 {
1295 	if (!square_isplayertrap(c, grid)) return;
1296 	square_set_trap_timeout(c, grid, false, -1, 10);
1297 }
1298 
square_destroy_decoy(struct chunk * c,struct loc grid)1299 void square_destroy_decoy(struct chunk *c, struct loc grid)
1300 {
1301 	square_remove_all_traps(c, grid);
1302 	c->decoy = loc(0, 0);
1303 	if (los(c, player->grid, grid) && !player->timed[TMD_BLIND]){
1304 		msg("The decoy is destroyed!");
1305 	}
1306 }
1307 
square_tunnel_wall(struct chunk * c,struct loc grid)1308 void square_tunnel_wall(struct chunk *c, struct loc grid)
1309 {
1310 	square_set_feat(c, grid, FEAT_FLOOR);
1311 }
1312 
square_destroy_wall(struct chunk * c,struct loc grid)1313 void square_destroy_wall(struct chunk *c, struct loc grid)
1314 {
1315 	square_set_feat(c, grid, FEAT_FLOOR);
1316 }
1317 
square_smash_wall(struct chunk * c,struct loc grid)1318 void square_smash_wall(struct chunk *c, struct loc grid)
1319 {
1320 	int i;
1321 	square_set_feat(c, grid, FEAT_FLOOR);
1322 
1323 	for (i = 0; i < 8; i++) {
1324 		/* Extract adjacent location */
1325 		struct loc adj_grid = loc_sum(grid, ddgrid_ddd[i]);
1326 
1327 		/* Check legality */
1328 		if (!square_in_bounds_fully(c, adj_grid)) continue;
1329 
1330 		/* Ignore permanent grids */
1331 		if (square_isperm(c, adj_grid)) continue;
1332 
1333 		/* Ignore floors, but destroy decoys */
1334 		if (square_isfloor(c, adj_grid)) {
1335 			if (square_isdecoyed(c, adj_grid)) {
1336 				square_destroy_decoy(c, adj_grid);
1337 			}
1338 			continue;
1339 		}
1340 
1341 		/* Give this grid a chance to survive */
1342 		if ((square_isgranite(c, adj_grid) && one_in_(4)) ||
1343 			(square_isquartz(c, adj_grid) && one_in_(10)) ||
1344 			(square_ismagma(c, adj_grid) && one_in_(20))) {
1345 			continue;
1346 		}
1347 
1348 		/* Remove it */
1349 		square_set_feat(c, adj_grid, FEAT_FLOOR);
1350 	}
1351 }
1352 
square_destroy(struct chunk * c,struct loc grid)1353 void square_destroy(struct chunk *c, struct loc grid) {
1354 	int feat = FEAT_FLOOR;
1355 	int r = randint0(200);
1356 
1357 	if (r < 20)
1358 		feat = FEAT_GRANITE;
1359 	else if (r < 70)
1360 		feat = FEAT_QUARTZ;
1361 	else if (r < 100)
1362 		feat = FEAT_MAGMA;
1363 
1364 	square_set_feat(c, grid, feat);
1365 }
1366 
square_earthquake(struct chunk * c,struct loc grid)1367 void square_earthquake(struct chunk *c, struct loc grid) {
1368 	int t = randint0(100);
1369 	int f;
1370 
1371 	if (!square_ispassable(c, grid)) {
1372 		square_set_feat(c, grid, FEAT_FLOOR);
1373 		return;
1374 	}
1375 
1376 	if (t < 20)
1377 		f = FEAT_GRANITE;
1378 	else if (t < 70)
1379 		f = FEAT_QUARTZ;
1380 	else
1381 		f = FEAT_MAGMA;
1382 	square_set_feat(c, grid, f);
1383 }
1384 
1385 /**
1386  * Add visible treasure to a mineral square.
1387  */
square_upgrade_mineral(struct chunk * c,struct loc grid)1388 void square_upgrade_mineral(struct chunk *c, struct loc grid)
1389 {
1390 	if (square(c, grid)->feat == FEAT_MAGMA)
1391 		square_set_feat(c, grid, FEAT_MAGMA_K);
1392 	if (square(c, grid)->feat == FEAT_QUARTZ)
1393 		square_set_feat(c, grid, FEAT_QUARTZ_K);
1394 }
1395 
square_destroy_rubble(struct chunk * c,struct loc grid)1396 void square_destroy_rubble(struct chunk *c, struct loc grid) {
1397 	assert(square_isrubble(c, grid));
1398 	square_set_feat(c, grid, FEAT_FLOOR);
1399 }
1400 
square_force_floor(struct chunk * c,struct loc grid)1401 void square_force_floor(struct chunk *c, struct loc grid) {
1402 	square_set_feat(c, grid, FEAT_FLOOR);
1403 }
1404 
1405 /* Note that this returns the STORE_ index, which is one less than shopnum */
square_shopnum(struct chunk * c,struct loc grid)1406 int square_shopnum(struct chunk *c, struct loc grid) {
1407 	if (square_isshop(c, grid))
1408 		return f_info[square(c, grid)->feat].shopnum - 1;
1409 	return -1;
1410 }
1411 
square_digging(struct chunk * c,struct loc grid)1412 int square_digging(struct chunk *c, struct loc grid) {
1413 	if (square_isdiggable(c, grid))
1414 		return f_info[square(c, grid)->feat].dig;
1415 	return 0;
1416 }
1417 
square_apparent_name(struct chunk * c,struct player * p,struct loc grid)1418 const char *square_apparent_name(struct chunk *c, struct player *p, struct loc grid) {
1419 	int actual = square(player->cave, grid)->feat;
1420 	char *mimic_name = f_info[actual].mimic;
1421 	int f = mimic_name ? lookup_feat(mimic_name) : actual;
1422 	return f_info[f].name;
1423 }
1424 
square_apparent_look_prefix(struct chunk * c,struct player * p,struct loc grid)1425 const char *square_apparent_look_prefix(struct chunk *c, struct player *p, struct loc grid) {
1426 	int actual = square(player->cave, grid)->feat;
1427 	char *mimic_name = f_info[actual].mimic;
1428 	int f = mimic_name ? lookup_feat(mimic_name) : actual;
1429 	return (f_info[f].look_prefix) ? f_info[f].look_prefix :
1430 		(is_a_vowel(f_info[f].name[0]) ? "an " : "a ");
1431 }
1432 
square_apparent_look_in_preposition(struct chunk * c,struct player * p,struct loc grid)1433 const char *square_apparent_look_in_preposition(struct chunk *c, struct player *p, struct loc grid) {
1434 	int actual = square(player->cave, grid)->feat;
1435 	char *mimic_name = f_info[actual].mimic;
1436 	int f = mimic_name ? lookup_feat(mimic_name) : actual;
1437 	return (f_info[f].look_in_preposition) ?
1438 		 f_info[f].look_in_preposition : "on ";
1439 }
1440 
1441 /* Memorize the terrain */
square_memorize(struct chunk * c,struct loc grid)1442 void square_memorize(struct chunk *c, struct loc grid) {
1443 	if (c != cave) return;
1444 	square_set_known_feat(c, grid, square(c, grid)->feat);
1445 }
1446 
1447 /* Forget the terrain */
square_forget(struct chunk * c,struct loc grid)1448 void square_forget(struct chunk *c, struct loc grid) {
1449 	if (c != cave) return;
1450 	square_set_known_feat(c, grid, FEAT_NONE);
1451 }
1452 
square_mark(struct chunk * c,struct loc grid)1453 void square_mark(struct chunk *c, struct loc grid) {
1454 	sqinfo_on(square(c, grid)->info, SQUARE_MARK);
1455 }
1456 
square_unmark(struct chunk * c,struct loc grid)1457 void square_unmark(struct chunk *c, struct loc grid) {
1458 	sqinfo_off(square(c, grid)->info, SQUARE_MARK);
1459 }
1460