File: map-cell.h

package info (click to toggle)
crawl 2%3A0.34.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 100,188 kB
  • sloc: cpp: 363,709; ansic: 27,765; javascript: 9,516; python: 8,463; perl: 3,293; java: 3,132; xml: 2,380; makefile: 1,835; sh: 611; objc: 250; cs: 15; sed: 9; lisp: 3
file content (346 lines) | stat: -rw-r--r-- 8,945 bytes parent folder | download | duplicates (2)
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#pragma once

#include <libutil.h>

#include "enum.h"
#include "mon-info.h"
#include "tag-version.h"
#include "trap-type.h"

#define MAP_MAGIC_MAPPED_FLAG   0x01
#define MAP_SEEN_FLAG           0x02
#define MAP_CHANGED_FLAG        0x04 // FIXME: this doesn't belong here
#define MAP_DETECTED_MONSTER    0x08
#define MAP_INVISIBLE_MONSTER   0x10
#define MAP_DETECTED_ITEM       0x20
#define MAP_VISIBLE_FLAG        0x40
#define MAP_GRID_KNOWN (MAP_MAGIC_MAPPED_FLAG | MAP_SEEN_FLAG \
                        | MAP_DETECTED_MONSTER | MAP_INVISIBLE_MONSTER \
                        | MAP_DETECTED_ITEM | MAP_VISIBLE_FLAG)

#define MAP_EMPHASIZE          0x100
#define MAP_MORE_ITEMS         0x200
#define MAP_HALOED             0x400
#define MAP_SILENCED           0x800
#define MAP_BLOODY            0x1000
#define MAP_CORRODING         0x2000
#define MAP_ICY               0x8000

/* these flags require more space to serialize: put infrequently used ones there */
#define MAP_EXCLUDED_STAIRS  0x10000
#define MAP_BLOOD_WEST       0x20000
#define MAP_BLOOD_NORTH      0x40000
#define MAP_SANCTUARY_1      0x80000
#define MAP_SANCTUARY_2     0x100000
#define MAP_WITHHELD        0x200000
#define MAP_LIQUEFIED       0x400000
#define MAP_ORB_HALOED      0x800000
#define MAP_UMBRAED        0x1000000
#define MAP_OLD_BLOOD      0x2000000
#define MAP_QUAD_HALOED    0X4000000
#define MAP_DISJUNCT       0X8000000
#define MAP_BLASPHEMY     0X10000000
#define MAP_BFB_CORPSE    0X20000000

struct cloud_info
{
    cloud_info() : type(CLOUD_NONE), colour(0), variety(3), tile(0), pos(0, 0),
                   killer(KILL_NONE)
    { }

    cloud_info(cloud_type t, colour_t c,
               uint8_t dur, unsigned short til, coord_def gc,
               killer_type kill)
        : type(t), colour(c), variety(dur), tile(til), pos(gc), killer(kill)
    { }

    friend bool operator==(const cloud_info &lhs, const cloud_info &rhs) {
        return lhs.type == rhs.type
               && lhs.colour == rhs.colour
               && lhs.variety == rhs.variety
               && lhs.tile == rhs.tile
               && lhs.pos == rhs.pos
               && lhs.killer == rhs.killer;
    }

    friend bool operator!=(const cloud_info &lhs, const cloud_info &rhs) {
        return !(lhs == rhs);
    }


    cloud_type type:8;
    colour_t colour;
    // for clouds with duration: decay/20, clamped to 0-3
    // for vortex clouds: the vortex phase
    uint8_t variety;
    // TODO: should this be tileidx_t?
    unsigned short tile;
    coord_def pos;
    killer_type killer;
};

/*
 * A map_cell stores what the player knows about a cell.
 * These go in env.map_knowledge.
 * TODO: this can shrink to 32 bytes by shrinking enums
 */
struct map_cell
{
    // TODO: in C++20 we can give these a default member initializer
    map_cell() : _feat(DNGN_UNSEEN),
                 _trap(TRAP_UNASSIGNED)
    {
    }

    ~map_cell() = default;

    // copy constructor
    map_cell(const map_cell& o)
    {
        *this = o;
    }

    // copy assignment
    map_cell& operator=(const map_cell& o)
    {
        if (this == &o)
            return *this;

        flags = o.flags;
        _feat = o._feat;
        _feat_colour = o._feat_colour;
        _trap = o._trap;
        _cloud = o._cloud ? make_unique<cloud_info>(*o._cloud) : nullptr;
        _item = o._item ? make_unique<item_def>(*o._item) : nullptr;
        _mons = o._mons ? make_unique<monster_info>(*o._mons) : nullptr;

        return *this;
    }

    // move constructor
    map_cell(map_cell&& o) noexcept = default;
    // move assignment
    // XXX: Using the default implementation causes a compiler error on gcc
    // 4.7, so we specify the implementation for now.
    map_cell& operator=(map_cell&& o) noexcept
    {
        flags = o.flags;
        _feat = o._feat;
        _feat_colour = o._feat_colour;
        _trap = o._trap;
        _cloud = std::move(o._cloud);
        _item = std::move(o._item);
        _mons = std::move(o._mons);
        return *this;
    }

