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
bolt_generic.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include "bolt.h"
3 #include "gfxlib.h"
4 #include "gfx/mesh.h"
5 #include "gfxlib_struct.h"
6 #include <vector>
7 
8 #include <string>
9 #include <algorithm>
10 #include "unit_generic.h"
11 #include "audiolib.h"
12 #include "config_xml.h"
13 
14 using std::vector;
15 using std::string;
16 
17 Bolt::Bolt( const weapon_info *typ,
18  const Matrix &orientationpos,
19  const Vector &shipspeed,
20  void *owner,
21  CollideMap::iterator hint ) : cur_position( orientationpos.p )
22  , ShipSpeed( shipspeed )
23 {
24  VSCONSTRUCT2( 't' )
26  prev_position = cur_position;
27  this->owner = owner;
28  this->type = typ;
29  curdist = 0;
30  CopyMatrix( drawmat, orientationpos );
31  Vector vel = shipspeed+orientationpos.getR()*typ->Speed;
32  if (typ->type == weapon_info::BOLT) {
33  ScaleMatrix( drawmat, Vector( typ->Radius, typ->Radius, typ->Length ) );
34  decal = Bolt::AddTexture( q, typ->file );
35  this->location =
37  size(),
38  decal,
39  false ).bolt_index,
40  (shipspeed+orientationpos.getR()
41  *typ->Speed).Magnitude()*.5,
42  cur_position+vel*SIMULATION_ATOM*.5 ),
43  hint );
44  q->bolts[decal].push_back( *this );
45  } else {
46  ScaleMatrix( drawmat, Vector( typ->Radius, typ->Radius, typ->Radius ) );
47  decal = Bolt::AddAnimation( q, typ->file, cur_position );
48 
49  this->location =
51  size(),
52  decal,
53  true ).bolt_index,
54  (shipspeed+orientationpos.getR()
55  *typ->Speed).Magnitude()*.5,
56  cur_position+vel*SIMULATION_ATOM*.5 ),
57  hint );
58  q->balls[decal].push_back( *this );
59  }
60 }
61 
63 {
64  return b.bolt_index>>8;
65 }
66 
68 {
69  const weapon_info *type = this->type;
70  float speed = type->Speed;
71  curdist += speed*SIMULATION_ATOM;
72  prev_position = cur_position;
73  cur_position +=
74  ( ( ShipSpeed+drawmat.getR()*speed
75  /( (type->type
76  == weapon_info::BALL)*type->Radius+(type->type != weapon_info::BALL)*type->Length ) ).Cast()*SIMULATION_ATOM );
77  if (curdist > type->Range) {
78  this->Destroy( nondecal_index( index ) ); //risky
79  return false;
80  }
81  Collidable updated( **location );
82  updated.SetPosition( .5*(prev_position+cur_position) );
84  return true;
85 }
86 
88 {
89  CollideMap *collidemap;
90  StarSystem *starSystem;
91 public: UpdateBolt( StarSystem *ss, CollideMap *collidemap )
92  {
93  this->starSystem = ss;
94  this->collidemap = collidemap;
95  }
96  void operator()( Collidable &collidable )
97  {
98  if (collidable.radius < 0) {
99  Bolt *thus = Bolt::BoltFromIndex( starSystem, collidable.ref );
100  if ( !collidemap->CheckCollisions( thus, collidable ) )
101  thus->Update( collidable.ref );
102  }
103  }
104 };
105 
106 namespace vsalg
107 {
108 //
109 
110 template < typename IT, typename F >
111 void for_each( IT start, IT end, F f )
112 {
113  //This way, deletion of current item is allowed
114  //- drawback: iterator copy each iteration
115  while (start != end)
116  f( *start++ );
117 }
118 
119 //
120 }
121 
123 {
124  UpdateBolt sub;
125 public: UpdateBolts( StarSystem *ss, CollideMap *collidemap ) : sub( ss, collidemap ) {}
126  template < class T >
127  void operator()( T &collidableList )
128  {
129  vsalg::for_each( collidableList.begin(), collidableList.end(), sub );
130  }
131 };
132 
134 {
136  vsalg::for_each( cm->sorted.begin(), cm->sorted.end(), UpdateBolt( ss, cm ) );
137  vsalg::for_each( cm->toflattenhints.begin(), cm->toflattenhints.end(), UpdateBolts( ss, cm ) );
138 }
139 
140 bool Bolt::Collide( Unit *target )
141 {
142  Vector normal;
143  float distance;
144  Unit *affectedSubUnit;
145  if ( ( affectedSubUnit = target->rayCollide( prev_position, cur_position, normal, distance ) ) ) {
146  //ignore return
147  if (target == owner) return false;
148  enum clsptr type = target->isUnit();
149  if (type == NEBULAPTR || type == ASTEROIDPTR) {
150  static bool collideroids =
151  XMLSupport::parse_bool( vs_config->getVariable( "physics", "AsteroidWeaponCollision", "false" ) );
152  if ( type != ASTEROIDPTR || (!collideroids) )
153  return false;
154  }
155  static bool collidejump = XMLSupport::parse_bool( vs_config->getVariable( "physics", "JumpWeaponCollision", "false" ) );
156  if ( type == PLANETPTR && (!collidejump) && !target->GetDestinations().empty() )
157  return false;
158  QVector tmp = (cur_position-prev_position).Normalize();
159  tmp = tmp.Scale( distance );
160  distance = curdist/this->type->Range;
161  GFXColor coltmp( this->type->r, this->type->g, this->type->b, this->type->a );
162  target->ApplyDamage( (prev_position+tmp).Cast(),
163  normal,
164  this->type->Damage*( (1-distance)+distance*this->type->Longrange ),
165  affectedSubUnit,
166  coltmp,
167  owner,
168  this->type->PhaseDamage*( (1-distance)+distance*this->type->Longrange ) );
169  return true;
170  }
171  return false;
172 }
173 
175 {
176  size_t ind = nondecal_index( b );
177  if (b.bolt_index&128)
178  return &ss->bolts->balls[b.bolt_index&0x7f][ind];
179  else
180  return &ss->bolts->bolts[b.bolt_index&0x7f][ind];
181 }
182 
184 {
186  if ( tmp->Collide( un ) ) {
187  tmp->Destroy( nondecal_index( b ) );
188  return true;
189  }
190  return false;
191 }
192 
193 Collidable::CollideRef Bolt::BoltIndex( int index, int decal, bool isBall )
194 {
196  temp.bolt_index = index;
197  temp.bolt_index <<= 8;
198  temp.bolt_index |= decal;
199  temp.bolt_index |= isBall ? 128 : 0;
200  return temp;
201 }
202 
203 void BoltDestroyGeneric( Bolt *whichbolt, unsigned int index, int decal, bool isBall )
204 {
207  vector< vector< Bolt > > *target;
208  if (!isBall)
209  target = &q->bolts;
210  else
211  target = &q->balls;
212  vector< Bolt > *vec = &(*target)[decal];
213  if (&(*vec)[index] == whichbolt) {
214  unsigned int tsize = vec->size();
216  cm->UpdateBoltInfo( vec->back().location, (*(*vec)[index].location)->ref );
217 
218  assert( index < tsize );
219  cm->erase( (*vec)[index].location );
220  if ( index+1 != vec->size() )
221  (*vec)[index] = vec->back(); //just a memcopy, yo
222  vec->pop_back(); //pop that back up
223  } else {
224  VSFileSystem::vs_fprintf( stderr, "Bolt Fault Nouveau! Not found in draw queue! No Chance to recover\n" );
225  fflush( stderr );
226  assert( 0 );
227  }
228 }
229