8 #include "../gfx/camera.h"
18 inline static float mymax(
float a,
float b )
20 return (a > b) ? a :
b;
23 inline static float mymin(
float a,
float b )
25 return (a < b) ? a :
b;
55 CollideInfo.
object.b = NULL;
60 local_transformation = trans;
88 if (curthick > thickness)
94 memset( beam, 0,
sizeof (*beam)*numvertex );
106 #define V( xx, yy, zz, ss, tt, aa ) \
113 beam[a].r = this->Col.r*aa; \
114 beam[a].g = this->Col.g*aa; \
115 beam[a].b = this->Col.b*aa; \
121 void Beam::RecalculateVertices(
const Matrix &trans )
125 static float hitfadelocation =
127 static float scoopangle =
130 static float scooptanangle = (
float)
tan( scoopangle );
132 static float scoopa =
134 static int radslices =
136 static int longslices =
138 const float fadeinlength = 4;
139 const bool tractor = (damagerate < 0 && phasedamage > 0);
140 const bool repulsor = (damagerate > 0 && phasedamage < 0);
142 float righttex = leftex+texturestretch*curlength/curthick;
143 float len = (impact == ALIVE)
146 float fadelen = (impact == ALIVE) ? len*fadelocation : len*hitfadelocation;
147 const bool doscoop = ( scoop && (tractor || repulsor) );
148 float fadetex = leftex+(righttex-leftex)*fadelocation;
149 const float touchtex = leftex-fadeinlength*.5*texturestretch;
150 float thick = curthick != thickness ? curthick-radialspeed*
SIMULATION_ATOM
152 float ethick = ( thick/( (thickness > 0) ? thickness : 1.0
f ) )*(doscoop ? curlength*scooptanangle : 0);
153 const float invfadelen = thick*fadeinlength;
154 const float invfadealpha =
mymax( 0.0f,
mymin( 1.0f, 1.0f-
mysqr( invfadelen/len ) ) );
155 const float fadealpha =
mymax( 0.0f,
mymin( 1.0f, 1.0f-
mysqr( fadelen/len ) ) );
156 const float endalpha = 0.0f;
157 const float peralpha = doscoop ? 0.25f : 0.0f;
167 const float xyalpha =
mymax( 0, fabs(
z*r ) );
168 const float xzalpha =
mymax( 0, fabs(
y*r ) )*0.5f;
169 const float yzalpha =
mymax( 0, fabs(
x*r ) )*0.5f;
170 const float lislices = (longslices > 0) ? 1.0f/longslices : 0.0f;
171 const float rislices = (radslices > 0) ? 1.0f/radslices : 0.0f;
172 const float bxyalpha = xyalpha*lislices;
173 const float bxzalpha = xzalpha*rislices;
174 const float byzalpha = yzalpha*rislices;
175 const float zs = lislices*(fadelen-invfadelen);
176 const float ths = lislices*ethick*1.2f;
177 const float rim1 = (radslices-1)*rislices*2;
178 for (
int i = 0;
i < longslices;
i++) {
179 float f =
i*lislices;
180 float xa =
mymax( 0, 1.0f-
mysqr( f ) )*byzalpha*scoopa;
181 float ya =
mymax( 0, 1.0f-
mysqr( f ) )*bxzalpha*scoopa;
182 float za =
mymax( 0, 1.0f-
mysqr( f ) )*bxyalpha*scoopa;
183 float th = f*ethick+thick;
184 float z =
i*zs+invfadelen;
186 V( -th, +th, z, 0, 0.5f, za );
187 V( -th, -th, z, 0, 0.0f, za );
188 V( +th, -th, z, 1, 0.0f, za );
189 V( +th, +th, z, 1, 0.5f, za );
193 for (
int j = -radslices/2;
j <= radslices/2;
j++) {
194 float y =
j*2*th*rislices;
195 float f = 1.0f-fabs( rim1*
j*rislices );
196 float sf =
sqrt( f );
199 V( -(th+ths)*sf, y, z+zs, 1, 0.50f, aa );
200 V( -(th-ths)*sf, y, z-zs, 0, 0.50f, aa );
201 V( 0, y, z-zs, 0, 0.75f, aa );
202 V( 0, y, z+zs, 1, 0.75f, aa );
203 V( 0, y, z+zs, 1, 0.75f, aa );
204 V( 0, y, z-zs, 0, 0.75f, aa );
205 V( +(th-ths)*sf, y, z-zs, 0, 1.00f, aa );
206 V( +(th+ths)*sf, y, z+zs, 1, 1.00f, aa );
211 for (
int j = -radslices/2;
j <= radslices/2;
j++) {
212 float x =
j*2*th*rislices;
213 float f = 1.0f-fabs( rim1*
j*rislices );
214 float sf =
sqrt( f );
217 V( x, -(th+ths)*sf, z+zs, 1, 0.50f, aa );
218 V( x, -(th-ths)*sf, z-zs, 0, 0.50f, aa );
219 V( x, 0, z-zs, 0, 0.75f, aa );
220 V( x, 0, z+zs, 1, 0.75f, aa );
221 V( x, 0, z+zs, 1, 0.75f, aa );
222 V( x, 0, z-zs, 0, 0.75f, aa );
223 V( x, +(th-ths)*sf, z-zs, 0, 1.00f, aa );
224 V( x, +(th+ths)*sf, z+zs, 1, 1.00f, aa );
232 V( 0, 0, invfadelen, leftex, 0.5f, invfadealpha );
233 V( 0, thick, invfadelen, leftex, 1, peralpha*invfadealpha );
234 V( 0, thick, fadelen, fadetex, 1, peralpha*fadealpha );
235 V( 0, 0, fadelen, fadetex, 0.5f, fadealpha );
236 V( 0, 0, invfadelen, leftex, 0.5f, invfadealpha );
237 V( 0, 0, fadelen, fadetex, 0.5f, fadealpha );
238 V( 0, -thick, fadelen, fadetex, 0, peralpha*fadealpha );
239 V( 0, -thick, invfadelen, leftex, 0, peralpha*invfadealpha );
241 V( 0, 0, fadelen, fadetex, 0.5f, fadealpha );
242 V( 0, thick, fadelen, fadetex, 1, peralpha*fadealpha );
243 V( 0, thick, len, righttex, 1, peralpha*endalpha );
244 V( 0, 0, len, righttex, 0.5f, endalpha );
245 V( 0, 0, fadelen, fadetex, 0.5f, fadealpha );
246 V( 0, 0, len, righttex, 0.5f, endalpha );
247 V( 0, -thick, len, righttex, 0, peralpha*endalpha );
248 V( 0, -thick, fadelen, fadetex, 0, peralpha*fadealpha );
250 V( 0, 0, invfadelen, leftex, 0.5f, invfadealpha );
251 V( 0, thick, invfadelen, leftex, 1, peralpha*invfadealpha );
252 V( 0, thick, 0, touchtex, 1, peralpha );
253 V( 0, 0, 0, touchtex, 0.5f, 1.0f );
254 V( 0, 0, invfadelen, leftex, 0.5f, invfadealpha );
255 V( 0, 0, 0, touchtex, 0.5f, 1.0f );
256 V( 0, -thick, 0, touchtex, 0, peralpha );
257 V( 0, -thick, invfadelen, leftex, 0, peralpha*invfadealpha );
259 for (
int i = 0, upto = a;
i < upto;
i++, a++) {
261 float aux = beam[
a].
x;
262 beam[
a].
x = beam[
a].
y;
278 Unit *targetToCollideWith,
286 if (curlength > range)
297 Matrix cumulative_transformation_matrix;
299 cumulative_transformation.
Compose( trans, m );
300 cumulative_transformation.
to_matrix( cumulative_transformation_matrix );
301 bool possible =
AdjustMatrix( cumulative_transformation_matrix,
Vector( 0, 0, 0 ), targ, speed,
false, tracking_cone );
302 static bool firemissingautotrackers =
304 if (targ && possible ==
false && !firemissingautotrackers)
307 center = cumulative_transformation.
position;
309 #ifndef PERFRAMESOUND
313 if (curthick > thickness)
314 curthick = thickness;
321 CollideHuge( CollideInfo, listen_to_owner ? targetToCollideWith : NULL, firer, superunit );
322 if ( !(curlength <= range && curlength > 0) ) {
324 if (curlength > range)
329 QVector tmpvec( center+direction.Cast().Scale( curlength ) );
330 QVector tmpMini = center.Min( tmpvec );
331 tmpvec = center.Max( tmpvec );
336 CollideInfo.
object.b =
this;
338 ( ( (CollideInfo.
Maxi.i
343 CollideInfo.
Mini = tmpMini;
344 CollideInfo.
Maxi = tmpvec;
348 CollideInfo.
Mini = tmpMini;
349 CollideInfo.
Maxi = tmpvec;
360 if (
this == NULL || target == NULL) {
367 QVector direction( this->direction.Cast() );
368 QVector end( center+direction.Scale( curlength ) );
371 static bool collideroids =
396 static float scoopcosangle = (
float)
cos( scoopangle );
397 static float maxrelspeed =
399 static float c_lighting =
401 static float u_lighting =
403 static float f_lighting =
405 static float d_lighting =
407 static float o_lighting =
409 static float c_ors_m =
411 static float c_trs_m =
414 static float u_ors_m =
416 static float u_trs_m =
419 static float f_ors_m =
421 static float f_trs_m =
424 static float o_ors_m =
426 static float o_trs_m =
429 bool tractor = (damagerate < 0 && phasedamage > 0);
430 bool repulsor = (damagerate > 0 && phasedamage < 0);
431 if ( scoop && (tractor || repulsor) ) {
434 float angle = this->direction*d2;
435 if (angle > scoopcosangle) {
436 end = center+d2*curlength;
437 direction = end-center;
438 direction.Normalize();
442 if ( ( colidee = target->
rayCollide( center, end, normal, distance ) ) ) {
443 if ( !( scoop && (tractor || repulsor) ) ){
444 this->curlength = distance;
446 float curlength = distance;
449 float tmp = (curlength/range);
450 float appldam = (damagerate*
SIMULATION_ATOM*curthick/thickness)*( (1-tmp)+tmp*rangepenalty );
451 float phasdam = (phasedamage*
SIMULATION_ATOM*curthick/thickness)*( (1-tmp)+tmp*rangepenalty );
452 float owner_rsize = superunit->
rSize();
453 int owner_faction = superunit->
faction;
454 if (tractor || repulsor) {
455 bool fp = o_fp, fi = o_fi;
456 if (target->
faction == owner_faction)
457 fp = f_fp, fi = f_fi;
459 else if (target->
faction == upgradesfaction)
460 fp = u_fp, fi = u_fi;
462 else if (target->
faction == cargofaction)
463 fp = c_fp, fi = c_fi;
466 fp = d_fp, fi = d_fi;
469 float lighting = o_lighting;
470 if (target->
faction == owner_faction)
471 lighting = f_lighting;
473 else if (target->
faction == upgradesfaction)
474 lighting = u_lighting;
476 else if (target->
faction == cargofaction)
477 lighting = c_lighting;
480 lighting = d_lighting;
488 float relspeed = target->
GetVelocity()*direction.Cast();
489 if (relspeed < maxrelspeed) {
497 float ors_m = o_ors_m, trs_m = o_trs_m, ofs = o_o;
498 if (target->
faction == owner_faction)
499 ors_m = f_ors_m, trs_m = f_trs_m, ofs = f_o;
501 else if (target->
faction == upgradesfaction)
502 ors_m = u_ors_m, trs_m = u_trs_m, ofs = u_o;
504 else if (target->
faction == cargofaction)
505 ors_m = c_ors_m, trs_m = c_trs_m, ofs = c_o;
509 Unit *un = superunit;
510 if ( target->
faction == upgradesfaction || owner_rsize*nbig > target->
rSize() ) {
515 bool isnotcargo = (c == NULL);
523 tmp.category =
"Uncategorized_Cargo";
525 tmp.price = spacejunk;
529 if (target->
faction != upgradesfaction) {
530 tmp.content = target->
name;
531 tmp.category =
"starships";
532 static float starshipprice =
534 static float starshipmass =
536 static float starshipvolume =
538 tmp.price = starshipprice;
540 tmp.mass = starshipmass;
541 tmp.volume = starshipvolume;
550 static int tractor_onboard =
552 "tractor_onboard.wav" ) );
556 if (tmp && tmp->
owner == un) {
558 static int tractor_onboard_fromturret =
560 "player_tractor_cargo_fromturret",
561 "tractor_onboard.wav" ) );
571 target->
ApplyDamage( center.Cast()+direction*curlength, normal, appldam, colidee, coltmp, owner, phasdam );