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
firekeyboard.cpp
Go to the documentation of this file.
1 
4 #include <set>
5 #include "firekeyboard.h"
6 #include "flybywire.h"
7 #include "navigation.h"
8 #include "in_joystick.h"
9 #include "cmd/unit_generic.h"
10 #include "communication.h"
11 #include "gfx/cockpit.h"
12 #include "gfx/animation.h"
13 #include "audiolib.h"
14 #include "config_xml.h"
15 #include "cmd/images.h"
16 #include "cmd/planet.h"
17 #include "cmd/script/flightgroup.h"
18 #include "cmd/script/mission.h"
19 #include "vs_globals.h"
20 #include "gfx/car_assist.h"
21 #include "cmd/unit_util.h"
22 #include <algorithm>
23 #include "fire.h"
24 #include "docking.h"
25 #include "cmd/pilot.h"
26 //for getatmospheric
27 #include "cmd/role_bitmask.h"
29 #include "networking/netclient.h"
30 #include "universe_util.h"
31 
32 extern bool toggle_pause();
33 
34 FireKeyboard::FireKeyboard( unsigned int whichplayer, unsigned int whichjoystick ) : Order( WEAPON, 0 )
35 {
36  memset( savedTargets, 0, sizeof (void*)*NUMSAVEDTARGETS );
37  this->autotrackingtoggle = 1;
38  this->cloaktoggle = true;
39  this->whichjoystick = whichjoystick;
40  this->whichplayer = whichplayer;
41  gunspeed = gunrange = .0001;
42  refresh_target = true;
43 }
44 
45 const unsigned int NUMCOMMKEYS = 10;
46 
48 {
50  {
52 commKeys[3] = commKeys[4] = commKeys[5] = commKeys[6] = commKeys[7] = commKeys[8] = commKeys[9] = turretaikey = UP;
62  shieldpowerstate = 1;
63 #ifdef CAR_SIM
64  blinkleftkey = blinkrightkey = headlightkey = sirenkey = UP;
65 #endif
66  doc = und = req = 0;
67  }
70  bool doc;
71  bool und;
72  bool req;
73 #ifdef CAR_SIM
74  KBSTATE blinkleftkey;
75  KBSTATE blinkrightkey;
76  KBSTATE headlightkey;
77  KBSTATE sirenkey;
78 #endif
129  //Added for nearest targets keys --ch
137 };
138 
139 static std::vector< FIREKEYBOARDTYPE >vectorOfKeyboardInput;
140 
142 {
143  while (vectorOfKeyboardInput.size() <= (unsigned int) _Universe->CurrentCockpit() || vectorOfKeyboardInput.size()
144  <= (unsigned int) MAX_JOYSTICKS)
147 }
148 
150 {
152 }
153 
155 {
157 }
158 
160 {
161  if (k == PRESS) {
162  float pow = 1./3;
163  static soundContainer sc;
164  if (sc.sound < 0) {
165  static string str = vs_config->getVariable( "cockpitaudio", "shield", "vdu_d" );
166  sc.loadsound( str );
167  }
168  sc.playsound();
169  if (g().shieldpowerstate != pow)
170  g().shieldpowerstate = pow;
171  else
172  g().shieldpowerstate = 1;
173  }
174 }
175 
177 {
178  if (k == PRESS) {
179  float pow = 0;
180  static soundContainer sc;
181  if (sc.sound < 0) {
182  static string str = vs_config->getVariable( "cockpitaudio", "shield", "vdu_d" );
183  sc.loadsound( str );
184  }
185  sc.playsound();
186  if (g().shieldpowerstate != pow)
187  g().shieldpowerstate = pow;
188  else
189  g().shieldpowerstate = 1;
190  }
191 }
192 
194 {
195  if (k == PRESS) {
196  float pow = 2./3;
197  static soundContainer sc;
198  if (sc.sound < 0) {
199  static string str = vs_config->getVariable( "cockpitaudio", "shield", "vdu_d" );
200  sc.loadsound( str );
201  }
202  sc.playsound();
203  if (g().shieldpowerstate != pow)
204  g().shieldpowerstate = pow;
205  else
206  g().shieldpowerstate = 1;
207  }
208 }
209 
211 {
212  if (k == PRESS)
213  g().toggleglow = PRESS;
214 }
215 
217 {
218  if (k == PRESS)
220 }
221 
223 {
224  if (k == PRESS)
225  g().togglewarpdrive = PRESS;
226 }
227 
229 {
230  if (k == PRESS)
231  g().toggleanimation = PRESS;
232 }
233 
235 {
236  if (k == PRESS)
237  g().commKeys[0] = PRESS;
238 }
239 
241 {
242  if (k == PRESS)
243  g().commKeys[1] = PRESS;
244 }
245 
247 {
248  if (k == PRESS)
249  g().commKeys[2] = PRESS;
250 }
251 
253 {
254  if (k == PRESS)
255  g().commKeys[3] = PRESS;
256 }
257 
259 {
260  if (k == PRESS)
261  g().commKeys[4] = PRESS;
262 }
263 
265 {
266  if (k == PRESS)
267  g().commKeys[5] = PRESS;
268 }
269 
271 {
272  if (k == PRESS)
273  g().commKeys[6] = PRESS;
274 }
275 
277 {
278  if (k == PRESS)
279  g().commKeys[7] = PRESS;
280 }
281 
283 {
284  if (k == PRESS)
285  g().commKeys[8] = PRESS;
286 }
287 
289 {
290  if (k == PRESS)
291  g().commKeys[9] = PRESS;
292 }
293 
295 {
296  if (k == PRESS)
297  g().saveTargetKeys[0] = PRESS;
298 }
299 
301 {
302  if (k == PRESS)
303  g().saveTargetKeys[1] = PRESS;
304 }
305 
307 {
308  if (k == PRESS)
309  g().saveTargetKeys[2] = PRESS;
310 }
311 
313 {
314  if (k == PRESS)
315  g().saveTargetKeys[3] = PRESS;
316 }
317 
319 {
320  if (k == PRESS)
321  g().saveTargetKeys[4] = PRESS;
322 }
323 
325 {
326  if (k == PRESS)
327  g().saveTargetKeys[5] = PRESS;
328 }
329 
331 {
332  if (k == PRESS)
333  g().saveTargetKeys[6] = PRESS;
334 }
335 
337 {
338  if (k == PRESS)
339  g().saveTargetKeys[7] = PRESS;
340 }
341 
343 {
344  if (k == PRESS)
345  g().saveTargetKeys[8] = PRESS;
346 }
347 
349 {
350  if (k == PRESS)
351  g().saveTargetKeys[9] = PRESS;
352 }
353 
355 {
356  if (k == PRESS)
357  g().restoreTargetKeys[0] = PRESS;
358 }
359 
361 {
362  if (k == PRESS)
363  g().restoreTargetKeys[1] = PRESS;
364 }
365 
367 {
368  if (k == PRESS)
369  g().restoreTargetKeys[2] = PRESS;
370 }
371 
373 {
374  if (k == PRESS)
375  g().restoreTargetKeys[3] = PRESS;
376 }
377 
379 {
380  if (k == PRESS)
381  g().restoreTargetKeys[4] = PRESS;
382 }
383 
385 {
386  if (k == PRESS)
387  g().restoreTargetKeys[5] = PRESS;
388 }
389 
391 {
392  if (k == PRESS)
393  g().restoreTargetKeys[6] = PRESS;
394 }
395 
397 {
398  if (k == PRESS)
399  g().restoreTargetKeys[7] = PRESS;
400 }
401 
403 {
404  if (k == PRESS)
405  g().restoreTargetKeys[8] = PRESS;
406 }
407 
409 {
410  if (k == PRESS)
411  g().restoreTargetKeys[9] = PRESS;
412 }
413 
414 extern void LeadMe( Unit *un, string directive, string speech, bool changetarget );
415 
416 static void LeadMe( string directive, string speech, bool changetarget )
417 {
419  if (un) LeadMe( un, directive, speech, changetarget );
420 }
421 
423 {
424  if (k == PRESS)
425  g().req = true;
426  if (k == RELEASE)
427  g().req = false;
428 }
429 
431 {
433  if ( k == PRESS && u && (u->isSubUnit() == false) )
434  g().doc = true;
435  if ( k == RELEASE && u && (u->isSubUnit() == false) )
436  g().doc = false;
437 }
438 
440 {
442  if ( k == PRESS && u && (u->isSubUnit() == false) )
443  g().und = true;
444  if ( k == RELEASE && u && (u->isSubUnit() == false) )
445  g().und = false;
446 }
447 
449 {
450  if (k == PRESS) {
451  LeadMe( "", "I am ejecting! Record the current location of my ship.", false ); //used to clear group target
452  LeadMe( "e", "Then get over here and pick me up!", false );
453  g().eject = k;
454  }
455 }
456 
458 {
459  if (k == PRESS) {
460  g().ejectdock = k;
461  g().doc = true;
462  }
463  if (k == RELEASE)
464  g().doc = false;
465 }
466 
468 {
469  if (k == PRESS)
470  g().turretaikey = k;
471 }
472 
474 {
475  if (k == PRESS)
476  g().turretoffkey = k;
477 }
478 
480 {
481  if (k == PRESS)
482  g().turretfaw = k;
483 }
484 
486 {
487  if (k == PRESS)
489 }
490 
492 {
493  if (k == PRESS)
495 }
496 
498 {
499  if (k == PRESS)
500  g().ejectcargo = k;
501 }
502 
504 {
505  if (k == PRESS)
506  g().enslave = k;
507 }
508 
510 {
511  if (k == PRESS)
512  g().freeslave = k;
513 }
514 
516 {
517  if (k == PRESS)
518  g().ejectnonmissioncargo = k;
519 }
520 
522 {
523  if (k == PRESS)
524  g().cloakkey = k;
525 }
526 
528 {
529  if (k == PRESS)
530  g().lockkey = k;
531 }
532 
534 {
535  if (k == PRESS)
536  g().ECMkey = k;
537 }
538 
540 {
541  if (g().firekey == DOWN && k == UP)
542  return;
543  if (k == UP && g().firekey == RELEASE) {} else {
544  g().firekey = k;
545  }
546 }
547 
548 void ExamineWhenTargetKey();
549 
551 {
552  if (g().targetkey != PRESS)
553  g().targetkey = k;
554  if (k == RESET)
555  g().targetkey = PRESS;
556  if (k == PRESS)
558 }
559 
561 {
562  if (g().picktargetkey != PRESS)
563  g().picktargetkey = k;
564  if (k == RESET)
565  g().picktargetkey = PRESS;
566  if (k == PRESS)
568 }
569 
571 {
572  if (g().missiletargetkey != PRESS)
573  g().missiletargetkey = k;
574  if (k == PRESS)
576 }
577 
579 {
580  if (g().incomingmissiletargetkey != PRESS)
582  if (k == PRESS)
584 }
585 
587 {
588  if (g().rmissiletargetkey != PRESS)
589  g().rmissiletargetkey = k;
590  if (k == PRESS)
592 }
593 
595 {
596  if (g().rincomingmissiletargetkey != PRESS)
598  if (k == PRESS)
600 }
601 
603 {
604  if (g().neartargetkey != PRESS)
605  g().neartargetkey = k;
606  if (k == PRESS)
608 }
609 
611 {
612  if (g().subtargetkey != PRESS)
613  g().subtargetkey = k;
614  if (k == PRESS)
616 }
617 
619 {
620  if (g().threattargetkey != PRESS)
621  g().threattargetkey = k;
622  if (k == PRESS)
624 }
625 
627 {
628  if (g().targetukey != PRESS)
629  g().targetukey = k;
630  if (k == PRESS)
632 }
633 
635 {
636  if (g().targetskey != PRESS)
637  g().targetskey = k;
638  if (k == PRESS)
640 }
641 
643 {
644  if (g().rtargetkey != PRESS)
645  g().rtargetkey = k;
646  if (k == RESET)
647  g().rtargetkey = PRESS;
648  if (k == PRESS)
650 }
651 
653 {
654  if (g().rpicktargetkey != PRESS)
655  g().rpicktargetkey = k;
656  if (k == RESET)
657  g().rpicktargetkey = PRESS;
658  if (k == PRESS)
660 }
661 
663 {
664  if (g().rneartargetkey != PRESS)
665  g().rneartargetkey = k;
666  if (k == PRESS)
668 }
669 
671 {
672  if (g().rthreattargetkey != PRESS)
673  g().rthreattargetkey = k;
674  if (k == PRESS)
676 }
677 
679 {
680  if (g().rtargetukey != PRESS)
681  g().rtargetukey = k;
682  if (k == PRESS)
684 }
685 
687 {
688  if (g().rtargetskey != PRESS)
689  g().rtargetskey = k;
690  if (k == PRESS)
692 }
693 
695 {
696  if (g().nearesthostilekey != PRESS)
697  g().nearesthostilekey = k;
698  if (k == PRESS)
700 }
701 
703 {
704  if (g().nearestdangeroushostilekey != PRESS)
706  if (k == PRESS)
708 }
709 
711 {
712  if (g().nearestfriendlykey != PRESS)
713  g().nearestfriendlykey = k;
714  if (k == PRESS)
716 }
717 
719 {
720  if (g().nearestbasekey != PRESS)
721  g().nearestbasekey = k;
722  if (k == PRESS)
724 }
725 
727 {
728  if (g().nearestplanetkey != PRESS)
729  g().nearestplanetkey = k;
730  if (k == PRESS)
732 }
733 
735 {
736  if (g().nearestjumpkey != PRESS)
737  g().nearestjumpkey = k;
738  if (k == PRESS)
740 }
741 
743 {
744  if (g().togglepausekey != PRESS)
745  g().togglepausekey = k;
746 }
747 
748 #ifdef CAR_SIM
749 void FireKeyboard::BlinkLeftKey( const KBData&, KBSTATE k )
750 {
751  if (k == PRESS)
752  g().blinkleftkey = k;
753  if (k == RELEASE)
754  g().blinkleftkey = k;
755 }
756 
757 void FireKeyboard::BlinkRightKey( const KBData&, KBSTATE k )
758 {
759  if (k == PRESS)
760  g().blinkrightkey = k;
761  if (k == RELEASE)
762  g().blinkrightkey = k;
763 }
764 
765 void FireKeyboard::SirenKey( const KBData&, KBSTATE k )
766 {
767  if (k == PRESS)
768  g().sirenkey = k;
769  if (k == RELEASE)
770  g().sirenkey = k;
771 }
772 
773 void FireKeyboard::HeadlightKey( const KBData&, KBSTATE k )
774 {
775  if (k == PRESS)
776  g().headlightkey = k;
777  if (k == RELEASE)
778  g().headlightkey = k;
779 }
780 #endif
781 
782 extern unsigned int DoSpeech( Unit *un, Unit *player_un, const FSM::Node &convNode );
783 extern Unit * GetThreat( Unit *par, Unit *leader );
784 
785 void HelpOut( bool crit, std::string conv )
786 {
788  if (un) {
789  Unit *par = NULL;
790  DoSpeech( un, NULL, FSM::Node::MakeNode( conv, .1 ) );
792  ( par = (*ui) );
793  ++ui)
794  if ( (crit && UnitUtil::getFactionRelation( par, un ) > 0) || par->faction == un->faction ) {
795  Unit *threat = GetThreat( par, un );
796  CommunicationMessage c( par, un, NULL, 0 );
797  if (threat) {
798  par->Target( threat );
799  c.SetCurrentState( c.fsm->GetYesNode(), NULL, 0 );
800  } else {
801  c.SetCurrentState( c.fsm->GetNoNode(), NULL, 0 );
802  }
803  Order *o = un->getAIState();
804  if (o)
805  o->Communicate( c );
806  }
807  }
808 }
809 
811 {
812  if (k == PRESS) {
814  if (un) {
815  Unit *targ = un->Target();
816  if (targ) {
817  if (targ->faction == un->faction) {
818  Flightgroup *fg = targ->getFlightgroup();
819  if (fg) {
820  if ( fg != un->getFlightgroup() ) {
821  if ( un->getFlightgroup() )
822  un->getFlightgroup()->Decrement( un );
823  fg->nr_ships_left++;
824  fg->nr_ships++;
825  un->SetFg( fg, fg->nr_ships_left-1 );
826  }
827  }
828  }
829  }
830  }
831  }
832 }
833 
835 {
836  if (k == PRESS)
837  LeadMe( "k", "Attack my target!", true );
838 }
839 
841 {
842  if (k == PRESS)
843  LeadMe( "h", "Help me out!", false );
844 }
845 
847 {
848  if (k == PRESS)
849  HelpOut( false, "Help me out! I need critical assistance!" );
850 }
851 
853 {
854  if (k == PRESS)
855  HelpOut( true, "Help me out! Systems going critical!" );
856 }
857 
859 {
860  if (k == PRESS)
861  LeadMe( "l", "Get in front of me and prepare to be tractored in.", false );
862 }
863 
865 {
866  if (k == PRESS)
867  LeadMe( "p", "Defend my target!", true );
868 }
870 {
871  if (k == PRESS)
872  LeadMe( "t", "Dock at my target!", true );
873 }
874 
876 {
877  if (k == PRESS)
878  LeadMe( "s", "Hold Position!", true );
879 }
881 {
882  if (k == PRESS)
883  LeadMe( "f", "Form on my wing.", false );
884 }
885 
887 {
888  if (k == PRESS) {
889  LeadMe( "", "Break formation!", false ); //used to clear group target
890 
891  LeadMe( "b", "Pick a target and open fire!", false );
892  }
893 }
894 
896 {
897  if (g().turrettargetkey != PRESS)
898  g().turrettargetkey = k;
899  if (k == RESET)
900  g().turrettargetkey = PRESS;
901  if (k == PRESS)
903 }
904 
906 {
907  if (g().pickturrettargetkey != PRESS)
908  g().pickturrettargetkey = k;
909  if (k == RESET)
911  if (k == PRESS)
913 }
914 
916 {
917  if (g().nearturrettargetkey != PRESS)
918  g().nearturrettargetkey = k;
919  if (k == PRESS)
921 }
922 
924 {
925  if (g().threatturrettargetkey != PRESS)
926  g().threatturrettargetkey = k;
927  if (k == PRESS)
929 }
930 
932 {
933  if (g().rweapk != PRESS)
934  g().rweapk = k;
935 }
936 
938 {
939  if (g().rmisk != PRESS)
940  g().rmisk = k;
941 }
942 
944 {
945  if (g().weapk != PRESS)
946  g().weapk = k;
947 }
948 
950 {
951  if (g().misk != PRESS)
952  g().misk = k;
953 }
954 
956 {
957  if (k == PRESS)
958  g().missilekey = k;
959 }
960 
961 static bool isNotTurretOwner( Unit *parent, Unit *un )
962 {
963  return parent->isSubUnit() == false || un != parent->owner;
964 }
965 
966 bool TargMission( Unit *me, Unit *target )
967 {
968  for (unsigned int i = 0; i < active_missions.size(); ++i)
969  if (active_missions[i]->runtime.pymissions) {
970  vector< UnitContainer* > *relevant = &active_missions[i]->runtime.pymissions->relevant_units;
971  vector< UnitContainer* >::iterator ir = relevant->begin();
972  vector< UnitContainer* >::iterator ie = relevant->end();
973  for (; ir != ie; ++ir)
974  if (**ir == target) return true;
975  }
976  return false;
977 }
978 
979 bool TargAll( Unit *me, Unit *target )
980 {
981  static bool can_target_sun = XMLSupport::parse_bool( vs_config->getVariable( "graphics", "can_target_sun", "false" ) );
982  return ( me->InRange( target, true,
983  false )
984  || me->InRange( target, true, true ) ) && ( can_target_sun || !UnitUtil::isSun( target ) ) && isNotTurretOwner(
985  me,
986  target );
987 }
988 
989 bool TargSig( Unit *me, Unit *target )
990 {
991  static bool can_target_asteroid = XMLSupport::parse_bool( vs_config->getVariable( "graphics", "can_target_asteroid", "true" ) );
992 
993  bool ret =
994  me->InRange( target, false,
995  true ) && ( UnitUtil::isSignificant( target ) || TargMission( me, target ) ) && isNotTurretOwner(
996  me,
997  target );
998  if (can_target_asteroid == false)
999  if (target->isUnit() == ASTEROIDPTR || target->name.get().find( "Asteroid" ) == 0)
1000  ret = false;
1001  return ret;
1002 }
1003 
1004 extern Unit * getTopLevelOwner();
1005 
1006 bool TargUn( Unit *me, Unit *target )
1007 {
1008  static bool can_target_cargo = XMLSupport::parse_bool( vs_config->getVariable( "graphics", "can_target_cargo", "false" ) );
1010  return me->InRange( target, true,
1011  false )
1012  && (target->isUnit() == UNITPTR
1013  || target->isUnit() == ENHANCEMENTPTR) && getTopLevelOwner() != target->owner
1014  && (can_target_cargo || target->faction != up) && isNotTurretOwner( me, target );
1015 }
1016 
1017 bool TargMissile( Unit *me, Unit *target )
1018 {
1019  return me->InRange( target, true, false ) && (target->isUnit() == MISSILEPTR) && isNotTurretOwner( me, target );
1020 }
1021 
1022 bool TargIncomingMissile( Unit *me, Unit *target )
1023 {
1024  Unit *tt = target->Target();
1025  return TargMissile( me, target ) && ( tt == me || ( me->isSubUnit() && tt == _Universe->AccessCockpit()->GetSaveParent() ) );
1026 }
1027 
1028 bool TargFront( Unit *me, Unit *target )
1029 {
1030  if ( !TargAll( me, target ) )
1031  return false;
1032  QVector delta( target->Position()-me->Position() );
1033  double mm = delta.Magnitude();
1034  double tempmm = mm-target->rSize();
1035  if (tempmm > 0.0001)
1036  if ( (me->ToLocalCoordinates( Vector( delta.i, delta.j, delta.k ) ).k/tempmm) > .995 )
1037  return true;
1038  return false;
1039 }
1040 
1041 bool TargThreat( Unit *me, Unit *target )
1042 {
1043  if ( !TargAll( me, target ) )
1044  return false;
1045  if (target->isUnit() == MISSILEPTR)
1046  return false;
1047  if (target->Target() == me)
1048  return true;
1049  if (me->Threat() == target)
1050  return true;
1051  return false;
1052 }
1053 
1054 bool TargNear( Unit *me, Unit *target )
1055 {
1056  static bool can_target_sun = XMLSupport::parse_bool( vs_config->getVariable( "graphics", "can_target_sun", "false" ) );
1057  return (me->getRelation( target ) < 0
1058  || TargThreat( me,
1059  target )
1060  || target->getRelation( me ) < 0)
1061  && TargAll( me,
1062  target ) && target->isUnit() != MISSILEPTR
1063  && ( can_target_sun || !UnitUtil::isSun( target ) ) && isNotTurretOwner( me,
1064  target );
1065 }
1066 
1067 //Target the nearest unit of a specified type
1068 //Possible types are:
1069 //0 = hostile
1070 //1 = hostile targetting me
1071 //2 = friendly
1072 //3 = base
1073 //4 = planet
1074 //5 = jump point
1075 bool getNearestTargetUnit( Unit *me, int iType )
1076 {
1077  QVector pos( me->Position() );
1078  Unit *un = NULL;
1079  Unit *targ = NULL;
1080  double minrange = FLT_MAX;
1081  for (un_iter i = _Universe->activeStarSystem()->getUnitList().createIterator(); ( un = (*i) ); ++i) {
1082  if (un == me)
1083  continue;
1084  if (un->hull < 0)
1085  continue;
1086  if ( !( me->InRange( un, true, false ) )
1087  || !( me->InRange( un, true, true ) ) )
1088  continue;
1089  if ( (iType == 0)
1090  && ( (un->isUnit() != UNITPTR)
1091  || !me->isEnemy( un ) ) )
1092  continue;
1093  if ( (iType == 1)
1094  && ( (un->isUnit() != UNITPTR)
1095  || ( !me->isEnemy( un )
1096  && (un->Target() != me) ) ) )
1097  continue;
1098  if ( (iType == 2)
1099  && ( (un->isUnit() != UNITPTR)
1100  || me->isEnemy( un )
1101  || (UnitUtil::getFlightgroupName( un ) == "Base") ) )
1102  continue;
1103  if ( (iType == 3)
1104  && (UnitUtil::getFlightgroupName( un ) != "Base") )
1105  continue;
1106  if ( (iType == 4)
1107  && ( ( !un->isPlanet() )
1108  || ( un->isJumppoint() ) ) )
1109  continue;
1110  if ( (iType == 5)
1111  && ( !un->isJumppoint() ) )
1112  continue;
1113  double temp = (un->Position()-pos).Magnitude();
1114  if (targ == NULL) {
1115  targ = un;
1116  minrange = temp;
1117  } else if (temp < minrange) {
1118  targ = un;
1119  minrange = temp;
1120  }
1121  }
1122  if (targ == NULL)
1123  return false;
1124  me->Target( targ );
1125  if (Network != NULL) {
1126  int player = _Universe->whichPlayerStarship( me );
1127  if (player >= 0)
1128  Network[player].targetRequest( targ );
1129  }
1130  return true;
1131 }
1132 
1133 bool ChooseTargets( Unit *me, bool (*typeofunit)( Unit*, Unit* ), bool reverse )
1134 {
1136  vector< Unit* > vec;
1137  Unit *target;
1138  for (un_iter iter = drawlist.createIterator(); (target=*iter)!=NULL; ++iter)
1139  vec.push_back( target );
1140  if (vec.size() == 0)
1141  return false;
1142  if (reverse)
1143  std::reverse( vec.begin(), vec.end() );
1144  std::vector< Unit* >::const_iterator veciter = std::find( vec.begin(), vec.end(), me->Target() );
1145  if ( veciter != vec.end() )
1146  ++veciter;
1147  int cur = 0;
1148  while (1) {
1149  while ( veciter != vec.end() ) {
1150  if ( ( (*veciter) != me ) && ( (*veciter)->GetHull() >= 0 ) && typeofunit( me, (*veciter) ) ) {
1151  me->Target( *veciter );
1152  if (Network != NULL) {
1153  int player = _Universe->whichPlayerStarship( me );
1154  if (player >= 0)
1155  Network[player].targetRequest( *veciter );
1156  }
1157  if ( (*veciter) != NULL ) {
1158  if (reverse) {
1159  static soundContainer foosound;
1160  if (foosound.sound < 0) {
1161  static string str = vs_config->getVariable( "cockpitaudio", "target", "vdu_b" );
1162  foosound.loadsound( str );
1163  }
1164  foosound.playsound();
1165  } else {
1166  static soundContainer foobersound;
1167  if (foobersound.sound < 0) {
1168  static string str = vs_config->getVariable( "cockpitaudio", "target_reverse", "vdu_a" );
1169  foobersound.loadsound( str );
1170  }
1171  foobersound.playsound();
1172  }
1173  }
1174  return true;
1175  }
1176  ++veciter;
1177  }
1178  ++cur;
1179  if (cur >= 2)
1180  break;
1181  veciter = vec.begin();
1182  }
1183  return true;
1184 }
1185 
1187 {
1188  Unit *parent = UnitUtil::owner( me->Target() );
1189  if (!parent)
1190  return;
1191  un_iter uniter = parent->getSubUnits();
1192  if ( parent == me->Target() ) {
1193  if ( !(*uniter) )
1194  return;
1195  me->Target( *uniter );
1196  return;
1197  }
1198  Unit *tUnit;
1199  for ( ; (tUnit=*uniter)!=NULL; ++uniter)
1200  if ( tUnit == me->Target() ) {
1201  ++uniter;
1202  tUnit = *uniter;
1203  break;
1204  }
1205  if (tUnit)
1206  me->Target( tUnit );
1207  else
1208  me->Target( parent );
1209 }
1210 
1212 {
1213 #ifdef ORDERDEBUG
1214  VSFileSystem::vs_fprintf( stderr, "fkb%x", this );
1215  fflush( stderr );
1216 #endif
1217 }
1218 
1219 bool FireKeyboard::ShouldFire( Unit *targ )
1220 {
1221  float dist = FLT_MAX;
1222  float mrange;
1223  if (gunspeed == .0001)
1224  parent->getAverageGunSpeed( gunspeed, gunrange, mrange );
1225  float angle = parent->cosAngleTo( targ, dist, gunspeed, gunrange );
1226  targ->Threaten( parent, angle/(dist < .8 ? .8 : dist) );
1227  if ( targ == parent->Target() )
1228  distance = dist;
1229  return dist < .8 && angle > 1;
1230 }
1231 
1232 static bool UnDockNow( Unit *me, Unit *targ )
1233 {
1234  bool ret = false;
1235  Unit *un;
1237  (un = *i) != NULL;
1238  ++i)
1239  if ( un->isDocked( me ) )
1240  if ( me->UnDock( un ) )
1241  ret = true;
1242  return ret;
1243 }
1244 
1245 void Enslave( Unit*, bool );
1246 
1247 void abletodock( int dock )
1248 {
1249  static bool play_anim = XMLSupport::parse_bool( vs_config->getVariable( "graphics", "docking_comm_anim", "false" ) );
1250  switch (dock)
1251  {
1252  case 5:
1253  {
1254  static soundContainer reqsound;
1255  if (reqsound.sound == -2) {
1256  static string str = vs_config->getVariable( "cockpitaudio", "undocking_complete", "undocking_complete" );
1257  reqsound.loadsound( str );
1258  }
1259  reqsound.playsound();
1260  break;
1261  }
1262  case 4:
1263  {
1264  static soundContainer reqsound;
1265  if (reqsound.sound == -2) {
1266  static string str = vs_config->getVariable( "cockpitaudio", "undocking_failed", "undocking_failed" );
1267  reqsound.loadsound( str );
1268  }
1269  reqsound.playsound();
1270  break;
1271  }
1272  case 3:
1273  {
1274  static soundContainer reqsound;
1275  static string otherstr = vs_config->getVariable( "audio", "automatic_docking_zone", "automatic_landing_zone.wav" );
1276  if (otherstr != "" && rand() < RAND_MAX/2) {
1277  static int s = AUDCreateSoundWAV( otherstr, false );
1278  AUDPlay( s, QVector( 0, 0, 0 ), Vector( 0, 0, 0 ), 1 );
1279  } else {
1280  if (reqsound.sound == -2) {
1281  static string str = vs_config->getVariable( "cockpitaudio", "docking_complete", "docking_complete" );
1282  reqsound.loadsound( str );
1283  }
1284  reqsound.playsound();
1285  }
1286  break;
1287  }
1288  case 2:
1289  {
1290  static soundContainer reqsound;
1291  if (reqsound.sound == -2) {
1292  static string str = vs_config->getVariable( "cockpitaudio", "docking_failed", "docking_failed" );
1293  reqsound.loadsound( str );
1294  }
1295  reqsound.playsound();
1296  break;
1297  }
1298  case 1:
1299  {
1300  static soundContainer reqsound;
1301  if (reqsound.sound == -2) {
1302  static string str = vs_config->getVariable( "cockpitaudio", "docking_granted", "request_granted" );
1303  reqsound.loadsound( str );
1304  }
1305  reqsound.playsound();
1306  break;
1307  }
1308  case 0:
1309  {
1310  static soundContainer reqsound;
1311  if (reqsound.sound == -2) {
1312  static string str = vs_config->getVariable( "cockpitaudio", "docking_denied", "request_denied" );
1313  reqsound.loadsound( str );
1314  }
1315  reqsound.playsound();
1316  break;
1317  }
1318  }
1319 }
1320 
1321 static bool SuperDock( Unit *parent, Unit *target )
1322 {
1323  if ( UnitUtil::isCloseEnoughToDock( parent, target ) ) {
1324  if ( UnitUtil::isDockableUnit( target ) ) {
1325  for (unsigned int i = 0; i < target->GetImageInformation().dockingports.size(); ++i)
1326  if (!target->GetImageInformation().dockingports[i].IsOccupied())
1327  return parent->ForceDock( target, i ) != 0;
1328  }
1329  }
1330  return false;
1331 }
1332 
1333 static bool TryDock( Unit *parent, Unit *targ, unsigned char playa, int severity )
1334 {
1335  static float min_docking_relationship =
1336  XMLSupport::parse_float( vs_config->getVariable( "AI", "min_docking_relationship", "-.002" ) );
1337  static bool can_dock_to_enemy_base =
1338  XMLSupport::parse_bool( vs_config->getVariable( "AI", "can_dock_to_enemy_base", "true" ) );
1339  static bool nojumpinSPEC = XMLSupport::parse_bool( vs_config->getVariable( "physics", "noSPECJUMP", "true" ) );
1340  bool SPEC_interference = targ && parent && nojumpinSPEC
1341  && (targ->graphicOptions.InWarp || parent->graphicOptions.InWarp);
1342  unsigned char gender = 0;
1343  vector< Animation* > *anim = NULL;
1344  if (SPEC_interference)
1345  //FIXME js_NUDGE -- need some indicator of non-interaction because one or both objects are in SPEC.
1346  return false;
1347  anim = targ->pilot->getCommFaces( gender );
1348 
1349  bool isDone = false;
1350  if ( targ->getRelation( parent ) >= min_docking_relationship
1351  || (can_dock_to_enemy_base && UnitUtil::getFlightgroupName( targ ) == "Base") ) {
1352  bool hasDock = severity == 0 ? parent->Dock( targ ) : SuperDock( parent, targ );
1353 
1354  CommunicationMessage c( targ, parent, anim, gender );
1355  if (hasDock) {
1356  isDone = true;
1357  c.SetCurrentState( c.fsm->GetDockNode(), anim, gender );
1358  abletodock( 3 );
1359  if ( parent->getAIState() ) parent->getAIState()->Communicate( c );
1360  parent->UpgradeInterface( targ );
1361  } else if ( UnDockNow( parent, targ ) ) {
1362  isDone = true;
1363  c.SetCurrentState( c.fsm->GetUnDockNode(), anim, gender );
1364  if ( parent->getAIState() ) parent->getAIState()->Communicate( c );
1365  abletodock( 5 );
1366  }
1367  } else if (parent->GetComputerData().target == targ) {
1368  CommunicationMessage c( targ, parent, anim, gender );
1369  c.SetCurrentState( c.fsm->GetNoNode(), anim, gender );
1370  if ( parent->getAIState() ) parent->getAIState()->Communicate( c );
1371  }
1372  return isDone;
1373 }
1374 
1375 static bool ExecuteRequestClearenceKey( Unit *parent, Unit *endt )
1376 {
1377  bool tmp = endt->RequestClearance( parent );
1378  if (endt->getRelation( parent ) >= 0) {
1379  if (endt->graphicOptions.InWarp)
1380  endt->graphicOptions.WarpRamping = 1;
1381  endt->graphicOptions.InWarp = 0;
1382  static float clearencetime = ( XMLSupport::parse_float( vs_config->getVariable( "general", "dockingtime", "20" ) ) );
1383  endt->EnqueueAIFirst( new Orders::ExecuteFor( new Orders::MatchVelocity( Vector( 0, 0, 0 ),
1384  Vector( 0, 0, 0 ),
1385  true,
1386  false,
1387  true ), clearencetime ) );
1388  }
1389  return tmp;
1390 }
1391 
1392 static void DoDockingOps( Unit *parent, Unit *targ, unsigned char playa, unsigned char gender )
1393 {
1394  static int maxseverity = XMLSupport::parse_bool( vs_config->getVariable( "AI", "dock_to_area", "false" ) ) ? 2 : 1;
1395  Unit *endt = targ;
1396  bool wasdock = vectorOfKeyboardInput[playa].doc;
1397  if (vectorOfKeyboardInput[playa].doc) {
1398  bool isDone = false;
1399  if (targ) {
1400  for (int severity = 0; severity < maxseverity; ++severity) {
1401  targ->RequestClearance( parent );
1402  if ( ( isDone = TryDock( parent, targ, playa, severity ) ) != false ) {
1403  parent->EndRequestClearance( targ );
1404  break;
1405  } else {
1406  parent->EndRequestClearance( targ );
1407  }
1408  }
1409  }
1410  if (!isDone) {
1411  for (int severity = 0; severity < maxseverity && !isDone; ++severity)
1413  (targ = *u) != NULL && !isDone;
1414  ++u)
1415  //Let's make sure potentials are actually in range, and have
1416  //docking ports before we try to dock with them.
1417  if ( (targ != parent)
1418  && ( UnitUtil::isDockableUnit( targ ) )
1419  && ( UnitUtil::isCloseEnoughToDock( parent, targ ) ) ) {
1420  targ->RequestClearance( parent );
1421  if ( TryDock( parent, targ, playa, severity ) ) {
1422  parent->Target( targ );
1423  isDone = true;
1424  parent->EndRequestClearance( targ );
1425  break;
1426  } else {
1427  parent->EndRequestClearance( targ );
1428  }
1429  }
1430  }
1431  if (!isDone) {
1432  if (endt)
1433  ExecuteRequestClearenceKey( parent, endt );
1434  abletodock( 0 );
1435  }
1436  vectorOfKeyboardInput[playa].doc = false;
1437  }
1438  if (vectorOfKeyboardInput[playa].req && endt != NULL) {
1439  bool request = ExecuteRequestClearenceKey( parent, endt );
1440  if (!request) {
1441  mission->msgcenter->add( "game",
1442  "all",
1443  "[Computer] Cannot dock with insubstantidisabal object, target another object and retry." );
1444  abletodock( 0 );
1445  return;
1446  } else if (!wasdock) {
1447  abletodock( 1 );
1448  }
1449  vectorOfKeyboardInput[playa].req = false;
1450  }
1451  if (vectorOfKeyboardInput[playa].und && endt != NULL) {
1452  CommunicationMessage c( endt, parent, NULL, 0 );
1453  if ( UnDockNow( parent, endt ) ) {
1454  c.SetCurrentState( c.fsm->GetUnDockNode(), NULL, 0 );
1455  abletodock( 5 );
1456  } else {
1457  c.SetCurrentState( c.fsm->GetFailDockNode(), NULL, 0 );
1458  abletodock( 4 );
1459  }
1460  parent->getAIState()->Communicate( c );
1461  vectorOfKeyboardInput[playa].und = 0;
1462  }
1463 }
1464 
1465 using std::list;
1466 unsigned int FireKeyboard::DoSpeechAndAni( Unit *un, Unit *parent, class CommunicationMessage &c )
1467 {
1468  this->AdjustRelationTo( un, c.getCurrentState()->messagedelta );
1469  unsigned int retval = DoSpeech( un, parent, *c.getCurrentState() );
1470  if ( parent == _Universe->AccessCockpit()->GetParent() )
1472  this->refresh_target = true;
1473  return retval;
1474 }
1475 
1476 static void MyFunction()
1477 {
1478  //quit it--he's dead all ready
1479  static string comm_static = vs_config->getVariable( "graphics", "comm_static", "static.ani" );
1480  //dead dead dead dead
1481  static Animation Statuc( comm_static.c_str() );
1482  //yep really dead
1483  _Universe->AccessCockpit()->SetCommAnimation( &Statuc, NULL );
1484 }
1485 
1487 {
1488  Unit *un = c.sender.GetUnit();
1489  unsigned int whichsound = 0;
1490  bool foundValidMessage = false;
1491  if ( _Universe->AccessCockpit()->CheckCommAnimation( un ) )
1492  return; //wait till later
1493 
1494  bool reallydospeech = false;
1495  if (un && un->GetHull() > 0) {
1496  reallydospeech = true;
1497  for (list< CommunicationMessage >::iterator i = resp.begin(); i != resp.end(); i++)
1498  if ( (*i).sender.GetUnit() == un )
1499  if ( ( i = resp.erase( i ) ) == resp.end() )
1500  break;
1501  resp.push_back( c );
1502  if (!foundValidMessage)
1503  whichsound = DoSpeechAndAni( un, parent, c );
1504  } else if (0) {
1505  //none of this happens
1506  whichsound = DoSpeech( NULL, NULL, *c.getCurrentState() );
1507  //this is when a unit is already dead
1508  if ( parent == _Universe->AccessCockpit()->GetParent() )
1509  MyFunction();
1510  //mmhmm! Gcc-4.1 hack -- otherwise linker failure
1511  }
1512  int sound = c.getCurrentState()->GetSound( c.sex, whichsound );
1513  if ( reallydospeech && !AUDIsPlaying( sound ) )
1514  AUDPlay( sound, QVector( 0, 0, 0 ), Vector( 0, 0, 0 ), 1 );
1515 }
1516 using std::list;
1517 
1518 static CommunicationMessage * GetTargetMessageQueue( Unit *targ, std::list< CommunicationMessage > &messagequeue )
1519 {
1520  CommunicationMessage *mymsg = NULL;
1521  for (list< CommunicationMessage >::iterator i = messagequeue.begin(); i != messagequeue.end(); i++)
1522  if ( (*i).sender.GetUnit() == targ ) {
1523  mymsg = &(*i);
1524  break;
1525  }
1526  return mymsg;
1527 }
1528 extern std::set< Unit* >arrested_list_do_not_dereference;
1529 
1530 void Arrested( Unit *parent )
1531 {
1533  int own = FactionUtil::GetFactionIndex( fac );
1534  static string po = vs_config->getVariable( "galaxy", "police_faction", "homeland-security" );
1535  int police = FactionUtil::GetFactionIndex( po );
1536  int police2 = FactionUtil::GetFactionIndex( po+"_"+fac );
1537  float ownrel = UnitUtil::getRelationFromFaction( parent, own );
1538  bool attack = ownrel < 0;
1539  if (!attack) {
1540  Unit *contra = FactionUtil::GetContraband( own );
1541  if (contra) {
1542  for (unsigned int i = 0; (!attack) && i < parent->numCargo(); ++i) {
1543  Cargo *ci = &parent->GetCargo( i );
1544  for (unsigned int j = 0; j < contra->numCargo(); ++j) {
1545  Cargo *cj = &contra->GetCargo( j );
1546  if (ci->content == cj->content) {
1547  attack = true;
1548  break;
1549  }
1550  }
1551  }
1552  }
1553  }
1554  if (!attack) {
1555  Unit *un;
1557  (un = *i) != NULL;
1558  ++i)
1559  if (un->faction == own || un->faction == police || un->faction == police2) {
1560  if (un->Target() == parent || un->getRelation( parent ) < 0) {
1561  int parentCp = _Universe->whichPlayerStarship( parent );
1562  if (parentCp != -1)
1563  UniverseUtil::adjustRelationModifier( parentCp, fac, -ownrel-.1 );
1564  attack = true;
1565  break;
1566  }
1567  }
1568  }
1569  if (attack) {
1570  static std::string prison_system = vs_config->getVariable( "galaxy", "PrisonSystem", "Sol/Nu_Pheonix" );
1571  std::string psys = prison_system+"_"+fac;
1572  if (UnitUtil::getUnitSystemFile( parent ) != psys) {
1573  UnitUtil::JumpTo( parent, psys );
1575  0,
1576  "game",
1577  "all",
1578  parent->name
1579  +", you are under arrest! You will be taken to the prison system and will be tried for your crimes." );
1580  } else {
1581  Unit *un;
1582  Unit *owner = NULL;
1583  Unit *base = NULL;
1584  for (un_iter i = _Universe->activeStarSystem()->getUnitList().createIterator(); (un = *i) != NULL; ++i) {
1585  if (owner == NULL && un->getFlightgroup() && un->faction == own)
1586  if ( UnitUtil::isSignificant( un ) && ( !un->isJumppoint() ) )
1587  owner = un;
1588  if ( UnitUtil::isSignificant( un ) && ( !un->isJumppoint() ) )
1589  base = un;
1590  }
1591  if (owner == NULL)
1592  owner = base;
1593  if (owner) {
1594  Order *tmp = parent->aistate;
1595  parent->aistate = NULL;
1596  parent->PrimeOrders( new Orders::DockingOps( owner, tmp, true, true ) );
1597  arrested_list_do_not_dereference.insert( parent );
1598  for (int i = parent->numCargo()-1; i >= 0; --i)
1599  parent->RemoveCargo( i, parent->GetCargo( (unsigned int) i ).quantity, true );
1601  0,
1602  "game",
1603  "all",
1604  parent->name
1605  +
1606  ", your cargo has been confiscated and scanned. Here your ship will be kept until you complete your reintegration into society through our reprogramming pod(tm) system." );
1607  int whichCp = _Universe->whichPlayerStarship( parent );
1609  }
1610  }
1611  }
1612 }
1613 
1614 extern void PowerDownShield( Shield *shield, float howmuch );
1615 
1616 static void ForceChangeTarget( Unit *parent )
1617 {
1618  Unit *curtarg = parent->Target();
1619  ChooseTargets( parent, TargUn, false );
1620  static bool force_change_only_unit =
1621  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "target_null_if_no_unit", "false" ) );
1622  if (parent->Target() == curtarg) {
1623  if (force_change_only_unit) {
1624  parent->Target( NULL );
1625  } else {
1626  ChooseTargets( parent, TargNear, false );
1627  if (parent->Target() == curtarg)
1628  ChooseTargets( parent, TargAll, false );
1629  }
1630  }
1631 }
1632 
1633 int SelectDockPort( Unit *utdw, Unit *parent );
1634 
1636 {
1637  this->Order::SetParent( parent1 );
1638  static bool allow_special_with_weapons =
1639  XMLSupport::parse_bool( vs_config->getVariable( "physics", "special_and_normal_gun_combo", "true" ) );
1640  if (!allow_special_with_weapons) {
1641  parent->ToggleWeapon( false, true /*reverse*/ );
1642  parent->ToggleWeapon( false, false /*reverse*/ );
1643  }
1644 }
1645 
1647 {
1649  vectorOfKeyboardInput.push_back( FIREKEYBOARDTYPE() );
1651  Unit *targ = parent->Target();
1653  if (SERVER || Network == NULL) {
1654  if (targ) {
1655  double mm = 0.0;
1656  ShouldFire( targ );
1657  if (targ->GetHull() < 0) {
1658  parent->Target( NULL );
1660  refresh_target = true;
1661  } else if ( false == parent->InRange( targ, mm, true, true, true ) && !parent->TargetLocked() ) {
1662  ChooseTargets( parent, TargUn, false ); //only go for other active units in cone
1663  if (parent->Target() == NULL)
1664  parent->Target( targ );
1665  }
1666  } else {
1668  refresh_target = true;
1669  }
1670  }
1671  if (f().shieldpowerstate != 1) {
1672  Shield *shield = &parent->shield;
1673  PowerDownShield( shield, f().shieldpowerstate );
1674  }
1675  if (f().firekey == PRESS || f().jfirekey == PRESS || j().firekey == DOWN || j().jfirekey == DOWN) {
1676  if ( !_Universe->AccessCockpit()->CanDrawNavSystem() ) {
1677  static bool allow_special_with_weapons =
1678  XMLSupport::parse_bool( vs_config->getVariable( "physics", "special_and_normal_gun_combo", "true" ) );
1679  if (!allow_special_with_weapons) {
1680  bool special = false;
1681  bool normal = false;
1682  int nm = parent->GetNumMounts();
1683  int i;
1684  for (i = 0; i < nm; ++i)
1685  if (parent->mounts[i].status == Mount::ACTIVE) {
1686  special = special || (parent->mounts[i].type->size&weapon_info::SPECIAL) != 0;
1687  normal = normal
1688  || ( parent->mounts[i].type->size
1690  |weapon_info::CAPSHIPHEAVY) ) != 0;
1691  }
1692  for (i = 0; i < nm; ++i)
1693  if (special && normal) {
1694  if (parent->mounts[i].status == Mount::ACTIVE)
1695  if ( (parent->mounts[i].type->size&weapon_info::SPECIAL) != 0 )
1696  parent->mounts[i].status = Mount::INACTIVE;
1697  }
1698  }
1700  }
1701  }
1702  if (f().missilekey == PRESS || j().jmissilekey == PRESS) {
1705  if (f().missilekey == PRESS)
1706  f().missilekey = DOWN;
1707  if (j().jmissilekey == PRESS)
1708  j().jmissilekey = DOWN;
1709  } else if (f().firekey == RELEASE || j().jfirekey == RELEASE) {
1710  f().firekey = UP;
1711  j().jfirekey = UP;
1712  parent->UnFire();
1713  }
1714  if (f().cloakkey == PRESS) {
1715  f().cloakkey = DOWN;
1716  parent->Cloak( cloaktoggle );
1717  cloaktoggle = !cloaktoggle;
1718  }
1719  if (f().lockkey == PRESS) {
1720  f().lockkey = DOWN;
1722  }
1723  if (f().ECMkey == PRESS) {
1724  f().ECMkey = DOWN;
1726  }
1727 #ifdef CAR_SIM
1728  int origecm = UnitUtil::getECM( parent );
1729  if (origecm >= CAR::ON_NO_BLINKEN)
1730  origecm = CAR::FORWARD_BLINKEN;
1731  if (origecm < 0)
1732  origecm = 0;
1733  if (f().blinkleftkey == PRESS) {
1734  f().blinkleftkey = DOWN;
1735  if ( (origecm&CAR::LEFT_BLINKEN) )
1736  UnitUtil::setECM( parent, ( origecm&(~CAR::LEFT_BLINKEN) ) );
1737  else
1738  UnitUtil::setECM( parent, origecm|CAR::LEFT_BLINKEN );
1739  }
1740  if (f().blinkrightkey == PRESS) {
1741  f().blinkrightkey = DOWN;
1742  if ( (origecm&CAR::RIGHT_BLINKEN) )
1743  UnitUtil::setECM( parent, ( origecm&(~CAR::RIGHT_BLINKEN) ) );
1744  else
1745  UnitUtil::setECM( parent, origecm|CAR::RIGHT_BLINKEN );
1746  }
1747  if (f().sirenkey == PRESS) {
1748  f().sirenkey = DOWN;
1749  if ( (origecm&CAR::SIREN_BLINKEN) )
1750  UnitUtil::setECM( parent, ( origecm&(~CAR::SIREN_BLINKEN) ) );
1751  else
1752  UnitUtil::setECM( parent, origecm|CAR::SIREN_BLINKEN );
1753  }
1754  if (f().headlightkey == PRESS) {
1755  f().headlightkey = DOWN;
1756  if ( (origecm&CAR::FORWARD_BLINKEN) )
1757  UnitUtil::setECM( parent, ( origecm&(~CAR::FORWARD_BLINKEN) ) );
1758  else
1759  UnitUtil::setECM( parent, origecm|CAR::FORWARD_BLINKEN );
1760  }
1761 #endif
1762  if (f().targetkey == PRESS || j().jtargetkey == PRESS) {
1763  f().targetkey = DOWN;
1764  j().jtargetkey = DOWN;
1765  ChooseTargets( parent, TargAll, false );
1766  refresh_target = true;
1767  }
1768  if (f().rtargetkey == PRESS) {
1769  f().rtargetkey = DOWN;
1770  ChooseTargets( parent, TargAll, true );
1771  refresh_target = true;
1772  }
1773  if (f().missiontargetkey == PRESS) {
1774  f().missiontargetkey = DOWN;
1775  ChooseTargets( parent, TargMission, false );
1776  refresh_target = true;
1777  }
1778  if (f().rmissiontargetkey == PRESS) {
1779  f().rmissiontargetkey = DOWN;
1780  ChooseTargets( parent, TargMission, true );
1781  refresh_target = true;
1782  }
1783  if (f().targetskey == PRESS) {
1784  f().targetskey = DOWN;
1785  ChooseTargets( parent, TargSig, false );
1786  refresh_target = true;
1787  parent->LockTarget( true );
1788  }
1789  if (f().targetukey == PRESS) {
1790  f().targetukey = DOWN;
1791  static bool smart_targetting =
1792  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "smart_targetting_key", "true" ) );
1793  Unit *tmp = parent->Target();
1794  bool sysobj = false;
1795  if (tmp)
1796  if ( tmp->owner == getTopLevelOwner() )
1797  sysobj = true;
1798  ChooseTargets( parent, TargUn, false );
1799  if ( (Network == NULL || parent->Target() == NULL) && tmp == parent->Target() && sysobj && smart_targetting ) {
1800  ChooseTargets( parent, TargSig, false );
1801  if ( tmp == parent->Target() )
1802  ChooseTargets( parent, TargAll, false );
1803  }
1804  refresh_target = true;
1805  }
1806  if (f().picktargetkey == PRESS) {
1807  f().picktargetkey = DOWN;
1808  ChooseTargets( parent, TargFront, false );
1809  refresh_target = true;
1810  }
1811  if (f().neartargetkey == PRESS) {
1812  ChooseTargets( parent, TargNear, false );
1813  f().neartargetkey = DOWN;
1814  refresh_target = true;
1815  }
1816  if (f().missiletargetkey == PRESS) {
1817  ChooseTargets( parent, TargMissile, false );
1818  f().missiletargetkey = DOWN;
1819  refresh_target = true;
1820  }
1821  if (f().incomingmissiletargetkey == PRESS) {
1824  refresh_target = true;
1825  }
1826  if (f().rmissiletargetkey == PRESS) {
1827  ChooseTargets( parent, TargMissile, true );
1828  f().rmissiletargetkey = DOWN;
1829  refresh_target = true;
1830  }
1831  if (f().rincomingmissiletargetkey == PRESS) {
1834  refresh_target = true;
1835  }
1836  if (f().threattargetkey == PRESS) {
1837  ChooseTargets( parent, TargThreat, false );
1838  f().threattargetkey = DOWN;
1839  refresh_target = true;
1840  }
1841  if (f().subtargetkey == PRESS) {
1843  f().subtargetkey = DOWN;
1844  refresh_target = true;
1845  }
1846  if (f().rpicktargetkey == PRESS) {
1847  f().rpicktargetkey = DOWN;
1848  ChooseTargets( parent, TargFront, true );
1849  refresh_target = true;
1850  }
1851  if (f().rneartargetkey == PRESS) {
1852  ChooseTargets( parent, TargNear, true );
1853  f().rneartargetkey = DOWN;
1854  refresh_target = true;
1855  }
1856  if (f().rthreattargetkey == PRESS) {
1857  ChooseTargets( parent, TargThreat, true );
1858  f().rthreattargetkey = DOWN;
1859  refresh_target = true;
1860  }
1861  if (f().rtargetskey == PRESS) {
1862  f().rtargetskey = DOWN;
1863  ChooseTargets( parent, TargSig, true );
1864  refresh_target = true;
1865  parent->LockTarget( true );
1866  }
1867  if (f().rtargetukey == PRESS) {
1868  f().rtargetukey = DOWN;
1869  static bool smart_targetting =
1870  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "smart_targetting_key", "true" ) );
1871  Unit *tmp = parent->Target();
1872  bool sysobj = false;
1873  if (tmp)
1874  if ( tmp->owner == getTopLevelOwner() )
1875  sysobj = true;
1876  ChooseTargets( parent, TargUn, true );
1877  if (tmp == parent->Target() && sysobj && smart_targetting) {
1878  ChooseTargets( parent, TargFront, true );
1879  if ( tmp == parent->Target() )
1880  ChooseTargets( parent, TargAll, true );
1881  }
1882  refresh_target = true;
1883  }
1884  if (f().turretaikey == PRESS) {
1885  parent->SetTurretAI();
1887  f().turretaikey = DOWN;
1888  }
1889  static bool noturretai = XMLSupport::parse_bool( vs_config->getVariable( "AI", "no_turret_ai", "false" ) );
1890  static int taicounter = 0;
1891  if ( f().turretoffkey == PRESS || (noturretai && taicounter++%128 == 0) ) {
1893  f().turretoffkey = DOWN;
1894  }
1895  if (f().turretfaw == PRESS) {
1896  parent->TurretFAW();
1897  f().turretfaw = DOWN;
1898  }
1899  if (f().turretaikey == RELEASE)
1900  f().turretaikey = UP;
1901  if (f().turrettargetkey == PRESS) {
1902  f().turrettargetkey = DOWN;
1904  refresh_target = true;
1905  }
1906  if (f().pickturrettargetkey == PRESS) {
1909  refresh_target = true;
1910  }
1911  if (f().nearturrettargetkey == PRESS) {
1914  refresh_target = true;
1915  }
1916  if (f().threatturrettargetkey == PRESS) {
1919  refresh_target = true;
1920  }
1921  //Added for nearest unit targeting -ch
1922  if (f().nearesthostilekey == PRESS) {
1924  f().nearesthostilekey = DOWN;
1925  refresh_target = true;
1926  }
1927  if (f().nearestdangeroushostilekey == PRESS) {
1930  refresh_target = true;
1931  }
1932  if (f().nearestfriendlykey == PRESS) {
1935  refresh_target = true;
1936  }
1937  if (f().nearestbasekey == PRESS) {
1939  f().nearestbasekey = DOWN;
1940  refresh_target = true;
1941  }
1942  if (f().nearestplanetkey == PRESS) {
1944  f().nearestplanetkey = DOWN;
1945  refresh_target = true;
1946  }
1947  if (f().nearestjumpkey == PRESS) {
1949  f().nearestjumpkey = DOWN;
1950  refresh_target = true;
1951  }
1952  if (f().togglepausekey == PRESS) {
1953  f().togglepausekey = DOWN;
1954  if (toggle_pause())
1955  {
1957  }
1958  else
1959  {
1961  }
1962  }
1963  if (f().weapk == PRESS || f().rweapk == PRESS) {
1964  bool forward;
1965  if (f().weapk == PRESS) {
1966  f().weapk = DOWN;
1967  forward = true;
1968  }
1969  if (f().rweapk == PRESS) {
1970  f().rweapk = DOWN;
1971  forward = false;
1972  }
1973  parent->UnFire();
1974  parent->ToggleWeapon( false, forward );
1975  static soundContainer weapsound;
1976  if (weapsound.sound < 0) {
1977  static string str = vs_config->getVariable( "cockpitaudio", "weapon_switch", "vdu_d" );
1978  weapsound.loadsound( str );
1979  }
1980  weapsound.playsound();
1981  }
1982  if (f().toggleanimation == PRESS) {
1983  f().toggleanimation = DOWN;
1985  }
1986  if (f().toggleglow == PRESS) {
1987  f().toggleglow = DOWN;
1988  static bool isvis = true;
1989  isvis = !isvis;
1990  parent->SetGlowVisible( isvis );
1991  }
1992  if (f().togglewarpdrive == PRESS) {
1993  f().togglewarpdrive = DOWN;
1996  }
1997  if (f().toggleautotracking == PRESS) {
2000  }
2001  if (f().misk == PRESS || f().rmisk == PRESS) {
2002  bool forward;
2003  if (f().misk == PRESS) {
2004  f().misk = DOWN;
2005  forward = true;
2006  }
2007  if (f().rmisk == PRESS) {
2008  f().rmisk = DOWN;
2009  forward = false;
2010  }
2011  parent->ToggleWeapon( true, forward );
2012  static soundContainer missound;
2013  if (missound.sound < 0) {
2014  static string str = vs_config->getVariable( "cockpitaudio", "missile_switch", "vdu_d" );
2015  missound.loadsound( str );
2016  }
2017  missound.playsound();
2018  }
2019  unsigned int i;
2020  for (i = 0; i < NUMSAVEDTARGETS; i++) {
2021  if (f().saveTargetKeys[i] == PRESS) {
2022  f().saveTargetKeys[i] = RELEASE;
2023  savedTargets[i] = parent->Target();
2024  }
2025  if (f().restoreTargetKeys[i] == PRESS && parent->GetComputerData().radar.canlock) {
2026  f().restoreTargetKeys[i] = RELEASE;
2027  Unit *un;
2029  (un = *u) != NULL;
2030  ++u)
2031  if (un == savedTargets[i]) {
2032  parent->Target( un );
2033  break;
2034  }
2035  }
2036  }
2037  for (i = 0; i < NUMCOMMKEYS; i++)
2038  if (f().commKeys[i] == PRESS) {
2039  f().commKeys[i] = RELEASE;
2040  Unit *targ = parent->Target();
2041  if (targ) {
2042  CommunicationMessage *mymsg = GetTargetMessageQueue( targ, resp );
2044  if ( mymsg == NULL || mymsg->curstate >= static_cast<int>(fsm->nodes.size()) ) {
2045  CommunicationMessage c( parent, targ, i, NULL, parent->pilot->getGender() );
2046  unsigned int whichspeech = DoSpeech( targ, targ, *c.getCurrentState() );
2047  int sound = c.getCurrentState()->GetSound( c.sex, whichspeech );
2048  if ( !AUDIsPlaying( sound ) )
2049  AUDPlay( sound, QVector( 0, 0, 0 ), Vector( 0, 0, 0 ), 1 );
2050  Order *o = targ->getAIState();
2051  if (o)
2052  o->Communicate( c );
2053  } else {
2054  FSM *tmp = mymsg->fsm;
2055  mymsg->fsm = fsm;
2056  FSM::Node *n = mymsg->getCurrentState();
2057  if ( i < n->edges.size() ) {
2058  CommunicationMessage c( parent, targ, *mymsg, i, NULL, parent->pilot->getGender() );
2059  unsigned int whichmessage = DoSpeech( targ, targ, *c.getCurrentState() );
2060  int sound = c.getCurrentState()->GetSound( c.sex, whichmessage );
2061  if ( !AUDIsPlaying( sound ) )
2062  AUDPlay( sound, QVector( 0, 0, 0 ), Vector( 0, 0, 0 ), 1 );
2063  Order *oo = targ->getAIState();
2064  if (oo)
2065  oo->Communicate( c );
2066  }
2067  mymsg->fsm = tmp;
2068  }
2069  }
2070  }
2071  if (refresh_target) {
2072  Unit *targ;
2073  if ( ( targ = parent->Target() ) ) {
2074  if ( parent->isSubUnit() )
2075  parent->TargetTurret( targ );
2076  CommunicationMessage *mymsg = GetTargetMessageQueue( targ, resp );
2078  if (mymsg == NULL)
2080  fsm->GetEdgesString( fsm->getDefaultState( parent->getRelation( targ ) ) );
2081  else
2083  } else {
2084  _Universe->AccessCockpit()->communication_choices = "\nNo Communication\nLink\nEstablished";
2085  }
2086  }
2087  if (f().enslave == PRESS || f().freeslave == PRESS) {
2088  Enslave( parent, f().enslave == PRESS );
2089  f().enslave = RELEASE;
2090  f().freeslave = RELEASE;
2091  }
2092  if (f().ejectcargo == PRESS || f().ejectnonmissioncargo == PRESS) {
2093  bool missiontoo = (f().ejectcargo == PRESS);
2095  f().ejectcargo = RELEASE;
2097  if (offset < 3)
2098  offset = 0;
2099  else
2100  offset -= 3;
2101  for ( ; offset < static_cast<int>(parent->numCargo()); ++offset) {
2102  Cargo *tmp = &parent->GetCargo( offset );
2103  if ( tmp->GetCategory().find( "upgrades" ) == string::npos && (missiontoo || tmp->mission == false) ) {
2104  parent->EjectCargo( offset );
2105  break;
2106  }
2107  }
2108  if (missiontoo)
2110  else
2111  f().ejectcargo = DOWN;
2112  }
2113  //i think this ejects the pilot? yep it does
2114  if (f().eject == PRESS) {
2115  f().eject = DOWN;
2116  Cockpit *cp = NULL;
2117  if ( (parent->name != "eject") && (parent->name != "Pilot") && ( cp = _Universe->isPlayerStarship( parent ) ) )
2118  cp->Eject();
2119  }
2120  //eject pilot and warp pilot to the docking screen instantly.
2121  if (f().ejectdock == PRESS) {
2122  f().ejectdock = DOWN;
2123  Unit *utdw = parent;
2124  Cockpit *cp = NULL; //check if docking ports exist, no docking ports = no need to ejectdock so don't do anything
2125  if ( (SelectDockPort( utdw, parent ) > -1) && ( cp = _Universe->isPlayerStarship( parent ) ) )
2126  cp->EjectDock(); //use specialized ejectdock in the future
2127  }
2128  static bool actually_arrest = XMLSupport::parse_bool( vs_config->getVariable( "AI", "arrest_energy_zero", "false" ) );
2129  if (actually_arrest && parent->EnergyRechargeData() == 0)
2130  Arrested( parent );
2131 }
2132