File: floor.c

package info (click to toggle)
crossfire 1.75.0-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,168 kB
  • sloc: ansic: 83,169; sh: 4,659; perl: 1,736; lex: 1,443; makefile: 1,199; python: 43
file content (116 lines) | stat: -rw-r--r-- 3,213 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
 * Crossfire -- cooperative multi-player graphical RPG and adventure game
 *
 * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
 * Copyright (c) 1992 Frank Tore Johansen
 *
 * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
 * welcome to redistribute it under certain conditions. For details, please
 * see COPYING and LICENSE.
 *
 * The authors can be reached via e-mail at <crossfire@metalforge.org>.
 */

/**
 * @file
 * Floor handling.
 */

#include <global.h>
#include <random_map.h>
#include <rproto.h>

/**
 * Checks if the tile 'propagates' the floor.
 * @param item
 * tile to check.
 * @return
 * 1 if this tile should propagate, 0 else.
 */
static int can_propagate(char item)
{
    return (item == '\0' || item == '<' || item == '>') ? 1 : 0;
}

/**
 * Put a floor at specified location, and then to adjacent tiles if applicable.
 * @param map
 * where to put the floor.
 * @param layout
 * layout that was used to generate the map.
 * @param x
 * @param y
 * coordinates.
 * @param floor_arch
 * what floor to use.
 */
static void put_floor(mapstruct *map, char **layout, int x, int y, object *floor_arch)
{
    int dx, dy;
    object *floor;

    floor = arch_to_object(floor_arch->arch);
    object_insert_in_map_at(floor, map, floor, INS_NO_MERGE|INS_NO_WALK_ON, x, y);

    for (dx = -1; dx < 2; dx++) {
        for (dy = -1; dy < 2; dy++) {
            if (GET_MAP_OB(map, x+dx, y+dy) == NULL && can_propagate(layout[x+dx][y+dy])) {
                put_floor(map, layout, x+dx, y+dy, floor_arch);
            }
        }
    }
}

/**
 * Creates the Crossfire mapstruct object from the layout, and adds the floor.
 * @param layout
 * generated layout.
 * @param floorstyle
 * floor style. Can be NULL, in which case a random one is chosen.
 * @param RP
 * parameters of the random map.
 * @return
 * Crossfire map.
 */
mapstruct *make_map_floor(char **layout, char *floorstyle, RMParms *RP)
{
    mapstruct *style_map = NULL;
    object *the_floor;
    mapstruct *newMap = NULL;
    int x, y;

    /* allocate the map */
    newMap = get_empty_map(RP->Xsize, RP->Ysize);

    /* get the style map */
    const char *styledirname = "/styles/floorstyles";
    style_map = find_style(styledirname, floorstyle, -1);
    if (style_map == NULL) {
        return newMap;
    }

    if (RP->multiple_floors) {
        for (x = 0; x < RP->Xsize; x++) {
            for (y = 0; y < RP->Ysize; y++) {
                if (GET_MAP_OB(newMap, x, y) == NULL && layout[x][y] == '\0') {
                    put_floor(newMap, layout, x, y, pick_random_object(style_map));
                }
            }
        }
    }

    /* fill up the map with the given floor style */
    if ((the_floor = pick_random_object(style_map)) != NULL) {
        object *thisfloor;

        for (x = 0; x < RP->Xsize; x++)
            for (y = 0; y < RP->Ysize; y++) {
                if (GET_MAP_OB(newMap, x, y) != NULL) {
                    continue;
                }
                thisfloor = arch_to_object(the_floor->arch);
                object_insert_in_map_at(thisfloor, newMap, thisfloor, INS_NO_MERGE|INS_NO_WALK_ON, x, y);
            }
    }
    return newMap;
}