-
Notifications
You must be signed in to change notification settings - Fork 10
/
room.h
234 lines (204 loc) · 5.88 KB
/
room.h
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
#pragma once
#include <boost/serialization/bitset.hpp>
#include <string>
#include <vector>
#include <memory>
#include <bitset>
#include <variant>
#include <tuple>
#include "defs.h"
#include "globals.h"
#include "object.h"
#include "roomfns.h"
typedef std::variant<int, std::vector<Bits>> RPValue;
typedef std::tuple<ObjectSlots, RPValue> RP;
inline RP rg(const std::initializer_list<Bits> &rb)
{
std::vector<Bits> bits(rb);
return RP(ObjectSlots::ksl_rglobal, bits);
}
// Special message on no exit
class NExit
{
public:
explicit NExit(const char *desc) : nexit_desc(desc) {}
std::string_view desc() const { return nexit_desc; }
private:
std::string_view nexit_desc;
};
// Special exit conditions
class CExit
{
public:
typedef std::variant<FlagId, rapplic> FlagVar;
CExit(FlagVar flag_name, std::string_view rmid, std::string_view desc = "", bool flag = false, ex_rapplic fn = nullptr) :
_flid(flag_name),
_rmid(rmid),
_desc(desc),
_fn(fn)
{
//flag;
}
ex_rapplic cxaction() const { return _fn; }
const RoomP &cxroom() const;
const std::string &cxstr() const { return _desc; }
bool cxflag() const {
if (auto fid = std::get_if<FlagId>(&_flid))
{
return flags[*fid];
}
return false;
}
private:
FlagVar _flid;
std::string _rmid;
std::string _desc;
ex_rapplic _fn;
};
typedef std::shared_ptr<CExit> CExitPtr;
class DoorExit
{
public:
DoorExit(std::string_view oid, std::string_view rm1, std::string_view rm2, std::string_view str = std::string_view(), ex_rapplic fn = nullptr) :
_oid(oid),
_rm1(rm1),
_rm2(rm2),
_str(str),
_fn(fn)
{
}
ex_rapplic daction() const {
return _fn;
}
const ObjectP &dobj() const;
const RoomP &droom1() const;
const RoomP &droom2() const;
const std::string &dstr() const { return _str; }
void dstr(std::string_view s) { _str = s; }
private:
std::string _oid;
std::string _rm1;
std::string _rm2;
std::string _str;
ex_rapplic _fn;
};
typedef std::shared_ptr<DoorExit> DoorExitPtr;
class SetgExit
{
public:
SetgExit(std::string_view name, const CExitPtr &cep) : sname(name), ce(cep) {}
const std::string &name() const { return sname; }
const CExitPtr &cexit() const { return ce; }
private:
std::string sname;
CExitPtr ce;
};
typedef std::shared_ptr<SetgExit> SetgExitP;
typedef std::variant<std::monostate, NExit, CExitPtr, DoorExitPtr, SetgExitP, std::string, RoomP> ExitType;
using Ex = std::tuple<direction, ExitType>;
inline bool operator==(const Ex& e, direction d) { return std::get<0>(e) == d; }
inline bool operator==(direction d, const Ex& e) { return e == d; }
class Room
{
public:
Room(std::string_view rid, std::string_view d1, std::string_view d2,
const std::initializer_list<Ex> &exits,
const std::initializer_list<const char*> &contents,
rapplic roomf,
const std::initializer_list<RoomBit> &rb,
const std::initializer_list<RP> &room_slots);
const std::string &rid() const { return _id; }
const std::string &rdesc1() const { return _desc1; }
std::string &rdesc1() { return _desc1; }
const std::string &rdesc2() const { return _desc2; }
ObjList &robjs() { return _contents; }
const ObjList &robjs() const { return _contents; }
const std::vector<Ex> &rexits() const { return _exits; }
const std::vector<Bits> &rglobal() const { return _rglobal; }
void rglobal(Bits new_global) { _rglobal.push_back(new_global); }
RoomBits &rbits() { return _room_bits; }
rapplic raction() const { return _room_fn; }
int rval() const;
void rval(int new_val);
void restore(const Room &src)
{
_room_bits = src._room_bits;
_rval = src._rval;
robjs() = src.robjs();
// Also have to save the room description, since mung_room
// might change it.
_desc1 = src.rdesc1();
}
private:
friend class boost::serialization::access;
Room() {}
template <class archive>
void save(archive &ar, const unsigned int version) const
{
ar & _room_bits;
ar & _rval;
std::list<std::string> rob;
std::transform(robjs().begin(), robjs().end(), std::back_inserter(rob), [](ObjectP o)
{
return o->oid();
});
ar & rob;
ar & _desc1;
}
template <class archive>
void load(archive &ar, const unsigned int version)
{
ar & _room_bits;
ar & _rval;
std::list<std::string> rob;
ar & rob;
ar & _desc1;
robjs().clear();
std::transform(rob.begin(), rob.end(), std::back_inserter(robjs()), [](const std::string &oid)
{
return sfind_obj(oid);
});
}
BOOST_SERIALIZATION_SPLIT_MEMBER();
std::string _id;
std::string _desc1;
std::string _desc2;
int _rval = 0;
RoomBits _room_bits;
std::vector<Bits> _rglobal;
std::vector<Ex> _exits;
ObjList _contents;
rapplic _room_fn = nullptr;
};
void init_rooms();
const RoomP &get_room(std::string_view rid, RoomP init_val = RoomP());
const RoomP &find_room(std::string_view rid);
inline const RoomP &sfind_room(std::string_view s) { return find_room(s); }
RoomList &rooms();
typedef std::map<std::string, RoomP, std::less<>> RoomMap;
RoomMap &room_map();
inline RoomList::iterator rest(RoomList::iterator i, int count = 1)
{
return std::next(i);
}
// Set or 0 room bit
inline bool rtro(const RoomP &p, RoomBit b)
{
p->rbits()[b] = true;
return true;
}
inline bool rtrz(const RoomP& p, RoomBit b)
{
p->rbits()[b] = false;
return true;
}
// Used for memq
inline bool operator==(const RoomP& p, const Ex& exit)
{
auto rid = std::get_if<std::string>(&std::get<1>(exit));
return rid ? (*rid == p->rid()) : false;
}
inline bool operator==(const Ex& exit, const RoomP& p)
{
return p == exit;
}