~ubuntu-branches/ubuntu/wily/gargoyle-free/wily-proposed

« back to all changes in this revision

Viewing changes to terps/geas/geas-state.cc

  • Committer: Bazaar Package Importer
  • Author(s): Sylvain Beucler
  • Date: 2009-09-11 20:09:43 UTC
  • Revision ID: james.westby@ubuntu.com-20090911200943-idgzoyupq6650zpn
Tags: upstream-2009-08-25
ImportĀ upstreamĀ versionĀ 2009-08-25

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *                                                                         *
 
3
 * Copyright (C) 2006 by Mark J. Tilford                                   *
 
4
 *                                                                         *
 
5
 * This file is part of Geas.                                              *
 
6
 *                                                                         *
 
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.                                     *
 
11
 *                                                                         *
 
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.                            *
 
16
 *                                                                         *
 
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
 
20
 *                                                                         *
 
21
 ***************************************************************************/
 
22
 
 
23
#include "geas-state.hh"
 
24
#include "GeasRunner.hh"
 
25
#include "geas-util.hh"
 
26
#include "readfile.hh"
 
27
#include "general.hh"
 
28
 
 
29
#include <sstream>
 
30
#include <ostream>
 
31
#include <fstream>
 
32
#include <iostream>
 
33
 
 
34
using namespace std;
 
35
 
 
36
ostream &operator<< (ostream &o, const map <string, string> &m)
 
37
{
 
38
  for (map <string, string>::const_iterator i = m.begin(); i != m.end(); i ++)
 
39
    o << (*i).first << " -> " << (*i).second << "\n";
 
40
  return o;
 
41
}
 
42
 
 
43
class GeasOutputStream { 
 
44
  ostringstream o; 
 
45
  
 
46
public: 
 
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 ...
 
52
  
 
53
 
 
54
  void write_out (string gamename, string savename)
 
55
  {
 
56
    ofstream ofs;
 
57
    ofs.open (savename.c_str());
 
58
    if (!ofs.is_open())
 
59
      throw string ("Unable to open \"" + savename + "\"");
 
60
    ofs << "QUEST300" << char(0) << gamename << char(0);
 
61
    string tmp = o.str();
 
62
    for (uint i = 0; i < tmp.size(); i ++)
 
63
      ofs << char (255 - tmp[i]);
 
64
    cerr << "Done writing save game\n";
 
65
  }
 
66
};
 
67
 
 
68
template <class T> void write_to (GeasOutputStream &gos, const vector<T> &v) 
 
69
 
70
  gos.put(v.size());
 
71
  for (uint i = 0; i < v.size(); i ++)
 
72
    write_to (gos, v[i]);
 
73
}
 
74
  
 
75
void write_to (GeasOutputStream &gos, const PropertyRecord &pr)
 
76
{
 
77
  gos.put (pr.name).put (pr.data);
 
78
}
 
79
 
 
80
void write_to (GeasOutputStream &gos, const ObjectRecord &pr)
 
81
{
 
82
  gos.put (pr.name).put (char(pr.hidden ? 0 : 1))
 
83
    .put (char(pr.invisible ? 0 : 1)).put (pr.parent);
 
84
}
 
85
 
 
86
void write_to (GeasOutputStream &gos, const ExitRecord &er)
 
87
{
 
88
  gos.put (er.src).put (er.dest);
 
89
}
 
90
 
 
91
void write_to (GeasOutputStream &gos, const TimerRecord &tr)
 
92
{
 
93
  gos.put (tr.name).put (tr.is_running ? 0 : 1).put (tr.interval)
 
94
    .put (tr.timeleft);
 
95
}
 
96
 
 
97
 
 
98
void write_to (GeasOutputStream &gos, const SVarRecord &svr)
 
99
{
 
100
  gos.put (svr.name);
 
101
  gos.put (svr.max());
 
102
  for (uint i = 0; i < svr.size(); i ++)
 
103
    gos.put (svr.get(i));
 
104
}
 
105
 
 
106
void write_to (GeasOutputStream &gos, const IVarRecord &ivr)
 
107
{
 
108
  gos.put (ivr.name);
 
109
  gos.put (ivr.max());
 
110
  for (uint i = 0; i < ivr.size(); i ++)
 
111
    gos.put (ivr.get(i));
 
112
}
 
113
 
 
114
void write_to (GeasOutputStream &gos, const GeasState &gs)
 
115
{
 
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);
 
123
}
 
124
 
 
125
void save_game_to (std::string gamename, std::string savename, const GeasState &gs)
 
126
{
 
127
  GeasOutputStream gos;
 
128
  write_to (gos, gs);
 
129
  gos.write_out (gamename, savename);
 
130
}
 
