/[adonthell]/adonthell/src/rpg/quest.cc
ViewVC logotype

Diff of /adonthell/src/rpg/quest.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by ksterker, Sun Aug 14 16:51:21 2005 UTC revision 1.6 by ksterker, Sun Oct 9 07:38:40 2005 UTC
# Line 1  Line 1 
1  /*  /*
2     $Id$     $Id$
3        
4     Copyright (C) 2004 Kai Sterker <kaisterker@linuxgames.com>     Copyright (C) 2004/2005 Kai Sterker <kaisterker@linuxgames.com>
5     Part of the Adonthell Project http://adonthell.linuxgames.com     Part of the Adonthell Project http://adonthell.linuxgames.com
6    
7     Adonthell is free software; you can redistribute it and/or modify     Adonthell is free software; you can redistribute it and/or modify
# Line 31  Line 31 
31  #include "base/base.h"  #include "base/base.h"
32  #include "base/diskio.h"  #include "base/diskio.h"
33  #include "python/python.h"  #include "python/python.h"
34    #include "event/manager.h"
35    #include "rpg/quest_event.h"
36    
37  using rpg::quest;  using rpg::quest;
38  using rpg::quest_part;  using rpg::quest_part;
39    using rpg::quest_event;
40    
41  // ctor  // ctor
42  quest_part::quest_part (const std::string & id)  quest_part::quest_part (const std::string & id, quest_part *parent)
43  {  {
44      Id = id;      Id = id;
45      Code = "";      Code = "";
46      Entry = NULL;      Parent = parent;
     Parent = NULL;  
47      Started = false;      Started = false;
48      Completed = false;      Completed = false;
49        EntryOnStart = NULL;
50            EntryOnCompl = NULL;
51            
52            if (Parent != NULL)
53                    Parent->add_child (this);
54  }  }
55    
56  // dtor  // dtor
# Line 52  quest_part::~quest_part () Line 59  quest_part::~quest_part ()
59      std::map<std::string, quest_part*>::iterator q;      std::map<std::string, quest_part*>::iterator q;
60      for (q = Children.begin (); q != Children.end (); q++)      for (q = Children.begin (); q != Children.end (); q++)
61          delete (*q).second;          delete (*q).second;
62                    
63            delete EntryOnStart;
64            delete EntryOnCompl;
65  }  }
66    
67  // set a step to completed  // set a step to completed
# Line 60  bool quest_part::set_completed () Line 70  bool quest_part::set_completed ()
70      // only steps can be completed that way      // only steps can be completed that way
71      if (!Children.empty ()) return false;      if (!Children.empty ()) return false;
72            
73      Completed = true;          // set state to started and completed
74      Started = true;      update ();
   
     // update parent, if it has one  
     if (Parent != NULL) Parent->update ();  
75            
76      return true;      return true;
77  }  }
# Line 82  const quest_part *quest_part::child (con Line 89  const quest_part *quest_part::child (con
89      return NULL;      return NULL;
90  }  }
91    
92    // add a quest to list of quests
93    void quest_part::add_child (quest_part *part)
94    {
95        std::map<std::string, quest_part*>::iterator q;
96        if ((q = Children.find (part->id ())) != Children.end ())
97        {
98            delete (*q).second;
99            (*q).second = part;
100        }
101        else Children[part->id ()] = part;
102    }
103    
104    
105  // update state of a quest part from state of its children  // update state of a quest part from state of its children
106  void quest_part::update ()  void quest_part::update ()
107  {  {
# Line 119  void quest_part::update () Line 139  void quest_part::update ()
139          if (Completed == true) changed = true;          if (Completed == true) changed = true;
140      }      }
141            
142      // if state changed, update parent too          if (changed)
143      if (Parent != NULL && changed) Parent->update ();          {
144                    // fire quest event
145                    quest_event evt (full_name(), this);
146                    events::manager::raise_event (&evt);
147                    
148                    // if state changed, update parent too
149                    if (Parent != NULL) Parent->update ();
150            }
151  }  }
152    
153  // calculate the state of completion with given code  // calculate the state of completion with given code
154  bool quest_part::evaluate ()  bool quest_part::evaluate ()
155  {  {
156      std::string code = "", token = 0;      std::string code = "", token = "";
157      std::map<std::string, quest_part*>::iterator child;      std::map<std::string, quest_part*>::iterator child;
158    
159      // prepare code for evaluation, replacing all references to quest parts with      // prepare code for evaluation, replacing all references to quest parts with
160      // their state of completion      // their state of completion
161      for (std::string::const_iterator i = Code.begin (); i != Code.end (); i++)      for (const char *cptr = Code.c_str(); *cptr != '\0'; cptr++)
162      {      {
163          if (!isalnum (*i))          if (!isalnum (*cptr) && *cptr != '_')
164          {          {
165              // check if we have just read a new token              // check if we have just read a new token
166              if (token != "")              if (token != "")
167              {              {
168                  // check if the token we read is a quest_part                  // check if the token we read is a quest_part
169                  if ((child = Children.find (token)) != Children.end ())                  if ((child = Children.find (token)) != Children.end ())
170                      // if so, add it's state of completion to the code                      // if so, add its state of completion to the code
171                      code += (*child).second->is_completed () ? '1' : '0';                      code += (*child).second->is_completed () ? '1' : '0';
172                  else                  else
173                      // otherwise assume the token is part of the code                      // otherwise assume the token is part of the code
# Line 149  bool quest_part::evaluate () Line 176  bool quest_part::evaluate ()
176                  // reset token                  // reset token
177                  token = "";                  token = "";
178              }              }
179              code += *i;                          code += *cptr;
180          }          }
181          else token += *i;          else token += *cptr;
182      }      }
183            
184      // now try to evaluate our code snippet      // now try to evaluate our code snippet
# Line 169  bool quest_part::evaluate () Line 196  bool quest_part::evaluate ()
196      return completed;      return completed;
197  }  }
198    
199    
200    // get full name of this quest part
201    std::string quest_part::full_name () const
202    {
203            if (Parent != NULL) return Parent->full_name() + std::string(".") + Id;
204            return Id;
205    }
206    
207  // save quest_part  // save quest_part
208  void quest_part::put_state (base::flat & out) const  void quest_part::put_state (base::flat & out) const
209  {  {
210      base::flat record;      base::flat record;
211            
212            // id needs be saved here only for quest root
213            if (Parent == NULL) record.put_string ("qid", Id);
214    
215      // save attributes      // save attributes
     record.put_string ("qid", Id);  
216      record.put_bool ("qst", Started);      record.put_bool ("qst", Started);
217      record.put_bool ("qcp", Completed);      record.put_bool ("qcp", Completed);
218      record.put_string ("qcd", Code);      record.put_string ("qcd", Code);
219            
220      // save associated log entry      // save associated log entries
221      record.put_bool ("qhe", Entry != NULL);      record.put_bool ("qse", EntryOnStart != NULL);
222      if (Entry) Entry->put_state (record);      if (EntryOnStart) EntryOnStart->put_state (record);
223        record.put_bool ("qce", EntryOnCompl != NULL);
224        if (EntryOnCompl) EntryOnCompl->put_state (record);
225    
226      // save child quest parts      // save child quest parts
227      std::map<std::string, quest_part*>::const_iterator i;      std::map<std::string, quest_part*>::const_iterator i;
228      record.put_uint16 ("qnc", Children.size ());      record.put_uint16 ("qnc", Children.size ());
229      for (i = Children.begin (); i != Children.end (); i++)      for (i = Children.begin (); i != Children.end (); i++)
230            {
231                record.put_string ("qid", (*i).second->id ());
232          (*i).second->put_state (record);          (*i).second->put_state (record);
233                    }
234            
235      // save this quest part to stream      // save this quest part to stream
236      out.put_flat ("q", record);      out.put_flat ("q", record);
237  }  }
# Line 200  bool quest_part::get_state (base::flat & Line 242  bool quest_part::get_state (base::flat &
242      base::flat record = in.get_flat ("q");      base::flat record = in.get_flat ("q");
243      if (!in.success ()) return false;      if (!in.success ()) return false;
244    
245            // id needs to be loaded only for quest root
246            if (Parent == NULL) Id = record.get_string ("qid");
247    
248      // get attributes      // get attributes
     Id = record.get_string ("qid");  
249      Started = record.get_bool ("qst");      Started = record.get_bool ("qst");
250      Completed = record.get_bool ("qcp");      Completed = record.get_bool ("qcp");
251      Code = record.get_string ("qcd");      Code = record.get_string ("qcd");
252    
253      // get log entry, if any      // get log entry for quest start, if any
254      if (record.get_bool ("qhe") == true)      if (record.get_bool ("qse") == true)
255      {      {
256          Entry = new rpg::log_entry ("", "", "");          EntryOnStart = new rpg::log_entry ("", "", "");
257          Entry->get_state (record);          EntryOnStart->get_state (record);
258        }
259    
260        // get log entries for quest completion, if any
261        if (record.get_bool ("qce") == true)
262        {
263            EntryOnCompl = new rpg::log_entry ("", "", "");
264            EntryOnCompl->get_state (record);
265      }      }
266    
267      // get children, if any      // get children, if any
268      quest_part *part;      quest_part *part;
269      for (u_int16 i = record.get_uint16 ("qhc"); i > 0; i--)      for (u_int16 i = record.get_uint16 ("qnc"); i > 0; i--)
270      {      {
271          part = new quest_part ("");                  string id = record.get_string ("qid");
272    
273            part = new quest_part (id, this);
274          part->get_state (record);          part->get_state (record);
         part->Parent = this;  
         Children[part->Id] = part;  
275      }      }
276            
277      return record.success ();      return record.success ();
# Line 237  void quest::cleanup () Line 288  void quest::cleanup ()
288          delete (*q).second;          delete (*q).second;
289  }  }
290    
291  // check wether a given quest (step) has been started  // check whether a given quest (step) has been started
292  bool quest::is_started (const std::string & id)  bool quest::is_started (const std::string & id)
293  {  {
294      const quest_part *part = get_part (id);      const quest_part *part = get_part (id);
# Line 245  bool quest::is_started (const std::strin Line 296  bool quest::is_started (const std::strin
296      return false;      return false;
297  }  }
298    
299  // check wether a given quest (step) has been completed  // check whether a given quest (step) has been completed
300  bool quest::is_completed (const std::string & id)  bool quest::is_completed (const std::string & id)
301  {  {
302      const quest_part *part = get_part (id);      const quest_part *part = get_part (id);
# Line 253  bool quest::is_completed (const std::str Line 304  bool quest::is_completed (const std::str
304      return false;      return false;
305  }  }
306    
307  // check wether a given quest (step) is in progress  // check whether a given quest (step) is in progress
308  bool quest::in_progress (const std::string & id)  bool quest::in_progress (const std::string & id)
309  {  {
310      const quest_part *part = get_part (id);      const quest_part *part = get_part (id);
# Line 302  bool quest::get_state () Line 353  bool quest::get_state ()
353  {  {
354      // open file      // open file
355      base::igzstream in;      base::igzstream in;
356      if (!base::Paths.open (in, QUEST_DATA));      if (!base::Paths.open (in, QUEST_DATA))
357      {      {
358          fprintf (stderr, "*** quest::put_state: cannot open '" QUEST_DATA "' for reading!\n");          fprintf (stderr, "*** quest::get_state: cannot open '" QUEST_DATA "' for reading!\n");
359          return false;          return false;
360      }      }
361            
# Line 324  bool quest::get_state (base::flat & in) Line 375  bool quest::get_state (base::flat & in)
375            
376      for (int i = 0; i < size; i++)      for (int i = 0; i < size; i++)
377      {      {
378          part = new quest_part ("");          part = new quest_part ("", NULL);
379          if (part->get_state (in)) add (part);          if (part->get_state (in)) add (part);
380      }      }
381            
# Line 354  const quest_part* quest::get_part (const Line 405  const quest_part* quest::get_part (const
405      if ((q = Quests.find (*i)) != Quests.end ())      if ((q = Quests.find (*i)) != Quests.end ())
406          part = (*q).second;          part = (*q).second;
407      else      else
408          fprintf (stderr, "*** quest::get_part: quest '%s' no found!\n", (*i).c_str ());          fprintf (stderr, "*** quest::get_part: quest '%s' not found!\n", (*i).c_str ());
409            
410      for (i = i++; i != result.end () && part != NULL; i++)      for (i++; i != result.end () && part != NULL; i++)
411          part = part->child (*i);          part = part->child (*i);
412    
413      return part;      return part;

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26