1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
|
|
4 | * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2001 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 2001 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
8 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * Deliantra is free software: you can redistribute it and/or modify it under |
… | |
… | |
114 | } |
115 | } |
115 | |
116 | |
116 | // can freeindex ever be < 0? |
117 | // can freeindex ever be < 0? |
117 | if (freeindex >= 0) |
118 | if (freeindex >= 0) |
118 | { |
119 | { |
119 | kx += freearr_x [freeindex]; |
120 | kx += DIRX (freeindex); |
120 | ky += freearr_y [freeindex]; |
121 | ky += DIRY (freeindex); |
121 | } |
122 | } |
122 | } |
123 | } |
123 | } |
124 | } |
124 | else |
125 | else |
125 | { /* NO_PASS_DOORS --we have to work harder. */ |
126 | { /* NO_PASS_DOORS --we have to work harder. */ |
… | |
… | |
341 | { |
342 | { |
342 | the_chest->destroy (); |
343 | the_chest->destroy (); |
343 | return NULL; |
344 | return NULL; |
344 | } |
345 | } |
345 | |
346 | |
346 | int xl = x + freearr_x[i]; |
347 | int xl = x + DIRX (i); |
347 | int yl = y + freearr_y[i]; |
348 | int yl = y + DIRY (i); |
348 | |
349 | |
349 | /* if the placement is blocked, return a fail. */ |
350 | /* if the placement is blocked, return a fail. */ |
350 | if (wall_blocked (map, xl, yl)) |
351 | if (wall_blocked (map, xl, yl)) |
351 | return 0; |
352 | return 0; |
352 | |
353 | |
… | |
… | |
425 | |
426 | |
426 | for (i = 0; i < SIZEOFFREE; i++) |
427 | for (i = 0; i < SIZEOFFREE; i++) |
427 | { |
428 | { |
428 | int lx, ly; |
429 | int lx, ly; |
429 | |
430 | |
430 | lx = x + freearr_x[i]; |
431 | lx = x + DIRX (i); |
431 | ly = y + freearr_y[i]; |
432 | ly = y + DIRY (i); |
432 | /* boundscheck */ |
433 | /* boundscheck */ |
433 | if (lx >= 0 && ly >= 0 && lx < map->width && ly < map->height) |
434 | if (lx >= 0 && ly >= 0 && lx < map->width && ly < map->height) |
434 | /* don't bother searching this square unless the map says life exists. */ |
435 | /* don't bother searching this square unless the map says life exists. */ |
435 | if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE) |
436 | if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE) |
436 | { |
437 | { |
… | |
… | |
486 | } |
487 | } |
487 | |
488 | |
488 | /* now search all the 8 squares around recursively for a monster,in random order */ |
489 | /* now search all the 8 squares around recursively for a monster,in random order */ |
489 | for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) |
490 | for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) |
490 | { |
491 | { |
491 | theMonsterToFind = find_monster_in_room_recursive (maze, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1]); |
492 | theMonsterToFind = find_monster_in_room_recursive (maze, map, x + DIRX (i % 8 + 1), y + DIRY (i % 8 + 1)); |
492 | if (theMonsterToFind) |
493 | if (theMonsterToFind) |
493 | return theMonsterToFind; |
494 | return theMonsterToFind; |
494 | } |
495 | } |
495 | |
496 | |
496 | return theMonsterToFind; |
497 | return theMonsterToFind; |
… | |
… | |
534 | maze[x][y] = 1; |
535 | maze[x][y] = 1; |
535 | spots.push (point (x, y)); |
536 | spots.push (point (x, y)); |
536 | |
537 | |
537 | /* now search all the 8 squares around recursively for free spots,in random order */ |
538 | /* now search all the 8 squares around recursively for free spots,in random order */ |
538 | for (int i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) |
539 | for (int i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) |
539 | find_spot_in_room_recursive (maze, spots, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1]); |
540 | find_spot_in_room_recursive (maze, spots, x + DIRX (i % 8 + 1), y + DIRY (i % 8 + 1)); |
540 | |
541 | |
541 | } |
542 | } |
542 | |
543 | |
543 | /* find a random non-blocked spot in this room to drop a key. */ |
544 | /* find a random non-blocked spot in this room to drop a key. */ |
544 | static void |
545 | static void |
… | |
… | |
579 | |
580 | |
580 | for (i = 0; i <= SIZEOFFREE1; i++) |
581 | for (i = 0; i <= SIZEOFFREE1; i++) |
581 | { |
582 | { |
582 | int lx, ly, sindex; |
583 | int lx, ly, sindex; |
583 | |
584 | |
584 | lx = x + freearr_x[i]; |
585 | lx = x + DIRX (i); |
585 | ly = y + freearr_y[i]; |
586 | ly = y + DIRY (i); |
586 | sindex = surround_flag3 (map, lx, ly); |
587 | sindex = surround_flag3 (map, lx, ly); |
587 | /* if it's blocked on 3 sides, it's enclosed */ |
588 | /* if it's blocked on 3 sides, it's enclosed */ |
588 | if (sindex == 7 || sindex == 11 || sindex == 13 || sindex == 14) |
589 | if (sindex == 7 || sindex == 11 || sindex == 13 || sindex == 14) |
589 | { |
590 | { |
590 | *cx = lx; |
591 | *cx = lx; |
… | |
… | |
597 | spots--try to find someplace which is 2x enclosed. */ |
598 | spots--try to find someplace which is 2x enclosed. */ |
598 | for (i = 0; i <= SIZEOFFREE1; i++) |
599 | for (i = 0; i <= SIZEOFFREE1; i++) |
599 | { |
600 | { |
600 | int lx, ly, sindex; |
601 | int lx, ly, sindex; |
601 | |
602 | |
602 | lx = x + freearr_x[i]; |
603 | lx = x + DIRX (i); |
603 | ly = y + freearr_y[i]; |
604 | ly = y + DIRY (i); |
604 | sindex = surround_flag3 (map, lx, ly); |
605 | sindex = surround_flag3 (map, lx, ly); |
605 | /* if it's blocked on 3 sides, it's enclosed */ |
606 | /* if it's blocked on 3 sides, it's enclosed */ |
606 | if (sindex == 3 || sindex == 5 || sindex == 9 || sindex == 6 || sindex == 10 || sindex == 12) |
607 | if (sindex == 3 || sindex == 5 || sindex == 9 || sindex == 6 || sindex == 10 || sindex == 12) |
607 | { |
608 | { |
608 | *cx = lx; |
609 | *cx = lx; |
… | |
… | |
614 | /* settle for one surround point */ |
615 | /* settle for one surround point */ |
615 | for (i = 0; i <= SIZEOFFREE1; i++) |
616 | for (i = 0; i <= SIZEOFFREE1; i++) |
616 | { |
617 | { |
617 | int lx, ly, sindex; |
618 | int lx, ly, sindex; |
618 | |
619 | |
619 | lx = x + freearr_x[i]; |
620 | lx = x + DIRX (i); |
620 | ly = y + freearr_y[i]; |
621 | ly = y + DIRY (i); |
621 | sindex = surround_flag3 (map, lx, ly); |
622 | sindex = surround_flag3 (map, lx, ly); |
622 | /* if it's blocked on 3 sides, it's enclosed */ |
623 | /* if it's blocked on 3 sides, it's enclosed */ |
623 | if (sindex) |
624 | if (sindex) |
624 | { |
625 | { |
625 | *cx = lx; |
626 | *cx = lx; |
… | |
… | |
630 | /* give up and return the closest free spot. */ |
631 | /* give up and return the closest free spot. */ |
631 | i = rmg_find_free_spot (archetype::find (shstr_chest), map, x, y, 1, SIZEOFFREE1 + 1); |
632 | i = rmg_find_free_spot (archetype::find (shstr_chest), map, x, y, 1, SIZEOFFREE1 + 1); |
632 | |
633 | |
633 | if (i != -1) |
634 | if (i != -1) |
634 | { |
635 | { |
635 | *cx = x + freearr_x[i]; |
636 | *cx = x + DIRX (i); |
636 | *cy = y + freearr_y[i]; |
637 | *cy = y + DIRY (i); |
637 | } |
638 | } |
638 | else |
639 | else |
639 | { |
640 | { |
640 | /* indicate failure */ |
641 | /* indicate failure */ |
641 | *cx = -1; |
642 | *cx = -1; |
… | |
… | |
682 | } |
683 | } |
683 | |
684 | |
684 | /* place doors in all the 8 adjacent unblocked squares. */ |
685 | /* place doors in all the 8 adjacent unblocked squares. */ |
685 | for (i = 1; i < 9; i++) |
686 | for (i = 1; i < 9; i++) |
686 | { |
687 | { |
687 | int x1 = x + freearr_x[i], y1 = y + freearr_y[i]; |
688 | int x1 = x + DIRX (i), y1 = y + DIRY (i); |
688 | |
689 | |
689 | if (!wall_blocked (map, x1, y1) && maze[x1][y1] == '>') |
690 | if (!wall_blocked (map, x1, y1) && maze[x1][y1] == '>') |
690 | { /* place a door */ |
691 | { /* place a door */ |
691 | remove_monsters (x1, y1, map); |
692 | remove_monsters (x1, y1, map); |
692 | |
693 | |
693 | object *new_door = archetype::get (freearr_x[i] == 0 ? doors[1] : doors[0]); |
694 | object *new_door = archetype::get (DIRX (i) == 0 ? doors[1] : doors[0]); |
694 | map->insert (new_door, x1, y1); |
695 | map->insert (new_door, x1, y1); |
695 | doorlist[ndoors_made] = new_door; |
696 | doorlist[ndoors_made] = new_door; |
696 | ndoors_made++; |
697 | ndoors_made++; |
697 | } |
698 | } |
698 | } |
699 | } |
… | |
… | |
749 | maze[x][y] = 1; |
750 | maze[x][y] = 1; |
750 | |
751 | |
751 | /* now search all the 8 squares around recursively for free spots,in random order */ |
752 | /* now search all the 8 squares around recursively for free spots,in random order */ |
752 | for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) |
753 | for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) |
753 | find_doors_in_room_recursive (maze, map, |
754 | find_doors_in_room_recursive (maze, map, |
754 | x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], |
755 | x + DIRX (i % 8 + 1), y + DIRY (i % 8 + 1), |
755 | doorlist, ndoors); |
756 | doorlist, ndoors); |
756 | } |
757 | } |
757 | } |
758 | } |
758 | |
759 | |
759 | /* find a random non-blocked spot in this room to drop a key. */ |
760 | /* find a random non-blocked spot in this room to drop a key. */ |