    friend bool operator==(const map_cell &lhs, const map_cell &rhs) {
        // TODO: consider providing a proper equality operator
        // item_def and monster_info currently lack such operators
        // Which makes it impossible for map_cell to provide one
        // As far as I can tell, packed_cell is the only user of this
        // And packed_cell operator== doesn't *seem* to be used
        return &lhs == &rhs;
    }

    friend bool operator!=(const map_cell &lhs, const map_cell &rhs) {
        return !(lhs == rhs);
    }

    void clear()
    {
        *this = map_cell();
    }

    // Clear prior to show update. Need to retain at least "seen" flag.
    void clear_data()
    {
        const uint32_t f = flags & (MAP_SEEN_FLAG | MAP_CHANGED_FLAG
                                    | MAP_VISIBLE_FLAG);
        clear();
        flags = f;
    }

    dungeon_feature_type feat() const
    {
        // Ugh; MSVC makes the bit field signed even though that means it can't
        // actually hold all the enum values. That seems to be in contradiction
        // of the standard (ยง9.6 [class.bit] paragraph 4) but what can you do?
        return static_cast<dungeon_feature_type>(static_cast<uint8_t>(_feat));
    }

    unsigned feat_colour() const
    {
        return _feat_colour;
    }

    void set_feature(dungeon_feature_type nfeat, unsigned colour = 0,
                     trap_type tr = TRAP_UNASSIGNED)
    {
        _feat = nfeat;
        _feat_colour = colour;
        _trap = tr;
    }

    item_def* item() const
    {
        return _item.get();
    }

    bool detected_item() const
    {
        const bool ret = !!(flags & MAP_DETECTED_ITEM);
        // TODO: change to an ASSERT when the underlying crash goes away
        if (ret && !_item)
        {
            //clear_item();
            return false;
        }
        return ret;
    }

    void set_item(const item_def& ii, bool more_items)
    {
        clear_item();
        _item = make_unique<item_def>(ii);
        if (more_items)
            flags |= MAP_MORE_ITEMS;
    }

    void set_detected_item();

    void clear_item()
    {
        // TODO: internal callers are doing a bit of duplicate work here
        _item.reset();
        flags &= ~(MAP_DETECTED_ITEM | MAP_MORE_ITEMS);
    }

    monster_type monster() const
    {
        return _mons ? _mons->type : MONS_NO_MONSTER;
    }

    monster_info* monsterinfo() const
    {
        return _mons.get();
    }

    void set_monster(const monster_info& mi)
    {
        clear_monster();
        _mons = make_unique<monster_info>(mi);
    }

    bool detected_monster() const
    {
        return !!(flags & MAP_DETECTED_MONSTER);
    }

    bool invisible_monster() const
    {
        return !!(flags & MAP_INVISIBLE_MONSTER);
    }

    void set_detected_monster(monster_type mons)
    {
        clear_monster();
        _mons = make_unique<monster_info>(MONS_SENSED);
        _mons->base_type = mons;
        flags |= MAP_DETECTED_MONSTER;
    }

    void set_invisible_monster()
    {
        clear_monster();
        flags |= MAP_INVISIBLE_MONSTER;
    }

    void clear_monster()
    {
        // TODO: internal callers are doing a bit of duplicate work here
        _mons.reset();
        flags &= ~(MAP_DETECTED_MONSTER | MAP_INVISIBLE_MONSTER);
    }

    cloud_type cloud() const
    {
        return _cloud ? _cloud->type : CLOUD_NONE;
    }

    // TODO: should this be colour_t?
    unsigned cloud_colour() const
    {
        return _cloud ? _cloud->colour : static_cast<colour_t>(0);
    }

    cloud_info* cloudinfo() const
    {
        return _cloud.get();
    }

    void set_cloud(const cloud_info& ci)
    {
        _cloud = make_unique<cloud_info>(ci);
    }

    void clear_cloud()
    {
        _cloud.reset();
    }

    bool update_cloud_state();

    bool known() const
    {
        return !!(flags & MAP_GRID_KNOWN);
    }

    bool seen() const
    {
        return !!(flags & MAP_SEEN_FLAG);
    }

    bool visible() const
    {
        return !!(flags & MAP_VISIBLE_FLAG);
    }

    bool changed() const
    {
        return !!(flags & MAP_CHANGED_FLAG);
    }

    bool mapped() const
    {
        return !!(flags & MAP_MAGIC_MAPPED_FLAG);
    }

    trap_type trap() const
    {
        return _trap;
    }

#ifdef USE_TILE
    char blood_rotation() const noexcept
    {
        char result = 0;
        if (flags & MAP_BLOOD_WEST)
            result += 1;
        if (flags & MAP_BLOOD_NORTH)
            result += 2;
        return result;
    }
#endif

public:
    uint32_t flags = 0;   // Flags describing the mappedness of this square.
private:
    // TODO: shrink enums, shrink/re-order cloud_info and inline it
    dungeon_feature_type _feat:8;
    colour_t _feat_colour = 0;
    trap_type _trap:8;
    unique_ptr<cloud_info> _cloud;
    unique_ptr<item_def> _item;
    unique_ptr<monster_info> _mons;
};