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
FSM Class Reference

#include <communication.h>

Classes

struct  Node
 

Public Member Functions

bool StopAllSounds (unsigned char sex)
 
 FSM (const std::string &filename)
 
void LoadXML (const char *factionfile)
 
void beginElement (const string &name, const AttributeList attributes)
 
std::string GetEdgesString (unsigned int curstate)
 
float getDeltaRelation (int prevstate, unsigned int curstate) const
 
int getCommMessageMood (int curstate, float mood, float randomresponsefactor, float relationship) const
 
int getDefaultState (float relationship) const
 
int GetUnDockNode () const
 
int GetFailDockNode () const
 
int GetDockNode () const
 
int GetAbleToDockNode () const
 
int GetUnAbleToDockNode () const
 
int GetYesNode () const
 
int GetNoNode () const
 
int GetHitNode () const
 
int GetDamagedNode () const
 
int GetDealtDamageNode () const
 
int GetScoreKillNode () const
 
int GetRequestLandNode () const
 
int GetContrabandInitiateNode () const
 
int GetContrabandUnDetectedNode () const
 
int GetContrabandDetectedNode () const
 
int GetContrabandWobblyNode () const
 

Static Public Member Functions

static void beginElement (void *userData, const XML_Char *name, const XML_Char **atts)
 
static void endElement (void *userData, const XML_Char *name)
 

Public Attributes

vector< Nodenodes
 

Detailed Description

Definition at line 5 of file communication.h.

Constructor & Destructor Documentation

FSM::FSM ( const std::string &  filename)

Definition at line 8 of file communication.cpp.

References i, LoadXML(), FSM::Node::MakeNode(), and nodes.

9 {
10  //loads a conversation finite state machine with deltaRelation weight transition from an XML?
11  if (filename.empty()) {
12  nodes.push_back( Node::MakeNode( "welcome to cachunkcachunk.com", 0 ) );
13  nodes.push_back( Node::MakeNode( "I love you!", .1 ) );
14  nodes.push_back( Node::MakeNode( "J00 0wnz m3", .08 ) );
15  nodes.push_back( Node::MakeNode( "You are cool!", .06 ) );
16  nodes.push_back( Node::MakeNode( "You are nice!", .05 ) );
17  nodes.push_back( Node::MakeNode( "Ya you're naled! NALED PAL!", -.02 ) );
18  nodes.push_back( Node::MakeNode( "i 0wnz j00", -.08 ) );
19  nodes.push_back( Node::MakeNode( "I hate you!", -.1 ) );
20 
21  nodes.push_back( Node::MakeNode( "Docking operation complete.", 0 ) );
22  nodes.push_back( Node::MakeNode( "Please move into a green docking box and press d.", 0 ) );
23  nodes.push_back( Node::MakeNode( "Docking operation begun.", 0 ) );
24  nodes.push_back( Node::MakeNode( "Clearance denied.", 0 ) );
25  nodes.push_back( Node::MakeNode( "Clearance granted.", 0 ) );
26  nodes.push_back( Node::MakeNode( "No.", 0 ) );
27  nodes.push_back( Node::MakeNode( "Yes.", 0 ) );
28  nodes.push_back( Node::MakeNode( "Prepare To Be Searched. Maintain Speed and Course.", 0 ) );
29  nodes.push_back( Node::MakeNode( "No contraband detected: You may proceed.", 0 ) );
30  nodes.push_back( Node::MakeNode( "Contraband detected! All units close and engage!", 0 ) );
31  nodes.push_back( Node::MakeNode( "Your Course is deviating! Maintain Course!", 0 ) );
32  nodes.push_back( Node::MakeNode( "Request Clearence To Land.", 0 ) );
33  nodes.push_back( Node::MakeNode( "*hit*", -.2 ) );
34  vector< unsigned int >edges;
35  unsigned int i;
36  for (i = 0; i < nodes.size()-13; i++)
37  edges.push_back( i );
38  for (i = 0; i < nodes.size(); i++)
39  nodes[i].edges = edges;
40  } else {
41  LoadXML( filename.c_str() );
42  }
43 }

Member Function Documentation

void FSM::beginElement ( const string &  name,
const AttributeList  attributes 
)

Definition at line 52 of file communication_xml.cpp.

References CommXML::attribute_map, CommXML::EDGE, CommXML::element_map, CommXML::FILENAME, i, CommXML::INDEX, XMLSupport::EnumMap::lookup(), CommXML::NODE, XMLSupport::parse_float(), XMLSupport::parse_int(), CommXML::SEXE, CommXML::SOUND, strtoupper(), unitlevel, and CommXML::UNKNOWN.

