24 return nodockwithclear;
38 if ( !( ( (
Planet*) un )->isAtmospheric() ) )
66 bool FireAt::PursueTarget(
Unit *un,
bool leader )
71 return rand() < .9*RAND_MAX;
73 return rand() < .2*RAND_MAX;
82 if (limitmin > -.99) {
87 if (pnorm.Dot( worldlimit ) < limitmin)
102 static float mintimetoswitch =
107 agg = aggressivitylevel;
116 ReInit( aggressivitylevel );
136 this->relation = rel;
159 vector< TargetAndRange > listOfTargets[2];
172 const unsigned int lotsize[2] = {listOfTargets[0].size(), listOfTargets[1].size()};
173 for (vector< RangeSortedTurrets >::iterator uniter = turret.begin(); uniter != turret.end(); ++uniter) {
174 bool foundfinal =
false;
175 uniter->tur->Target( NULL );
176 uniter->tur->TargetTurret( NULL );
178 if (finalChoice.
range < uniter->gunrange
181 uniter->tur->Target( finalChoice.
t );
182 uniter->tur->TargetTurret( finalChoice.
t );
188 for (
unsigned int f = 0;
f < 2 && !foundfinal;
f++) {
189 for (
unsigned int i = 0;
i < lotsize[
f];
i++) {
190 const int index = (count+
i)%lotsize[
f];
191 if (listOfTargets[
f][index].range < uniter->gunrange) {
193 uniter->tur->
Target( listOfTargets[
f][index].t );
209 unsigned int bnum = 0;
210 for (; bnum < tbin.size(); bnum++)
211 if ( su->
attackPreference() == tbin[bnum].turret[0].tur->attackPreference() )
213 if ( bnum >= tbin.size() )
215 float gspeed, grange, mrange;
219 float ggspeed, ggrange, mmrange;
223 if (ggspeed > gspeed) gspeed = ggspeed;
224 if (ggrange > grange) grange = ggrange;
225 if (mmrange > mrange) mrange = mmrange;
228 if (tbin[bnum].maxrange < grange)
229 tbin[bnum].maxrange = grange;
233 float Priority(
Unit *me,
Unit *targ,
float gunrange,
float rangetotarget,
float relationship,
char *rolepriority )
235 if (relationship >= 0)
240 char invrolepriority = 31-*rolepriority;
241 if (invrolepriority <= 0)
243 if (rangetotarget < 1 && rangetotarget > -1000)
246 rangetotarget = fabs( rangetotarget );
247 if (rangetotarget < .5*gunrange)
248 rangetotarget = .5*gunrange;
250 static float mountless_gunrange =
252 gunrange = mountless_gunrange;
254 float inertial_priority = 0;
256 static float mass_inertial_priority_cutoff =
258 if (me->
GetMass() > mass_inertial_priority_cutoff) {
259 static float mass_inertial_priority_scale =
263 normv *= Speed ? 1.0f/Speed : 1.0f;
265 ourToThem.Normalize();
266 inertial_priority = mass_inertial_priority_scale*( .5+.5*( normv.Dot( ourToThem ) ) )*me->
GetMass()*Speed;
270 float threat_priority = (me->
Threat() == targ) ? threat_weight : 0;
271 threat_priority += (targ->
Target() == me) ? threat_weight : 0;
272 float role_priority01 = ( (
float) *rolepriority )/31.;
273 float range_priority01 = .5*gunrange/rangetotarget;
274 return range_priority01*role_priority01+inertial_priority+threat_priority;
277 float Priority(
Unit *me,
Unit *targ,
float gunrange,
float rangetotarget,
float relationship )
279 char rolepriority = 0;
280 return Priority( me, targ, gunrange, rangetotarget, relationship, &rolepriority );
283 template <
class T,
size_t n >
302 template <
size_t numTuple >
307 vector< TurretBin > *tbin;
312 char maxrolepriority;
325 vector< TurretBin > *tbin,
327 char maxrolepriority,
330 this->fireat = fireat;
338 for (
size_t i = 0;
i < numTuple; ++
i) {
339 double tmpless = currad-innermaxrange[
i];
340 double tmpmore = currad+innermaxrange[
i];
341 this->maxinnerrangeless[
i] = tmpless;
342 this->maxinnerrangemore[
i] = tmpmore;
344 this->maxrolepriority = maxrolepriority;
348 this->rolepriority = 31;
349 this->gunrange = gunrange;
350 this->numtargets = 0;
351 this->maxtargets = maxtargets;
356 bool lesscheck = unkey < maxinnerrangeless[0];
357 bool morecheck = unkey > maxinnerrangemore[0];
358 if (reachedMore ==
false || reachedLess ==
false) {
359 if (lesscheck || morecheck) {
364 if (mytarg && rolepriority < maxrolepriority) {
366 }
else if (reachedLess ==
true && reachedMore ==
true) {
367 for (
size_t i = 1;
i < numTuple; ++
i)
368 if (unkey > maxinnerrangeless[
i] && unkey < maxinnerrangemore[
i]) {
369 maxinnerrangeless[0] = maxinnerrangeless[i];
370 maxinnerrangemore[0] = maxinnerrangemore[i];
377 return ShouldTargetUnit( un, distance );
382 float rangetotarget = distance;
383 float rel0 = parent->getRelation( un );
386 , (parentparent ? parentparent->getRelation( un ) : rel0)
388 float relationship = rel0;
389 for (
unsigned int i = 1;
i <
sizeof (rel)/
sizeof (*rel);
i++)
390 if (rel[
i] < relationship)
391 relationship = rel[
i];
393 float tmp =
Priority( parent, un, gunrange, rangetotarget, relationship, &rp );
394 if (tmp > priority) {
399 for (vector< TurretBin >::iterator
k = tbin->begin();
k != tbin->end(); ++
k) {
400 if (rangetotarget >
k->maxrange)
403 if (relationship < 0) {
405 k->listOfTargets[0].push_back(
TargetAndRange( un, rangetotarget, relationship ) );
407 }
else if (tprior < 31) {
408 k->listOfTargets[1].push_back(
TargetAndRange( un, rangetotarget, relationship ) );
414 return (maxtargets == 0) || (numtargets < maxtargets);
426 float gunspeed, gunrange, missilerange;
427 parent->getAverageGunSpeed( gunspeed, gunrange, missilerange );
429 static float mintimetoswitch =
431 static float minnulltimetoswitch =
433 static int minnumpollers =
435 static int maxnumpollers =
437 static int numpollers[2] = {maxnumpollers, maxnumpollers};
439 static float nextframenumpollers[2] = {maxnumpollers, maxnumpollers};
440 if (lastchangedtarg+mintimetoswitch > 0)
444 int hastarg = (curtarg == NULL) ? 0 : 1;
458 if (
numpolled[hastarg] > numpollers[hastarg])
465 if ( isJumpablePlanet( curtarg ) )
467 bool wasnull = (curtarg == NULL);
472 if ( curtarg != NULL && ( *fg->
directive.begin() ) == toupper( *fg->
directive.begin() ) )
477 vector< TurretBin >tbin;
479 un_iter subun = parent->getSubUnits();
480 for (; (su = *subun) != NULL; ++subun) {
483 static bool assignpointdef =
495 std::sort( tbin.begin(), tbin.end() );
497 float mytargrange = FLT_MAX;
498 static float unitRad =
500 static char maxrolepriority =
506 maxranges[0] = gunrange;
507 maxranges[1] = missilerange;
509 maxranges[0] = (tbin[0].maxrange > gunrange ? tbin[0].maxrange : gunrange);
511 unitLocator.action.init(
this, parent, gunrange, &tbin, maxranges, maxrolepriority, maxtargets );
512 static int gcounter = 0;
515 if (gcounter++ < min_rechoose_interval || rand()/8 < RAND_MAX/9) {
519 for (
unsigned int i = 0;
i < np; ++
i) {
525 if (lead != NULL && lead != parent && ( lead = lead->
Target() ) != NULL)
534 if (unitLocator.action.mytarg == NULL)
537 Unit *mytarg = unitLocator.action.mytarg;
540 efrel = parent->getRelation( mytarg );
544 for (vector< TurretBin >::iterator
k = tbin.begin();
k != tbin.end(); ++
k)
545 k->AssignTargets( my_target, parent->cumulative_transformation_matrix );
546 parent->LockTarget(
false );
549 nextframenumpollers[hastarg] += 2;
550 if (nextframenumpollers[hastarg] > maxnumpollers)
551 nextframenumpollers[hastarg] = maxnumpollers;
554 nextframenumpollers[hastarg] -= .05;
555 if (nextframenumpollers[hastarg] < minnumpollers)
556 nextframenumpollers[hastarg] = minnumpollers;
559 if (parent->Target() != mytarg) {
560 nextframenumpollers[hastarg] += 2;
561 if (nextframenumpollers[hastarg] > maxnumpollers)
562 nextframenumpollers[hastarg] = maxnumpollers;
564 nextframenumpollers[hastarg] -= .01;
565 if (nextframenumpollers[hastarg] < minnumpollers)
566 nextframenumpollers[hastarg] = minnumpollers;
569 parent->Target( mytarg );
570 parent->LockTarget(
true );
571 SignalChosenTarget();
581 if (test++%1000 == 1)
584 float gunspeed, gunrange, missilerange;
585 parent->getAverageGunSpeed( gunspeed, gunrange, missilerange );
586 float angle = parent->cosAngleTo( targ, dist, parent->
GetComputerData().
itts ? gunspeed : FLT_MAX, gunrange, false );
588 targ->
Threaten( parent, angle/(dist < .8 ? .8 : dist) );
589 if ( targ == parent->
Target() )
592 static float fireangle_minagg =
595 "MaximumFiringAngle.minagg",
597 static float fireangle_maxagg =
600 "MaximumFiringAngle.maxagg",
602 float temp = parent->TrackingGuns( missilelock );
603 bool isjumppoint = targ->
isUnit() ==
PLANETPTR && ( (
Planet*) targ )->GetDestinations().empty() ==
false;
604 float fangle = (fireangle_minagg+fireangle_maxagg*agg)/(1.0
f+agg);
607 && ( (angle > fangle) || ( temp && (angle > temp) ) || ( missilelock && (angle > 0) ) ) ) && !isjumppoint;
614 if (attackers > max_attackers && max_attackers > 0) {
615 static float attacker_switch_time =
618 int seed = ( ( ( (size_t) parent )&0xffffffff )^curtime );
646 static bool AlwaysFireAutotrackers =
650 if (AlwaysFireAutotrackers && !shouldfire) {
663 bool fire_missile = lockmissile && rand() < RAND_MAX*missileprobability*
SIMULATION_ATOM;
665 if ( shouldfire && delay < parent->pilot->getReactionTime() )
667 else if (!shouldfire)
673 parent->Fire(
FireBitmask( parent, shouldfire, fire_missile ),
true );
679 if (istargetjumpableplanet) {
680 istargetjumpableplanet = ( !( (
Planet*) targ )->GetDestinations().empty() ) && (parent->GetJumpStatus().drive >= 0);
682 return istargetjumpableplanet;
692 if ( ( fg = parent->getFlightgroup() ) )
693 if (fg->
directive.find(
"." ) != string::npos)
694 ct = (parent->Target() == NULL);
703 bool missilelock =
false;
708 if (parent->isUnit() ==
UNITPTR) {
711 UpdateContrabandSearch();
714 static float contraband_initiate_time =
718 static float contraband_to_player =
720 static float contraband_to_target =
723 unsigned int modulo = ( (
unsigned int) (contraband_initiate_time/cont_initiate_time) );
727 RandomInitiateCommunication( comm_to_player, comm_to_target );
729 InitiateContrabandSearch( contraband_to_player, contraband_to_target );
732 bool shouldfire =
false;
733 bool istargetjumpableplanet =
false;
734 if ( ( targ = parent->
Target() ) ) {
735 istargetjumpableplanet = isJumpablePlanet( targ );
738 if (parent->GetNumMounts() > 0)
739 if (!istargetjumpableplanet)
740 shouldfire |= ShouldFire( targ, missilelock );
744 lastchangedtarg = -100000;
748 }
else if (had_target) {
750 lastchangedtarg = -100000;
752 PossiblySwitchTarget( istargetjumpableplanet );
753 if ( (!istargetjumpableplanet) && parent->GetNumMounts() > 0 )
754 FireWeapons( shouldfire, missilelock );