131
 
 
132
GeasState::GeasState (GeasInterface &gi, const GeasFile &gf)
 
133
{
 
134
  running = false;
 
135
 
 
136
  cerr << "GeasState::GeasState()" << endl;
 
137
  for (uint i = 0; i < gf.size ("game"); i ++)
 
138
    {
 
139
      //const GeasBlock &go = gf.game[i];
 
140
      //register_block ("game", "game");
 
141
      ObjectRecord data;
 
142
      data.name = "game";
 
143
      data.parent = "";
 
144
      data.hidden = false;
 
145
      data.invisible = true;
 
146
      objs.push_back (data);
 
147
    }
 
148
 
 
149
  cerr << "GeasState::GeasState() done setting game" << endl;
 
150
  for (uint i = 0; i < gf.size ("room"); i ++)
 
151
    {
 
152
      const GeasBlock &go = gf.block ("room", i);
 
153
      ObjectRecord data;
 
154
      //data.name = go.lname;
 
155
      data.name = go.name;
 
156
      data.parent = "";
 
157
      data.hidden = data.invisible = true;
 
158
      //register_block (data.name, "room");
 
159
      objs.push_back (data);
 
160
    }
 
161
 
 
162
  cerr << "GeasState::GeasState() done setting rooms" << endl;
 
163
  for (uint i = 0; i < gf.size ("object"); i++)
 
164
    {
 
165
      const GeasBlock &go = gf.block ("object", i);
 
166
      ObjectRecord data;
 
167
      //data.name = go.lname;
 
168
      data.name = go.name;
 
169
      if (go.parent == "")
 
170
        data.parent = "";
 
171
      else
 
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);
 
177
    }
 
178
 
 
179
  cerr << "GeasState::GeasState() done setting objects" << endl;
 
180
  for (uint i = 0; i < gf.size("timer"); i ++)
 
181
    {
 
182
      const GeasBlock &go = gf.block("timer", i);
 
183
      //cerr << "GS::GS: Handling timer " << go << "\n";
 
184
      TimerRecord tr;
 
185
      string interval = "", status = "";
 
186
      for (uint j = 0; j < go.data.size(); j ++)
 
187
        {
 
188
          string line = go.data[j];
 
189
          uint c1, c2;
 
190
          string tok = first_token (line, c1, c2);
 
191
          if (tok == "interval")
 
192
            {
 
193
              tok = next_token (line, c1, c2);
 
194
              if (!is_param (tok))
 
195
                gi.debug_print (nonparam ("interval", line));
 
196
              else
 
197
                interval = param_contents(tok);
 
198
            }
 
199
          else if (tok == "enabled" || tok == "disabled")
 
200
            {
 
201
              if (status != "")
 
202
                gi.debug_print ("Repeated status for timer");
 
203
              else
 
204
                    status = tok;
 
205
            }
 
206
          else if (tok == "action")
 
207
            {
 
208
            }
 
209
          else
 
210
            {
 
211
              gi.debug_print ("Bad timer line " + line);
 
212
            }
 
213
        }
 
214
      //tr.name = go.lname;
 
215
      tr.name = go.name;
 
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);
 
220
    }
 
221
 
 
222
  cerr << "GeasState::GeasState() done with timers" << endl;
 
223
  for (uint i = 0; i < gf.size("variable"); i ++)
 
224
    {
 
225
      const GeasBlock &go (gf.block("variable", i));
 
226
      cerr << "GS::GS: Handling variable #" << i << ": " << go << endl;
 
227
      string vartype;
 
228
      string value;
 
229
      for (uint j = 0; j < go.data.size(); j ++)
 
230
        {
 
231
          string line = go.data[j];
 
232
          cerr << "   Line #" << j << " of var: \"" << line << "\"" << endl;
 
233
          uint c1, c2;
 
234
          string tok = first_token (line, c1, c2);
 
235
          if (tok == "type")
 
236
            {
 
237
              tok = next_token (line, c1, c2);
 
238
              if (tok == "")
 
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")
 
245
                vartype = tok;
 
246
              else
 
247
                gi.debug_print (string ("Bad var. type ") + line);
 
248
            }
 
249
          else if (tok == "value")
 
250
            {
 
251
              tok = next_token (line, c1, c2);
 
252
              if (!is_param (tok))
 
253
                gi.debug_print (string ("Expected parameter in " + line));
 
254
              else
 
255
                value = param_contents (tok);
 
256
            }
 
257
          else if (tok == "display" || tok == "onchange")
 
258
            {
 
259
            }
 
260
          else
 
261
            {
 
262
              gi.debug_print (string ("Bad var. line: ") + line);
 
263
            }
 
264
        }
 
265
      if (vartype == "" || vartype == "numeric")
 
266
        {
 
267
          IVarRecord ivr;
 
268
          //ivr.name = go.lname;
 
269
          ivr.name = go.name;
 
270
          ivr.set (0, parse_int (value));
 
271
          ivars.push_back (ivr);
 
272
          //register_block (ivr.name, "numeric");
 
273
        }
 
274
      else
 
275
        {
 
276
          SVarRecord svr;
 
277
          //svr.name = go.lname;
 
278
          svr.name = go.name;
 
279
          svr.set (0, value);
 
280
          svars.push_back (svr);
 
281
          //register_block (svr.name, "string");
 
282
        }
 
283
    }
 