Referenced by LoadXML().

53 {
54  using namespace CommXML;
55  AttributeList::const_iterator iter;
56  Names elem = (Names) element_map.lookup( name );
57  string nam;
58  string filename;
59  float val = 0.0f; //FIXME "= 0.0f" added by chuck_starchaser without knowing what value to use
60  unsigned char sexe = 0; //FIXME "= 0" added by chuck_starchaser without knowing what value to use
61  switch (elem)
62  {
63  case SOUND:
64  for (iter = attributes.begin(); iter != attributes.end(); iter++) {
65  switch ( attribute_map.lookup( (*iter).name ) )
66  {
67  case SEXE:
68  sexe = XMLSupport::parse_int( (*iter).value );
69  break;
70  case FILENAME:
71  filename = (*iter).value;
72  break;
73  }
74  }
75  if (!filename.empty())
76  nodes.back().AddSound( filename, sexe ); //FIXME sexe was used uninitialized until I added = 0 --chuck_starchaser
77  break;
78  case UNKNOWN:
79  unitlevel++;
80  return;
81 
82  case NODE:
83  {
84  unitlevel++;
85  vector< string > messages;
86  for (iter = attributes.begin(); iter != attributes.end(); iter++) {
87  if (strtoupper( (*iter).name ) == "RELATIONSHIP") {
88  val = parse_float( (*iter).value );
89  } else {
90  string tmp = strtoupper( (*iter).name );
91  unsigned int num = 0;
92  if (1 == sscanf( tmp.c_str(), "TEXT%d", &num ) || tmp == "TEXT") {
93  while ( !( num < messages.size() ) )
94  messages.push_back( string() );
95  nam = (*iter).value;
96  {
97  for (string::iterator i = nam.begin(); i != nam.end(); i++)
98  if (*i == '\\')
99  *i = '\n';
100  }
101  messages[num] = nam;
102  }
103  }
104  }
105  nodes.push_back( Node( messages, val ) ); //FIXME val was used uninitialized until I added = 0 --chuck_starchaser
106  break;
107  }
108  case EDGE:
109  unitlevel++;
110  for (iter = attributes.begin(); iter != attributes.end(); iter++)
111  if ( ( attribute_map.lookup( (*iter).name ) ) == INDEX )
112  nodes.back().edges.push_back( parse_int( (*iter).value ) );
113  break;
114  default:
115  break;
116  }
117 }
void FSM::beginElement ( void *  userData,
const XML_Char *  name,
const XML_Char **  atts 
)
static

Definition at line 47 of file communication_xml.cpp.

48 {
49  ( (FSM*) userData )->beginElement( names, AttributeList( atts ) );
50 }
void FSM::endElement ( void *  userData,
const XML_Char *  name 
)
static

Definition at line 118 of file communication_xml.cpp.

References CommXML::element_map, XMLSupport::EnumMap::lookup(), unitlevel, and CommXML::UNKNOWN.

Referenced by LoadXML().

119 {
120  using namespace CommXML;
121  Names elem = (Names) element_map.lookup( name );
122  switch (elem)
123  {
124  case UNKNOWN:
125  unitlevel--;
126  break;
127  default:
128  unitlevel--;
129  break;
130  }
131 }
int FSM::GetAbleToDockNode ( ) const

Definition at line 65 of file communication.cpp.

References nodes.

Referenced by Order::ProcessCommunicationMessages().

66 {
67  return nodes.size()-12;
68 }
int FSM::getCommMessageMood ( int  curstate,
float  mood,
float  randomresponsefactor,
float  relationship 
) const

Definition at line 204 of file communication.cpp.

References b, FSM::Node::edges, float, g, getDefaultState(), VegaConfig::getVariable(), i, int, nodes, nonneg(), XMLSupport::parse_float(), sq(), and vs_config.

Referenced by CommunicatingAI::selectCommunicationMessageMood().

