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
docking.cpp
Go to the documentation of this file.
2 #include "docking.h"
3 #include "xml_support.h"
4 #include "config_xml.h"
5 #include "cmd/unit_generic.h"
6 #include "warpto.h"
7 #include "universe_util.h"
8 #include <string>
9 static void DockedScript( Unit *docker, Unit *base )
10 {
11  static string script = vs_config->getVariable( "AI", "DockedToScript", "" );
12  if (script.length() > 0) {
13  Unit *targ = docker->Target();
14  docker->GetComputerData().target.SetUnit( base );
16  CompileRunPython( script );
18  docker->GetComputerData().target.SetUnit( targ ); //should be NULL;
19  }
20 }
21 namespace Orders
22 {
23 DockingOps::DockingOps( Unit *unitToDockWith, Order *ai, bool physically_dock, bool keeptrying ) : MoveTo( QVector( 0, 0, 1 ),
24  false,
25  10, false )
26  , docking( unitToDockWith )
27  , state( GETCLEARENCE )
28  , oldstate( ai )
29 {
30  formerOwnerDoNotDereference = NULL;
31  this->keeptrying = keeptrying;
32  facedtarget = false;
33  physicallyDock = true;
34  port = -1;
35  static float temptimer = XMLSupport::parse_float( vs_config->getVariable( "physics", "docking_time", "10" ) );
36  timer = temptimer;
37 }
39 {
40  MoveTo::SetParent( par );
41  if (parent) {
42  formerOwnerDoNotDereference = parent->owner;
43  parent->SetOwner( docking.GetUnit() );
44  }
45 }
47 {
48  Unit *utdw = docking.GetUnit();
49  if (parent == utdw || utdw == NULL) {
50  RestoreOldAI();
51  Destroy();
52  return;
53  }
54  switch (state)
55  {
56  case GETCLEARENCE:
57  if ( !RequestClearence( utdw ) ) {
58  if (!keeptrying) {
59  RestoreOldAI();
60  Destroy();
61  return;
62  }
63  } else {
64  state = DOCKING;
65  //no break
66  }
67  case DOCKING:
68  if ( DockToTarget( utdw ) )
69  state = DOCKED;
70  break;
71  case DOCKED:
72  if ( PerformDockingOperations( utdw ) )
73  state = UNDOCKING;
74  break;
75  case UNDOCKING:
76  if ( Undock( utdw ) ) {
77  RestoreOldAI();
78  Destroy();
79  return;
80  }
81  break;
82  }
83  parent->SetAngularVelocity( Vector( 0, 0, 0 ) ); //FIXME if you want it to turn to dock point
84  done = false;
85 }
87 {
88  if (parent) {
89  if (oldstate)
90  oldstate->Destroy();
91  oldstate = NULL;
92  if (formerOwnerDoNotDereference) {
93  parent->SetOwner( (Unit*) formerOwnerDoNotDereference ); //set owner will not deref
94  formerOwnerDoNotDereference = NULL;
95  }
96  }
97  docking.SetUnit( NULL );
98 }
100 {
101  if (parent) {
102  parent->aistate = oldstate; //that's me!
103  if (formerOwnerDoNotDereference) {
104  parent->SetOwner( (Unit*) formerOwnerDoNotDereference );
105  formerOwnerDoNotDereference = NULL;
106  }
107  oldstate = NULL;
108  }
109 }
110 int SelectDockPort( Unit *utdw, Unit *parent )
111 {
112  const vector< DockingPorts >& dp = utdw->DockingPortLocations();
113  float dist = FLT_MAX;
114  int num = -1;
115  for (unsigned int i = 0; i < dp.size(); ++i)
116  if (!dp[i].IsOccupied()) {
117  Vector rez = Transform( utdw->GetTransformation(), dp[i].GetPosition() );
118  float wdist = ( rez - parent->Position() ).MagnitudeSquared();
119  if (wdist < dist) {
120  num = i;
121  dist = wdist;
122  }
123  }
124  return num;
125 }
127 {
128  if ( physicallyDock && !utdw->RequestClearance( parent ) )
129  return false;
130  port = SelectDockPort( utdw, parent );
131  if (port == -1)
132  return false;
133  return true;
134 }
136 {
137  const QVector loc( Transform( utdw->GetTransformation(), utdw->DockingPortLocations()[port].GetPosition().Cast() ) );
138  SetDest( loc );
139 
141  if (!facedtarget) {
142  facedtarget = true;
143  EnqueueOrder( new ChangeHeading( loc, 4, 1, true ) );
144  }
145  MoveTo::Execute();
146  if (rand()%256 == 0)
147  WarpToP( parent, utdw, true );
148  return loc;
149 }
151 {
152  if (utdw->DockingPortLocations()[port].IsOccupied()) {
153  if (keeptrying) {
154  state = GETCLEARENCE;
155  return false;
156  } else {
157  docking.SetUnit( NULL );
158  state = GETCLEARENCE;
159  return false;
160  }
161  }
162  QVector loc = Movement( utdw );
163  float rad = utdw->DockingPortLocations()[port].GetRadius() + parent->rSize();
164  float diss = (parent->Position()-loc).MagnitudeSquared()-.1;
165  bool isplanet = utdw->isUnit() == PLANETPTR;
166  static float MinimumCapacityToRefuelOnLand =
167  XMLSupport::parse_float( vs_config->getVariable( "physics", "MinimumWarpCapToRefuelDockeesAutomatically", "0" ) );
168  if ( diss <= ( isplanet ? rad*rad : parent->rSize()*parent->rSize() ) ) {
169  DockedScript( parent, utdw );
170  if (physicallyDock) {
171  return parent->Dock( utdw );
172  } else {
173  float maxWillingToRefill = utdw->WarpCapData();
174  if (maxWillingToRefill >= MinimumCapacityToRefuelOnLand)
175  parent->RefillWarpEnergy(); //BUCO! This needs its own units.csv column to see how much we refill!
176  return true;
177  }
178  } else if (diss <= 1.2*rad*rad) {
179  timer += SIMULATION_ATOM;
180  static float tmp = XMLSupport::parse_float( vs_config->getVariable( "physics", "docking_time", "10" ) );
181  if (timer >= 1.5*tmp) {
182  if (physicallyDock) {
183  return parent->Dock( utdw );
184  } else {
185  float maxWillingToRefill = utdw->WarpCapData();
186  if (maxWillingToRefill >= MinimumCapacityToRefuelOnLand)
187  parent->RefillWarpEnergy(); //BUCO! This needs its own units.csv column to see how much we refill!
188  return true;
189  }
190  }
191  }
192  return false;
193 }
195 {
196  timer -= SIMULATION_ATOM;
197  bool isplanet = utdw->isUnit() == PLANETPTR;
198  if (timer < 0) {
199  static float tmp = XMLSupport::parse_float( vs_config->getVariable( "physics", "un_docking_time", "180" ) );
200  timer = tmp;
201  EnqueueOrder( new ChangeHeading( parent->Position()*2-utdw->Position(), 4, 1, true ) );
202  if (physicallyDock)
203  return parent->UnDock( utdw );
204  else
205  return true;
206  } else if (!physicallyDock) {
207  if (isplanet) {
208  //orbit;
209  QVector cur = utdw->Position()-parent->Position();
210  QVector up = QVector( 0, 1, 0 );
211  if (up.i == cur.i && up.j == cur.j && up.k == cur.k)
212  up = QVector( 0, 0, 1 );
213  SetDest( cur.Cross( up )*10000 );
214  MoveTo::Execute();
215  } else {
216  Movement( utdw );
217  }
218  }
219  return false;
220 }
222 {
223  //this is a good heuristic... find the location where you are.compare with center...then fly the fuck away
224  QVector awaydir = parent->Position()-utdw->Position();
225  float len = ( (utdw->rSize()+parent->rSize()*2)/awaydir.Magnitude() );
226  awaydir *= len;
227  SetDest( awaydir+utdw->Position() );
228  MoveTo::Execute();
229  timer -= SIMULATION_ATOM;
230  return (len < 1) || done || timer < 0;
231 }
233 }
234