284
  //cerr << obj_types << endl;
 
285
  cerr << "GeasState::GeasState() done with variables" << endl;
 
286
}
 
287
 
 
288
ostream &operator<< (ostream &o, const PropertyRecord &pr) 
 
289
 
290
  o << pr.name << ", data == " << pr.data; 
 
291
  return o; 
 
292
}
 
293
 
 
294
ostream &operator<< (ostream &o, const ObjectRecord &objr) 
 
295
 
296
  o << objr.name << ", parent == " << objr.parent; 
 
297
  if (objr.hidden) 
 
298
    o << ", hidden"; 
 
299
  if (objr.invisible)
 
300
    o << ", invisible";
 
301
  return o; 
 
302
}
 
303
 
 
304
ostream &operator<< (ostream &o, const ExitRecord er) 
 
305
 
306
  return o << er.src << ": " << er.dest;
 
307
}
 
308
 
 
309
ostream &operator<< (ostream &o, const TimerRecord &tr) 
 
310
{
 
311
  return o << tr.name << ": " << (tr.is_running ? "" : "not ") << "running (" 
 
312
           << tr.timeleft << " // " << tr.interval << ")"; 
 
313
}
 
314
 
 
315
ostream &operator<< (ostream &o, const SVarRecord &sr) 
 
316
 
317
  o << sr.name << ": ";
 
318
  if (sr.size () == 0)
 
319
    o << "(empty)";
 
320
  else if (sr.size() <= 1)
 
321
    o << "<" << sr.get(0) << ">";
 
322
  else
 
323
    for (uint i = 0; i < sr.size(); i ++)
 
324
      {
 
325
        o << i << ": <" << sr.get(i) << ">";
 
326
        if (i + 1 < sr.size())
 
327
          o << ", ";
 
328
      }
 
329
  return o;
 
330
}
 
331
 
 
332
ostream &operator<< (ostream &o, const IVarRecord &ir) 
 
333
 
334
  o << ir.name << ": ";
 
335
  if (ir.size () == 0)
 
336
    o << "(empty)";
 
337
  else if (ir.size() <= 1)
 
338
    o << ir.get(0);
 
339
  else
 
340
    for (uint i = 0; i < ir.size(); i ++)
 
341
      {
 
342
        o << i << ": " << ir.get(i);
 
343
        if (i + 1 < ir.size())
 
344
          o << ", ";
 
345
      }
 
346
  return o;
 
347
}
 
348
 
 
349
ostream &operator<< (ostream &o, const GeasState &gs)
 
350
{
 
351
  o << "location == " << gs.location << "\nprops: \n";
 
352
 
 
353
  for (uint i = 0; i < gs.props.size(); i ++)
 
354
    o << "    " << i << ": " << gs.props[i] << "\n";
 
355
 
 
356
  o << "objs:\n";
 
357
  for (uint i = 0; i < gs.objs.size(); i ++)
 
358
    o << "    " << i << ": " << gs.objs[i] << "\n";
 
359
 
 
360
  o << "exits:\n";
 
361
  for (uint i = 0; i < gs.exits.size(); i ++)
 
362
    o << "    " << i << ": " << gs.exits[i] << "\n";
 
363
 
 
364
  o << "timers:\n";
 
365
  for (uint i = 0; i < gs.timers.size(); i ++)
 
366
    o << "    " << i << ": " << gs.timers[i] << "\n";
 
367
 
 
368
  o << "string variables:\n";
 
369
  for (uint i = 0; i < gs.svars.size(); i ++)
 
370
    o << "    " << i << ": " << gs.svars[i] << "\n";
 
371
 
 
372
  o << "integer variables:\n";
 
373
  for (uint i = 0; i < gs.svars.size(); i ++)
 
374
    o << "    " << i << ": " << gs.svars[i] << "\n";
 
375
 
 
376
  return o;
 
377
}