205 {
206  const FSM::Node *n = (unsigned int) curstate
207  < nodes.size() ? (&nodes[curstate]) : (&nodes[getDefaultState( relationship )]);
208  mood += -randomresponse+2*randomresponse*( (float) rand() )/RAND_MAX;
209 
210  int choice = 0;
211 #if 0
212  float bestchoice = 4;
213  bool fitmood = false;
214  for (unsigned i = 0; i < n->edges.size(); i++) {
215  float md = nodes[n->edges[i]].messagedelta;
216  bool newfitmood = nonneg( mood ) == nonneg( md );
217  if ( (!fitmood) || newfitmood ) {
218  float newbestchoice = sq( md-mood );
219  if ( (newbestchoice <= bestchoice) || (fitmood == false && newfitmood == true) )
220  if ( (newbestchoice == bestchoice && rand()%2) || newbestchoice < bestchoice ) {
221  //to make sure some variety happens
222  fitmood = newfitmood;
223  choice = i;
224  bestchoice = newbestchoice;
225  }
226  }
227  }
228 #endif
229  vector< unsigned int >g;
230  vector< unsigned int >b;
231  static float pos_limit = XMLSupport::parse_float( vs_config->getVariable( "AI",
232  "LowestPositiveCommChoice",
233  "0" ) );
234  static float neg_limit = XMLSupport::parse_float( vs_config->getVariable( "AI",
235  "LowestNegativeCommChoice",
236  "-.00001" ) );
237  for (unsigned int i = 0; i < n->edges.size(); i++) {
238  float md = nodes[n->edges[i]].messagedelta;
239  if (md >= pos_limit)
240  g.push_back( i );
241  if (md <= neg_limit)
242  b.push_back( i );
243  }
244  if ( g.size() != 0 && ( relationship > 0 || (b.size() == 0) ) )
245  choice = g[( rand()%g.size() )];
246  else if ( b.size() )
247  choice = b[rand()%b.size()];
248  return choice;
249 }
int FSM::GetContrabandDetectedNode ( ) const

Definition at line 90 of file communication.cpp.

References nodes.

Referenced by CommunicatingAI::TerminateContrabandSearch().

91 {
92  return nodes.size()-7;
93 }
int FSM::GetContrabandInitiateNode ( ) const

Definition at line 80 of file communication.cpp.

References nodes.

Referenced by CommunicatingAI::InitiateContrabandSearch().

81 {
82  return nodes.size()-9;
83 }
int FSM::GetContrabandUnDetectedNode ( ) const

Definition at line 85 of file communication.cpp.

References nodes.

Referenced by CommunicatingAI::TerminateContrabandSearch().

86 {
87  return nodes.size()-8;
88 }
int FSM::GetContrabandWobblyNode ( ) const

Definition at line 95 of file communication.cpp.

References nodes.

Referenced by CommunicatingAI::UpdateContrabandSearch().

96 {
97  return nodes.size()-6;
98 }
int FSM::GetDamagedNode ( ) const

Definition at line 110 of file communication.cpp.

References nodes.

Referenced by Unit::ApplyDamage().

111 {
112  return nodes.size()-2;
113 }
int FSM::GetDealtDamageNode ( ) const

Definition at line 115 of file communication.cpp.

References nodes.

Referenced by Unit::ApplyDamage().

116 {
117  return nodes.size()-3;
118 }
int FSM::getDefaultState ( float  relationship) const

Definition at line 251 of file communication.cpp.

References FSM::Node::edges, float, i, nodes, nonneg(), and sq().

Referenced by FireKeyboard::Execute(), getCommMessageMood(), CommunicationMessage::getCurrentState(), MatchingMood(), CommunicatingAI::RandomInitiateCommunication(), and CommunicatingAI::selectCommunicationMessageMood().

252 {
253  if (relationship < -1) relationship = -1;
254  if (relationship > 1) relationship = 1; //clamp it
255  float mood = relationship;
256  float randomresponse = .01;
257  int curstate = 0;
258 
259  const FSM::Node *n = &nodes[curstate];
260  mood += -randomresponse+2*randomresponse*( (float) rand() )/RAND_MAX;
261 
262  int choice = 0;
263  float bestchoice = 16;
264  bool fitmood = false;
265  for (unsigned i = 0; i < n->edges.size(); i++) {
266  float md = nodes[n->edges[i]].messagedelta;
267  bool newfitmood = nonneg( mood ) == nonneg( md );
268  if ( (!fitmood) || newfitmood ) {
269  float newbestchoice = sq( md-mood );
270  if ( (newbestchoice <= bestchoice) || (fitmood == false && newfitmood == true) ) {
271  if ( (newbestchoice == bestchoice && rand()%2) || newbestchoice < bestchoice ) {
272  //to make sure some variety happens
273  fitmood = newfitmood;
274  choice = i;
275  bestchoice = newbestchoice;
276  }
277  }
278  }
279  } //(0,relationship,.01)
280  return nodes[0].edges[choice];
281 }
float FSM::getDeltaRelation ( int  prevstate,
unsigned int  curstate 
) const

Definition at line 299 of file communication.cpp.

References fprintf, and nodes.

