Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
event_xml.cpp
Go to the documentation of this file.
1 #include "cmd/unit_generic.h"
2 #include "xml_support.h"
3 #include "event_xml.h"
4 #include <string>
5 #include <vector>
6 #include <list>
7 #include <float.h>
8 #include <assert.h>
9 #include "vegastrike.h"
10 #include "vsfilesystem.h"
11 #include "vs_globals.h"
12 #include "configxml.h"
13 extern bool validateHardCodedScript( std::string s );
14 //serves to run through a XML file that nests things for "and".
15 
22 namespace AIEvents
23 {
25  float const min,
26  const float max,
27  float timetofinish,
28  float timeuntilinterrupts,
29  float priority,
30  const std::string &aiscript )
31 {
32  this->timetointerrupt = timeuntilinterrupts;
33  this->timetofinish = timetofinish;
34  this->type = type;
35  this->priority = priority;
36  this->max = max;
37 
38  this->min = min;
39 
40  this->script = aiscript;
41  if ( !validateHardCodedScript( this->script ) ) {
42  static int aidebug = XMLSupport::parse_int( vs_config->getVariable( "AI", "debug_level", "0" ) );
43  if (aidebug) {
44  for (int i = 0; i < 10; ++i) {
45  printf( "SERIOUS WARNING %s\n", this->script.c_str() );
46  fprintf( stderr, "SERIOUS WARNING: %s\n", this->script.c_str() );
47  }
48  }
49  printf(
50  "SERIOUS WARNING in AI script: no fast method to perform %s when type %d is at least %f and at most %f with priority %f for %f time\n",
51  this->script.c_str(),
52  type,
53  min,
54  max,
55  priority,
56  timetofinish );
57  }
58 }
59 
60 const int AIUNKNOWN = 0;
61 const int AIMIN = 1;
62 const int AIMAX = 2;
63 const int AISCRIPT = 3;
64 const int AINOT = 4;
65 const int TIMEIT = 5;
66 const int OBEDIENCE = 6;
67 const int TIMETOINTERRUPT = 7;
68 const int PRIORITY = 8;
70  EnumMap::Pair( "UNKNOWN", AIUNKNOWN ),
71  EnumMap::Pair( "min", AIMIN ),
72  EnumMap::Pair( "max", AIMAX ),
73  EnumMap::Pair( "not", AINOT ),
74  EnumMap::Pair( "Script", AISCRIPT ),
75  EnumMap::Pair( "time", TIMEIT ),
76  EnumMap::Pair( "obedience", OBEDIENCE ),
77  EnumMap::Pair( "timetointerrupt", TIMETOINTERRUPT ),
78  EnumMap::Pair( "priority", PRIORITY )
79 };
81 
82 void GeneralAIEventBegin( void *userData, const XML_Char *name, const XML_Char **atts )
83 {
84  AttributeList attributes( atts );
85  string aiscriptname( "" );
86  float min = -FLT_MAX;
87  float max = FLT_MAX;
88  ElemAttrMap *eam = ( (ElemAttrMap*) userData );
89  float timetofinish = eam->maxtime;
90  float timetointerrupt = 0;
91  int elem = eam->element_map.lookup( name );
92  AttributeList::const_iterator iter;
93  float priority = 4;
94  eam->level++;
95  if (elem == 0) {
96  eam->result.push_back( std::list< AIEvresult > () );
97  eam->result.push_back( std::list< AIEvresult > () );
98  for (iter = attributes.begin(); iter != attributes.end(); iter++) {
99  switch ( attr_map.lookup( (*iter).name ) )
100  {
101  case TIMEIT:
102  eam->maxtime = (short) XMLSupport::parse_float( (*iter).value );
103  break;
104  case OBEDIENCE:
105  eam->obedience = (float) ( XMLSupport::parse_float( (*iter).value ) );
106  }
107  }
108  } else {
109  assert( eam->level != 1 && eam->result.size() >= 2 ); //might not have a back on result();
110  if ( eam->result.back().size() != eam->result[eam->result.size()-2].size() )
111  eam->result.push_back( eam->result.back() );
112  for (iter = attributes.begin(); iter != attributes.end(); iter++) {
113  switch ( attr_map.lookup( (*iter).name ) )
114  {
115  case AINOT:
116  elem = -elem; //since elem can't be 0 (see above) this will save the "not" info
117  break;
118  case AIMIN:
119  min = XMLSupport::parse_float( (*iter).value );
120  break;
121  case AIMAX:
122  max = XMLSupport::parse_float( (*iter).value );
123  break;
124  case AISCRIPT:
125  aiscriptname = (*iter).value;
126  break;
127  case TIMEIT:
128  timetofinish = XMLSupport::parse_float( (*iter).value );
129  break;
130  case TIMETOINTERRUPT:
131  timetointerrupt = XMLSupport::parse_float( (*iter).value );
132  break;
133  case PRIORITY:
134  priority = XMLSupport::parse_float( (*iter).value );
135  break;
136  default:
137  break;
138  }
139  }
140  AIEvresult newelem( elem, min, max, timetofinish, timetointerrupt, priority, aiscriptname );
141  eam->result.back().push_back( newelem );
142  eam->result[eam->result.size()-2].push_back( newelem );
143  }
144 }
145 
146 void GeneralAIEventEnd( void *userData, const XML_Char *name )
147 {
148  ElemAttrMap *eam = ( (ElemAttrMap*) userData );
149  eam->level--;
150  if (eam->result.back().size() == 0) {
151  eam->result.pop_back();
152  assert( eam->level == 0 );
153  } else {
154  eam->result.back().pop_back();
155  }
156 }
157 
158 void LoadAI( const char *filename, ElemAttrMap &result, const string &faction )
159 {
160  //returns obedience
161  using namespace VSFileSystem;
162  static float cfg_obedience = XMLSupport::parse_float( vs_config->getVariable( "AI",
163  "Targetting",
164  "obedience",
165  ".99" ) );
166  result.obedience = cfg_obedience;
167  result.maxtime = 10;
168  VSFile f;
169  VSError err;
170  err = f.OpenReadOnly( filename, AiFile );
171  if (err > Ok) {
172  printf( "ai file %s not found\n", filename );
173  string full_filename = filename;
174  full_filename = full_filename.substr( 0, strlen( filename )-4 );
175  string::size_type where = full_filename.find_last_of( "." );
176  string type = ".agg.xml";
177  if (where != string::npos) {
178  type = full_filename.substr( where );
179  full_filename = full_filename.substr( 0, where )+".agg.xml";
180  err = f.OpenReadOnly( full_filename, AiFile );
181  }
182  if (err > Ok) {
183  printf( "ai file %s again not found\n", full_filename.c_str() );
184  full_filename = "default";
185  full_filename += type;
186  err = f.OpenReadOnly( full_filename, AiFile );
187  }
188  if (err > Ok) {
189  printf( "ai file again %s again not found\n", full_filename.c_str() );
190  err = f.OpenReadOnly( "default.agg.xml", AiFile );
191  if (err > Ok) {
192  fprintf( stderr, "ai file again default.agg.xml again not found\n" );
193  return; //Who knows what will happen now? Crash?
194  }
195  }
196  }
197  XML_Parser parser = XML_ParserCreate( NULL );
198  XML_SetUserData( parser, &result );
199  XML_SetElementHandler( parser, &GeneralAIEventBegin, &GeneralAIEventEnd );
200  XML_Parse( parser, ( f.ReadFull() ).c_str(), f.Size(), 1 );
201  f.Close();
202  XML_ParserFree( parser );
203  if (result.level != 0)
204  fprintf( stderr, "Error loading AI script %s for faction %s. Final count not zero.\n", filename, faction.c_str() );
205  result.level = 0;
206 }
207 }
208