Pol  Revision:cb584c9
npctemplates.cpp
Go to the documentation of this file.
1 
9 #include <exception>
10 #include <stdexcept>
11 #include <string.h>
12 #include <string>
13 
14 #include <format/format.h>
15 #include "../clib/cfgelem.h"
16 #include "../clib/cfgfile.h"
17 #include "../clib/clib.h"
18 #include "../clib/fileutil.h"
19 #include "../clib/logfacility.h"
20 #include "../plib/pkg.h"
21 #include "../plib/systemstate.h"
22 #include "globals/uvars.h"
23 #include "npctmpl.h"
24 
25 
26 namespace Pol
27 {
28 namespace Core
29 {
31  : _filename( cf.filename() ), _fileline( cf.element_line_start() ){};
34 {
35  return _filename.capacity() + sizeof( unsigned int );
36 }
37 void NpcTemplateConfigSource::display_error( const std::string& msg, bool /*show_curline*/,
38  const Clib::ConfigElemBase* elem, bool error ) const
39 {
40  bool showed_elem_line = false;
41 
42  fmt::Writer tmp;
43  tmp << ( error ? "Error" : "Warning" ) << " reading configuration file " << _filename << ":\n";
44 
45  tmp << "\t" << msg << "\n";
46 
47  if ( elem != nullptr )
48  {
49  if ( strlen( elem->type() ) > 0 )
50  {
51  tmp << "\tElement: " << elem->type() << " " << elem->rest();
52  if ( _fileline )
53  tmp << ", found on line " << _fileline;
54  tmp << "\n";
55  showed_elem_line = true;
56  }
57  }
58 
59  // if (show_curline)
60  // cerr << "\tNear line: " << _cur_line << endl;
61  if ( _fileline && !showed_elem_line )
62  tmp << "\tElement started on line: " << _fileline << "\n";
63  ERROR_PRINT << tmp.str();
64 }
65 
66 
69  : _source( cf ), _elem( elem )
70 {
71 }
72 
74 {
75  elem = _elem;
76  elem.set_source( &_source );
77 }
78 
80 {
81  size_t size = sizeof( NpcTemplateElem ) + _source.estimateSize() + _elem.estimateSize();
82  return size;
83 }
84 
85 
86 bool FindNpcTemplate( const char* template_name, Clib::ConfigElem& elem )
87 {
88  auto itr = gamestate.npc_template_elems.find( template_name );
89  if ( itr != gamestate.npc_template_elems.end() )
90  {
91  const NpcTemplateElem& tm = ( *itr ).second;
92  tm.copyto( elem );
93  return true;
94  }
95  else
96  {
97  return false;
98  }
99 }
100 
101 // FIXME inefficient. Templates should be read in once, and reused.
102 bool FindNpcTemplate( const char* template_name, Clib::ConfigFile& cf, Clib::ConfigElem& elem )
103 {
104  try
105  {
106  const Plib::Package* pkg;
107  std::string npctemplate;
108  if ( !Plib::pkgdef_split( template_name, nullptr, &pkg, &npctemplate ) )
109  return false;
110 
111  std::string filename =
112  Plib::GetPackageCfgPath( const_cast<Plib::Package*>( pkg ), "npcdesc.cfg" );
113 
114  cf.open( filename.c_str() );
115  while ( cf.read( elem ) )
116  {
117  if ( !elem.type_is( "NpcTemplate" ) )
118  continue;
119 
120  std::string orig_rest = elem.rest();
121  if ( pkg != nullptr )
122  {
123  std::string newrest = ":" + pkg->name() + ":" + npctemplate;
124  elem.set_rest( newrest.c_str() );
125  }
126  const char* rest = elem.rest();
127  if ( rest != nullptr && *rest != '\0' )
128  {
129  if ( stricmp( orig_rest.c_str(), npctemplate.c_str() ) == 0 )
130  return true;
131  }
132  else
133  {
134  std::string tname = elem.remove_string( "TemplateName" );
135  if ( stricmp( tname.c_str(), npctemplate.c_str() ) == 0 )
136  return true;
137  }
138  }
139  return false;
140  }
141  catch ( const char* msg )
142  {
143  ERROR_PRINT << "NPC Creation (" << template_name << ") Failed: " << msg << "\n";
144  }
145  catch ( std::string& str )
146  {
147  ERROR_PRINT << "NPC Creation (" << template_name << ") Failed: " << str << "\n";
148  } // egcs has some trouble realizing 'exception' should catch
149  catch ( std::runtime_error& re ) // runtime_errors, so...
150  {
151  ERROR_PRINT << "NPC Creation (" << template_name << ") Failed: " << re.what() << "\n";
152  }
153  catch ( std::exception& ex )
154  {
155  ERROR_PRINT << "NPC Creation (" << template_name << ") Failed: " << ex.what() << "\n";
156  }
157 #ifndef WIN32
158  catch ( ... )
159  {
160  }
161 #endif
162  return false;
163 }
164 
166 {
167  std::string filename = GetPackageCfgPath( pkg, "npcdesc.cfg" );
168  if ( !Clib::FileExists( filename ) )
169  return;
170 
171  Clib::ConfigFile cf( filename.c_str() );
172  Clib::ConfigElem elem;
173  while ( cf.read( elem ) )
174  {
175  if ( elem.type_is( "NpcTemplate" ) )
176  {
177  // first determine the NPC template name.
178  std::string namebase;
179  const char* rest = elem.rest();
180  if ( rest != nullptr && *rest != '\0' )
181  {
182  namebase = rest;
183  }
184  else
185  {
186  namebase = elem.remove_string( "TemplateName" );
187  }
188  std::string descname;
189  if ( pkg != nullptr )
190  {
191  descname = ":" + pkg->name() + ":" + namebase;
192  elem.set_rest( descname.c_str() );
193  }
194  else
195  descname = namebase;
196 
197  gamestate.npc_template_elems[descname] = NpcTemplateElem( cf, elem );
198  }
199  }
200 }
201 
203 {
205  read_npc_templates( nullptr );
206  for ( auto& pkg : Plib::systemstate.packages )
207  {
208  read_npc_templates( pkg );
209  }
210 }
211 }
212 }
std::string remove_string(const char *propname)
Definition: cfgfile.cpp:381
SystemState systemstate
Definition: systemstate.cpp:12
bool FindNpcTemplate(const char *template_name, Clib::ConfigElem &elem)
const std::string & name() const
Definition: pkg.h:83
void copyto(Clib::ConfigElem &elem) const
NpcTemplateConfigSource _source
Definition: npctmpl.h:86
const char * rest() const
Definition: cfgfile.cpp:71
bool pkgdef_split(const std::string &spec, const Package *inpkg, const Package **outpkg, std::string *path)
Definition: pkg.cpp:410
virtual void display_error(const std::string &msg, bool show_curline=true, const Clib::ConfigElemBase *elem=nullptr, bool error=true) const POL_OVERRIDE
void read_npc_templates()
virtual size_t estimateSize() const POL_OVERRIDE
Definition: cfgfile.cpp:57
NpcTemplatesElems npc_template_elems
Definition: uvars.h:140
GameState gamestate
Definition: uvars.cpp:74
void open(const char *i_filename)
Definition: cfgfile.cpp:600
bool type_is(const char *name) const
Definition: cfgfile.cpp:95
Clib::ConfigElem _elem
Definition: npctmpl.h:87
std::string GetPackageCfgPath(const Package *pkg, const std::string &filename)
Definition: pkg.cpp:491
void set_source(const ConfigElem &elem)
Definition: cfgfile.cpp:86
#define ERROR_PRINT
Definition: logfacility.h:230
bool FileExists(const char *filename)
Definition: fileutil.cpp:118
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
const char * type() const
Definition: cfgfile.cpp:66
void set_rest(const char *newrest)
Definition: cfgfile.cpp:76
size_t estimateSize() const
Definition: berror.cpp:12