Referenced by CommunicationMessage::getDeltaRelation().

300 {
301  if (nodes.size() <= current_state) {
302  fprintf( stderr, "Error with faction relationship due to %d not being in range of faction\n", current_state );
303  return 0;
304  }
305  return nodes[current_state].messagedelta;
306 }
int FSM::GetDockNode ( ) const

Definition at line 55 of file communication.cpp.

References nodes.

Referenced by TryDock().

56 {
57  return nodes.size()-14;
58 }
std::string FSM::GetEdgesString ( unsigned int  curstate)

Definition at line 283 of file communication.cpp.

References fprintf, VegaConfig::getVariable(), i, nodes, XMLSupport::parse_bool(), tostring(), and vs_config.

Referenced by FireKeyboard::Execute().

284 {
285  std::string retval = "\n";
286  if (nodes.size() <= curstate) {
287  fprintf( stderr, "Error with faction relationship due to %d not being in range of faction\n", curstate );
288  return "\n1. Transmit Error\n2. Transmit Error\n3. Transmit Error\n";
289  }
290  for (unsigned int i = 0; i < nodes[curstate].edges.size(); i++)
291  retval += tostring( (int) ( (i+1)%10 ) )+"."+nodes[nodes[curstate].edges[i]].messages[0]+"\n";
292  static bool print_docking =
293  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "hud", "print_request_docking", "true" ) );
294  if (print_docking)
295  retval += "0. Request Docking Clearence";
296  return retval;
297 }
int FSM::GetFailDockNode ( ) const

Definition at line 50 of file communication.cpp.

References nodes.

Referenced by DoDockingOps().

51 {
52  return nodes.size()-15;
53 }
int FSM::GetHitNode ( ) const

Definition at line 105 of file communication.cpp.

References nodes.

Referenced by Unit::ApplyDamage(), and GetMadAt().

106 {
107  return nodes.size()-1;
108 }
int FSM::GetNoNode ( ) const

Definition at line 70 of file communication.cpp.

References nodes.

Referenced by HelpOut(), Orders::AggressiveAI::ProcessCurrentFgDirective(), and TryDock().

71 {
72  return nodes.size()-11;
73 }
int FSM::GetRequestLandNode ( ) const

Definition at line 100 of file communication.cpp.

References nodes.

Referenced by RequestClearence().

101 {
102  return nodes.size()-5;
103 }
int FSM::GetScoreKillNode ( ) const

Definition at line 120 of file communication.cpp.

References nodes.

Referenced by ScoreKill().

121 {
122  return nodes.size()-4;
123 }
int FSM::GetUnAbleToDockNode ( ) const

Definition at line 60 of file communication.cpp.

References nodes.

Referenced by Order::ProcessCommunicationMessages().

61 {
62  return nodes.size()-13;
63 }
int FSM::GetUnDockNode ( ) const
int FSM::GetYesNode ( ) const

Definition at line 75 of file communication.cpp.

References nodes.

Referenced by HelpOut(), and Orders::AggressiveAI::ProcessCurrentFgDirective().

76 {
77  return nodes.size()-10;
78 }
void FSM::LoadXML ( const char *  factionfile)

Definition at line 133 of file communication_xml.cpp.

References beginElement(), VSFileSystem::CommFile, endElement(), f, fprintf, VSFileSystem::Ok, and unitlevel.

Referenced by FSM().

134 {
135  using namespace CommXML;
136  using namespace VSFileSystem;
137  unitlevel = 0;
138  VSFile f;
139  VSError err = f.OpenReadOnly( filename, CommFile );
140  if (err > Ok) {
141  fprintf( stderr, "Failed to open Communications file '%s' -- aborting!\n", filename );
142  assert( 0 );
143  return;
144  }
145  XML_Parser parser = XML_ParserCreate( NULL );
146  XML_SetUserData( parser, this );
147  XML_SetElementHandler( parser, &FSM::beginElement, &FSM::endElement );
148 
149  XML_Parse( parser, ( f.ReadFull() ).c_str(), f.Size(), 1 );
150  f.Close();
151  XML_ParserFree( parser );
152 }
bool FSM::StopAllSounds ( unsigned char  sex)

Definition at line 172 of file communication.cpp.

References i, and nodes.

Referenced by CommunicatingAI::Destroy().

173 {
174  bool ret = false;
175  for (unsigned int i = 0; i < nodes.size(); ++i)
176  if ( nodes[i].StopSound( sex ) )
177  ret = true;
178  return ret;
179 }

Member Data Documentation


The documentation for this class was generated from the following files: