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
unit_functions_generic.cpp
Go to the documentation of this file.
1 #include "unit_generic.h"
2 #include "gfx/vec.h"
3 #include "gfx/cockpit_generic.h"
4 #include "faction_generic.h"
5 #include "ai/communication.h"
6 #include "savegame.h"
7 #include "xml_support.h"
8 #include "unit_factory.h"
9 #include "unit_util.h"
10 #include "universe_util.h"
11 #include "unit_const_cache.h"
12 #include "pilot.h"
13 //Various functions that were used in .cpp files that are now included because of
14 //the temple GameUnit class
15 //If not separated from those files functions would be defined in multiple places
16 //Those functions are generic ones
17 
18 //From unit.cpp
21 bool cam_setup_phase = false;
22 
23 int cloakVal( int cloak, int cloakmin, int cloakrate, bool cloakglass )
24 {
25  //Short fix ?
26  if (cloak < 0 && cloakrate < 0)
27  cloak = -2147483647-1; //intended warning should be max neg :-) leave it be
28  if (cloak < cloakmin && cloakrate > 0)
29  cloak = cloakmin;
30  if ( (cloak&0x1) && !cloakglass )
31  cloak -= 1;
32  if ( (cloak&0x1) == 0 && cloakglass )
33  cloak += 1;
34  return cloak;
35 }
36 
37 const Unit * getUnitFromUpgradeName( const string &upgradeName, int myUnitFaction = 0 )
38 {
39  const char *name = upgradeName.c_str();
41  if (!partUnit) {
45  }
46  if (partUnit->name == "LOAD_FAILED") {
47  partUnit = UnitConstCache::getCachedConst( StringIntKey( name, myUnitFaction ) );
48  if (!partUnit)
49  partUnit = UnitConstCache::setCachedConst( StringIntKey( name, myUnitFaction ),
50  UnitFactory::createUnit( name, true, myUnitFaction ) );
51  }
52  return partUnit;
53 }
54 
55 int SelectDockPort( Unit *utdw, Unit *parent )
56 {
57  const vector< DockingPorts > *dp = &utdw->DockingPortLocations();
58  float dist = FLT_MAX;
59  int num = -1;
60  for (unsigned int i = 0; i < dp->size(); ++i)
61  if (!(*dp)[i].IsOccupied()) {
62  Vector rez = Transform( utdw->GetTransformation(), (*dp)[i].GetPosition() );
63  float wdist = ( rez-parent->Position() ).MagnitudeSquared();
64  if (wdist < dist) {
65  num = i;
66  dist = wdist;
67  }
68  }
69  return num;
70 }
71 
72 //From unit_customize.cpp
73 Unit * CreateGameTurret( std::string tur, int faction )
74 {
75  return UnitFactory::createUnit( tur.c_str(), true, faction );
76 }
77 
78 void SetShieldZero( Unit *un )
79 {
80  switch (un->shield.number)
81  {
82  case 8:
83 
84  un->shield.shield8.frontlefttop =
85  un->shield.shield8.frontrighttop =
86  un->shield.shield8.backlefttop =
87  un->shield.shield8.backrighttop =
88  un->shield.shield8.frontleftbottom =
89  un->shield.shield8.frontrightbottom =
90  un->shield.shield8.backleftbottom =
91  un->shield.shield8.backrightbottom = 0;
92  break;
93  case 4:
94  un->shield.shield4fbrl.front =
95  un->shield.shield4fbrl.back =
96  un->shield.shield4fbrl.left =
97  un->shield.shield4fbrl.right = 0;
98  break;
99  case 2:
100  un->shield.shield2fb.front = un->shield.shield2fb.back = 0;
101  break;
102  }
103 }
104 
105 //un scored a faction kill
106 void ScoreKill( Cockpit *cp, Unit *un, Unit *killedUnit )
107 {
108  if (un->isUnit() != UNITPTR || killedUnit->isUnit() != UNITPTR)
109  return;
110  static float KILL_FACTOR = -XMLSupport::parse_float( vs_config->getVariable( "AI", "kill_factor", ".2" ) );
111  int killedCp = _Universe->whichPlayerStarship( killedUnit );
112  int killerCp = killedCp;
113  if (killedCp != -1) {
114  UniverseUtil::adjustRelationModifierInt( killedCp, un->faction, KILL_FACTOR );
115  } else {
116  killerCp = _Universe->whichPlayerStarship( un );
117  if (killerCp != -1)
118  UniverseUtil::adjustRelationModifierInt( killerCp, killedUnit->faction, KILL_FACTOR );
119  }
120  int faction = killedUnit->faction;
121  static float FRIEND_FACTOR = -XMLSupport::parse_float( vs_config->getVariable( "AI", "friend_factor", ".1" ) );
122  for (unsigned int i = 0; i < FactionUtil::GetNumFactions(); i++) {
123  float relation;
124  if (faction != (int) i && un->faction != (int) i) {
125  relation = FactionUtil::GetIntRelation( i, faction );
126  if (killedCp != -1)
127  relation += UniverseUtil::getRelationModifierInt( i, faction );
128  if (relation)
129  if (killerCp != -1)
130  UniverseUtil::adjustRelationModifierInt( killerCp, i, FRIEND_FACTOR*relation );
131  }
132  }
133  int upgrades = FactionUtil::GetUpgradeFaction();
134  int planets = FactionUtil::GetPlanetFaction();
135  if (cp != NULL) {
136  vector< float > *killlist = &cp->savegame->getMissionData( string( "kills" ) );
137  while ( killlist->size() <= FactionUtil::GetNumFactions() )
138  killlist->push_back( (float) 0.0 );
139  if ( (int) killlist->size() > faction )
140  (*killlist)[faction]++;
141  killlist->back()++;
142  } else if (UnitUtil::getRelationToFaction( un, faction ) < 0 && faction != upgrades && faction != planets) {
143  int whichcp = rand()%_Universe->numPlayers();
144  Unit *whichrecv = _Universe->AccessCockpit( whichcp )->GetParent();
145  if (whichrecv != NULL) {
146  if ( UnitUtil::getUnitSystemFile( whichrecv ) == UnitUtil::getUnitSystemFile( un ) ) {
147  if ( un->getAIState() && whichrecv->getAIState() ) {
148  unsigned char sex;
149  vector< Animation* > *anim = un->pilot->getCommFaces( sex );
150  CommunicationMessage c( un, whichrecv, anim, sex );
151  c.SetCurrentState( c.fsm->GetScoreKillNode(), anim, sex );
152  whichrecv->getAIState()->Communicate( c );
153  }
154  }
155  }
156  }
157 }
158 
159 //From unit_physics.cpp
160 signed char ComputeAutoGuarantee( Unit *un )
161 {
162  Cockpit *cp;
163  unsigned int cpnum = 0;
164  if ( ( cp = _Universe->isPlayerStarship( un ) ) )
165  cpnum = cp-_Universe->AccessCockpit( 0 );
166  else
167  return Mission::AUTO_ON;
168  unsigned int i;
169  for (i = 0; i < active_missions.size(); ++i)
170  if (active_missions[i]->player_num == cpnum && active_missions[i]->player_autopilot != Mission::AUTO_NORMAL)
171  return active_missions[i]->player_autopilot;
172  for (i = 0; i < active_missions.size(); i++)
173  if (active_missions[i]->global_autopilot != Mission::AUTO_NORMAL)
174  return active_missions[i]->global_autopilot;
175  return Mission::AUTO_NORMAL;
176 }
177 
178 float getAutoRSize( Unit *orig, Unit *un, bool ignore_friend = false )
179 {
180  static float gamespeed = XMLSupport::parse_float( vs_config->getVariable( "physics", "game_speed", "1" ) );
181 
182  static float friendly_autodist =
183  XMLSupport::parse_float( vs_config->getVariable( "physics", "friendly_auto_radius", "00" ) )*gamespeed;
184  static float neutral_autodist =
185  XMLSupport::parse_float( vs_config->getVariable( "physics", "neutral_auto_radius", "0" ) )*gamespeed;
186  static float hostile_autodist =
187  XMLSupport::parse_float( vs_config->getVariable( "physics", "hostile_auto_radius", "1000" ) )*gamespeed;
188  int upgradefaction = FactionUtil::GetUpgradeFaction();
189  int neutral = FactionUtil::GetNeutralFaction();
190  if (un->isUnit() == ASTEROIDPTR) {
191  static float minasteroiddistance =
192  XMLSupport::parse_float( vs_config->getVariable( "physics", "min_asteroid_distance", "-100" ) );
193  return minasteroiddistance;
194  }
195  if ( un->isUnit() == PLANETPTR || ( un->getFlightgroup() == orig->getFlightgroup() && orig->getFlightgroup() ) )
196  //same flihgtgroup
197  return orig->rSize();
198  if (un->faction == upgradefaction)
199  return ignore_friend ? -FLT_MAX : ( -orig->rSize()-un->rSize() );
200  float rel = un->getRelation( orig );
201  if ( orig == un->Target() )
202  rel -= 1.5;
203  if (un->faction == neutral)
204  return neutral_autodist;
205  else if (rel > .1)
206  return ignore_friend ? -FLT_MAX : friendly_autodist; //min distance apart
207  else if (rel < 0)
208  return hostile_autodist;
209  else
210  return ignore_friend ? -FLT_MAX : neutral_autodist;
211 }
212 
213 //From unit_weapon.cpp
214 bool AdjustMatrix( Matrix &mat, const Vector &vel, Unit *target, float speed, bool lead, float cone )
215 {
216  if (target) {
217  QVector pos( mat.p );
218  Vector R( mat.getR() );
219  QVector targpos( lead ? target->PositionITTS( pos, vel, speed, false ) : target->Position() );
220 
221  Vector dir = (targpos-pos).Cast();
222  dir.Normalize();
223  if (dir.Dot( R ) >= cone) {
224  Vector Q( mat.getQ() );
225  Vector P;
226  ScaledCrossProduct( Q, dir, P );
227  ScaledCrossProduct( dir, P, Q );
228  VectorAndPositionToMatrix( mat, P, Q, dir, pos );
229  } else {
230  return false;
231  }
232  return true;
233  }
234  return false;
235 }
236 
238 {
239  int i;
240  char tmp[384];
241  for (i = 0; i < 383 && str[i] != '\0'; i++)
242  tmp[i] = (char) toupper( str[i] );
243  tmp[i] = '\0';
244  if (strcmp( "LIGHT", tmp ) == 0)
245  return weapon_info::LIGHT;
246  if (strcmp( "MEDIUM", tmp ) == 0)
247  return weapon_info::MEDIUM;
248  if (strcmp( "HEAVY", tmp ) == 0)
249  return weapon_info::HEAVY;
250  if (strcmp( "CAPSHIP-LIGHT", tmp ) == 0)
252  if (strcmp( "CAPSHIP-HEAVY", tmp ) == 0)
254  if (strcmp( "SPECIAL", tmp ) == 0)
255  return weapon_info::SPECIAL;
256  if (strcmp( "LIGHT-MISSILE", tmp ) == 0)
258  if (strcmp( "MEDIUM-MISSILE", tmp ) == 0)
260  if (strcmp( "HEAVY-MISSILE", tmp ) == 0)
262  if (strcmp( "LIGHT-CAPSHIP-MISSILE", tmp ) == 0)
264  if (strcmp( "HEAVY-CAPSHIP-MISSILE", tmp ) == 0)
266  if (strcmp( "SPECIAL-MISSILE", tmp ) == 0)
268  if (strcmp( "AUTOTRACKING", tmp ) == 0)
270  return weapon_info::NOWEAP;
271 }
272 
273 int parseMountSizes( const char *str )
274 {
275  char tmp[13][50];
276  int ans = weapon_info::NOWEAP;
277  int num = sscanf( str,
278  "%s %s %s %s %s %s %s %s %s %s %s %s %s",
279  tmp[0],
280  tmp[1],
281  tmp[2],
282  tmp[3],
283  tmp[4],
284  tmp[5],
285  tmp[6],
286  tmp[7],
287  tmp[8],
288  tmp[9],
289  tmp[10],
290  tmp[11],
291  tmp[12] );
292  for (int i = 0; i < num; i++)
293  ans |= lookupMountSize( tmp[i] );
294  return ans;
295 }
296 
298 {
299  float speed = un->GetVelocity().Magnitude();
300  float damage = un->GetJumpStatus().damage+(rand()%100 < 1) ? (rand()%20) : 0;
301  static float muld = XMLSupport::parse_float( vs_config->getVariable( "physics", "jump_damage_multiplier", ".1" ) );
302  static float maxd = XMLSupport::parse_float( vs_config->getVariable( "physics", "max_jump_damage", "100" ) );
303  float dam = speed*(damage*muld);
304  if (dam > maxd) dam = maxd;
305  if (dam > 1) {
306  un->ApplyDamage( ( un->Position()+un->GetVelocity().Cast() ).Cast(),
307  un->GetVelocity(),
308  dam,
309  un,
310  GFXColor( ( (float) (rand()%100) )/100,
311  ( (float) (rand()%100) )/100,
312  ( (float) (rand()%100) )/100 ), NULL );
313  un->SetCurPosition( un->LocalPosition()+( ( (float) rand() )/RAND_MAX )*dam*un->GetVelocity().Cast() );
314  }
315 }
316 
317 void Enslave( Unit *parent, bool enslave )
318 {
319  unsigned int i;
320  vector< Cargo >ToBeChanged;
321  unsigned int numcargo = parent->numCargo();
322  for (i = numcargo-1; i >= 0; --i) {
323  Cargo *carg = &parent->GetCargo( i );
324  if (enslave) {
325  if (carg->GetCategory().find( "Passengers" ) != string::npos && carg->content != "Hitchhiker") {
326  ToBeChanged.push_back( *carg );
327  parent->RemoveCargo( i, carg->quantity, true );
328  }
329  } else if (carg->content == "Slaves" || carg->content == "Pilot") {
330  ToBeChanged.push_back( *carg );
331  parent->RemoveCargo( i, carg->quantity, true );
332  }
333  }
334  unsigned int dummy;
335  Cargo *newCarg = UniverseUtil::GetMasterPartList()->GetCargo( enslave ? "Slaves" : "Hitchhiker", dummy );
336  if (newCarg) {
337  Cargo slave = *newCarg;
338  for (i = 0; i < ToBeChanged.size(); ++i) {
339  slave.quantity = ToBeChanged[i].quantity;
340  while (parent->CanAddCargo( slave ) == false && (--slave.quantity) > 0) {}
341  if (slave.quantity)
342  if ( parent->CanAddCargo( slave ) )
343  parent->AddCargo( slave, true );
344  }
345  }
346 }
347