1
/***************************************************************************
3
* Copyright (C) 2006 by Mark J. Tilford *
5
* This file is part of Geas. *
7
* Geas is free software; you can redistribute it and/or modify *
8
* it under the terms of the GNU General Public License as published by *
9
* the Free Software Foundation; either version 2 of the License, or *
10
* (at your option) any later version. *
12
* Geas is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU General Public License for more details. *
17
* You should have received a copy of the GNU General Public License *
18
* along with Geas; if not, write to the Free Software *
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
***************************************************************************/
23
#include "geas-state.hh"
24
#include "GeasRunner.hh"
25
#include "geas-util.hh"
26
#include "readfile.hh"
36
ostream &operator<< (ostream &o, const map <string, string> &m)
38
for (map <string, string>::const_iterator i = m.begin(); i != m.end(); i ++)
39
o << (*i).first << " -> " << (*i).second << "\n";
43
class GeasOutputStream {
47
GeasOutputStream &put (string s) { o << s; o.put (char (0)); return *this; }
48
GeasOutputStream &put (char ch) { o.put (ch); return *this; }
49
GeasOutputStream &put (int i) { o << i; o.put (char (0)); return *this; }
50
GeasOutputStream &put (uint i) { o << i; o.put (char (0)); return *this; }
51
GeasOutputStream &put (unsigned long i) { o << i; o.put (char (0)); return *this; } // for Mac OS X ...
54
void write_out (string gamename, string savename)
57
ofs.open (savename.c_str());
59
throw string ("Unable to open \"" + savename + "\"");
60
ofs << "QUEST300" << char(0) << gamename << char(0);
62
for (uint i = 0; i < tmp.size(); i ++)
63
ofs << char (255 - tmp[i]);
64
cerr << "Done writing save game\n";
68
template <class T> void write_to (GeasOutputStream &gos, const vector<T> &v)
71
for (uint i = 0; i < v.size(); i ++)
75
void write_to (GeasOutputStream &gos, const PropertyRecord &pr)
77
gos.put (pr.name).put (pr.data);
80
void write_to (GeasOutputStream &gos, const ObjectRecord &pr)
82
gos.put (pr.name).put (char(pr.hidden ? 0 : 1))
83
.put (char(pr.invisible ? 0 : 1)).put (pr.parent);
86
void write_to (GeasOutputStream &gos, const ExitRecord &er)
88
gos.put (er.src).put (er.dest);
91
void write_to (GeasOutputStream &gos, const TimerRecord &tr)
93
gos.put (tr.name).put (tr.is_running ? 0 : 1).put (tr.interval)
98
void write_to (GeasOutputStream &gos, const SVarRecord &svr)
102
for (uint i = 0; i < svr.size(); i ++)
103
gos.put (svr.get(i));
106
void write_to (GeasOutputStream &gos, const IVarRecord &ivr)
110
for (uint i = 0; i < ivr.size(); i ++)
111
gos.put (ivr.get(i));
114
void write_to (GeasOutputStream &gos, const GeasState &gs)
116
gos.put (gs.location);
117
write_to (gos, gs.props);
118
write_to (gos, gs.objs);
119
write_to (gos, gs.exits);
120
write_to (gos, gs.timers);
121
write_to (gos, gs.svars);
122
write_to (gos, gs.ivars);
125
void save_game_to (std::string gamename, std::string savename, const GeasState &gs)
127
GeasOutputStream gos;
129
gos.write_out (gamename, savename);
132
GeasState::GeasState (GeasInterface &gi, const GeasFile &gf)
136
cerr << "GeasState::GeasState()" << endl;
137
for (uint i = 0; i < gf.size ("game"); i ++)
139
//const GeasBlock &go = gf.game[i];
140
//register_block ("game", "game");
145
data.invisible = true;
146
objs.push_back (data);
149
cerr << "GeasState::GeasState() done setting game" << endl;
150
for (uint i = 0; i < gf.size ("room"); i ++)
152
const GeasBlock &go = gf.block ("room", i);
154
//data.name = go.lname;
157
data.hidden = data.invisible = true;
158
//register_block (data.name, "room");
159
objs.push_back (data);
162
cerr << "GeasState::GeasState() done setting rooms" << endl;
163
for (uint i = 0; i < gf.size ("object"); i++)
165
const GeasBlock &go = gf.block ("object", i);
167
//data.name = go.lname;
172
//data.parent = lcase (param_contents (go.parent));
173
data.parent = param_contents (go.parent);
174
//register_block (data.name, "object");
175
data.hidden = data.invisible = false;
176
objs.push_back (data);
179
cerr << "GeasState::GeasState() done setting objects" << endl;
180
for (uint i = 0; i < gf.size("timer"); i ++)
182
const GeasBlock &go = gf.block("timer", i);
183
//cerr << "GS::GS: Handling timer " << go << "\n";
185
string interval = "", status = "";
186
for (uint j = 0; j < go.data.size(); j ++)
188
string line = go.data[j];
190
string tok = first_token (line, c1, c2);
191
if (tok == "interval")
193
tok = next_token (line, c1, c2);
195
gi.debug_print (nonparam ("interval", line));
197
interval = param_contents(tok);
199
else if (tok == "enabled" || tok == "disabled")
202
gi.debug_print ("Repeated status for timer");
206
else if (tok == "action")
211
gi.debug_print ("Bad timer line " + line);
214
//tr.name = go.lname;
216
tr.is_running = (status == "enabled");
217
tr.interval = tr.timeleft = parse_int (interval);
218
//register_block (tr.name, "timer");
219
timers.push_back (tr);
222
cerr << "GeasState::GeasState() done with timers" << endl;
223
for (uint i = 0; i < gf.size("variable"); i ++)
225
const GeasBlock &go (gf.block("variable", i));
226
cerr << "GS::GS: Handling variable #" << i << ": " << go << endl;
229
for (uint j = 0; j < go.data.size(); j ++)
231
string line = go.data[j];
232
cerr << " Line #" << j << " of var: \"" << line << "\"" << endl;
234
string tok = first_token (line, c1, c2);
237
tok = next_token (line, c1, c2);
239
gi.debug_print (string("Missing variable type in ")
240
+ string_geas_block (go));
241
else if (vartype != "")
242
gi.debug_print (string ("Redefining var. type in ")
243
+ string_geas_block (go));
244
else if (tok == "numeric" || tok == "string")
247
gi.debug_print (string ("Bad var. type ") + line);
249
else if (tok == "value")
251
tok = next_token (line, c1, c2);
253
gi.debug_print (string ("Expected parameter in " + line));
255
value = param_contents (tok);
257
else if (tok == "display" || tok == "onchange")
262
gi.debug_print (string ("Bad var. line: ") + line);
265
if (vartype == "" || vartype == "numeric")
268
//ivr.name = go.lname;
270
ivr.set (0, parse_int (value));
271
ivars.push_back (ivr);
272
//register_block (ivr.name, "numeric");
277
//svr.name = go.lname;
280
svars.push_back (svr);
281
//register_block (svr.name, "string");
284
//cerr << obj_types << endl;
285
cerr << "GeasState::GeasState() done with variables" << endl;
288
ostream &operator<< (ostream &o, const PropertyRecord &pr)
290
o << pr.name << ", data == " << pr.data;
294
ostream &operator<< (ostream &o, const ObjectRecord &objr)
296
o << objr.name << ", parent == " << objr.parent;
304
ostream &operator<< (ostream &o, const ExitRecord er)
306
return o << er.src << ": " << er.dest;
309
ostream &operator<< (ostream &o, const TimerRecord &tr)
311
return o << tr.name << ": " << (tr.is_running ? "" : "not ") << "running ("
312
<< tr.timeleft << " // " << tr.interval << ")";
315
ostream &operator<< (ostream &o, const SVarRecord &sr)
317
o << sr.name << ": ";
320
else if (sr.size() <= 1)
321
o << "<" << sr.get(0) << ">";
323
for (uint i = 0; i < sr.size(); i ++)
325
o << i << ": <" << sr.get(i) << ">";
326
if (i + 1 < sr.size())
332
ostream &operator<< (ostream &o, const IVarRecord &ir)
334
o << ir.name << ": ";
337
else if (ir.size() <= 1)
340
for (uint i = 0; i < ir.size(); i ++)
342
o << i << ": " << ir.get(i);
343
if (i + 1 < ir.size())
349
ostream &operator<< (ostream &o, const GeasState &gs)
351
o << "location == " << gs.location << "\nprops: \n";
353
for (uint i = 0; i < gs.props.size(); i ++)
354
o << " " << i << ": " << gs.props[i] << "\n";
357
for (uint i = 0; i < gs.objs.size(); i ++)
358
o << " " << i << ": " << gs.objs[i] << "\n";
361
for (uint i = 0; i < gs.exits.size(); i ++)
362
o << " " << i << ": " << gs.exits[i] << "\n";
365
for (uint i = 0; i < gs.timers.size(); i ++)
366
o << " " << i << ": " << gs.timers[i] << "\n";
368
o << "string variables:\n";
369
for (uint i = 0; i < gs.svars.size(); i ++)
370
o << " " << i << ": " << gs.svars[i] << "\n";
372
o << "integer variables:\n";
373
for (uint i = 0; i < gs.svars.size(); i ++)
374
o << " " << i << ": " << gs.svars[i] << "\n";