Pol  Revision:cb584c9
npctmpl.cpp
Go to the documentation of this file.
1 
8 #include "npctmpl.h"
9 
10 #include <format/format.h>
11 #include "../clib/cfgelem.h"
12 #include "../clib/cfgfile.h"
13 #include "../clib/fileutil.h"
14 #include "../clib/logfacility.h"
15 #include "../plib/pkg.h"
16 #include "../plib/systemstate.h"
17 #include "globals/uvars.h"
18 #include "item/armor.h"
19 #include "item/equipmnt.h"
20 #include "item/weapon.h"
21 #include "syshookscript.h"
22 
23 namespace Pol
24 {
25 namespace Core
26 {
28 {
29  const char* name;
30  int value;
31 };
32 
33 int translate( const std::string& name, TRANSLATION* table )
34 {
35  for ( int i = 0; table[i].name; ++i )
36  {
37  if ( table[i].name == name )
38  return table[i].value;
39  }
40  fmt::Writer tmp;
41  tmp << "Unable to translate value '" << name << "'\n";
42  tmp << " Expected one of the following values:\n";
43  for ( int i = 0; table[i].name; ++i )
44  {
45  tmp << " " << table[i].name << "\n";
46  }
47  ERROR_PRINT << tmp.str();
48  throw std::runtime_error( "Unable to translate value" );
49  return 0;
50 }
51 
53  {"neutral", NpcTemplate::NEUTRAL},
54  {"evil", NpcTemplate::EVIL},
55  {0, 0}};
56 
57 
59  : intrinsic_weapon( static_cast<Items::UWeapon*>(
60  Items::find_intrinsic_equipment( elem.rest(), LAYER_HAND1 ) ) ),
61  intrinsic_shield( static_cast<Items::UArmor*>(
62  Items::find_intrinsic_equipment( elem.rest(), LAYER_HAND2 ) ) ),
63  pkg( pkg ),
64  // script( elem.read_string( "SCRIPT" ) ),
65  alignment( static_cast<ALIGNMENT>(
66  translate( elem.read_string( "ALIGNMENT", "neutral" ), xlate_align ) ) ),
67  method_script( nullptr )
68 {
69  if ( pkg == nullptr )
70  {
71  name = elem.rest();
72  }
73  else
74  {
75  if ( elem.rest()[0] == ':' )
76  {
77  name = elem.rest();
78  }
79  else
80  {
81  name = ":" + pkg->name() + ":" + elem.rest();
82  }
83  }
84 
85  if ( elem.has_prop( "MethodScript" ) )
86  {
87  std::string temp = elem.read_string( "MethodScript" );
88  if ( !temp.empty() )
89  {
90  ExportScript* shs = new ExportScript( pkg, temp );
91  if ( shs->Initialize() )
92  method_script = shs;
93  else
94  delete shs;
95  }
96  }
97 }
98 
100 {
101  if ( method_script != nullptr )
102  {
103  delete method_script;
104  method_script = nullptr;
105  }
106 }
107 
109 {
110  size_t size = sizeof( NpcTemplate );
111  size += name.capacity();
112  if ( method_script != nullptr )
113  size += method_script->estimateSize();
114  return size;
115 }
116 
118 {
119  NpcTemplate* tmpl = new NpcTemplate( elem, pkg );
120  gamestate.npc_templates[tmpl->name] = tmpl;
121  return *tmpl;
122 }
123 
125 {
126  if ( Clib::FileExists( "config/npcdesc.cfg" ) )
127  {
128  Clib::ConfigFile cf( "config/npcdesc.cfg" );
129  Clib::ConfigElem elem;
130  while ( cf.read( elem ) )
131  {
132  create_npc_template( elem, nullptr );
133  }
134  }
135 
136  for ( Plib::Packages::iterator itr = Plib::systemstate.packages.begin();
137  itr != Plib::systemstate.packages.end(); ++itr )
138  {
139  Plib::Package* pkg = ( *itr );
140  std::string filename = Plib::GetPackageCfgPath( pkg, "npcdesc.cfg" );
141 
142  if ( Clib::FileExists( filename.c_str() ) )
143  {
144  Clib::ConfigFile cf( filename.c_str() );
145  Clib::ConfigElem elem;
146  while ( cf.read( elem ) )
147  {
148  create_npc_template( elem, pkg );
149  }
150  }
151  }
152 }
153 
155 {
156  NpcTemplates::const_iterator itr = gamestate.npc_templates.find( elem.rest() );
157  if ( itr != gamestate.npc_templates.end() )
158  {
159  return *( ( *itr ).second );
160  }
161  else
162  {
163  const Plib::Package* pkg;
164  std::string path;
165  if ( Plib::pkgdef_split( elem.rest(), nullptr, &pkg, &path ) )
166  {
167  return create_npc_template( elem, pkg );
168  }
169  else
170  {
171  throw std::runtime_error( std::string( "Error reading NPC template name " ) + elem.rest() );
172  }
173  }
174 }
175 }
176 }
NpcTemplates npc_templates
Definition: uvars.h:139
size_t estimateSize() const
Definition: npctmpl.cpp:108
const Plib::Package * pkg
Definition: npctmpl.h:41
const NpcTemplate & create_npc_template(const Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: npctmpl.cpp:117
TRANSLATION xlate_align[]
Definition: npctmpl.cpp:52
SystemState systemstate
Definition: systemstate.cpp:12
const char * name
Definition: npctmpl.cpp:29
const std::string & name() const
Definition: pkg.h:83
const NpcTemplate & find_npc_template(const Clib::ConfigElem &elem)
Definition: npctmpl.cpp:154
const char * rest() const
Definition: cfgfile.cpp:71
NpcTemplate(const Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: npctmpl.cpp:58
bool pkgdef_split(const std::string &spec, const Package *inpkg, const Package **outpkg, std::string *path)
Definition: pkg.cpp:410
void load_npc_templates()
Definition: npctmpl.cpp:124
std::string read_string(const char *propname) const
Definition: cfgfile.cpp:395
GameState gamestate
Definition: uvars.cpp:74
size_t estimateSize() const
bool has_prop(const char *propname) const
Definition: cfgfile.cpp:112
std::string GetPackageCfgPath(const Package *pkg, const std::string &filename)
Definition: pkg.cpp:491
int translate(const std::string &name, TRANSLATION *table)
Definition: npctmpl.cpp:33
#define ERROR_PRINT
Definition: logfacility.h:230
bool FileExists(const char *filename)
Definition: fileutil.cpp:118
ExportScript * method_script
Definition: npctmpl.h:51
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
std::string name
Definition: npctmpl.h:37
Definition: berror.cpp:12
Equipment * find_intrinsic_equipment(const std::string &name, u8 layer)
Looks up for an existing intrinsic equipment and return it or nullptr if not found.
Definition: equipmnt.cpp:128