REINF.CPP (32033B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: /CounterStrike/REINF.CPP 1 3/03/97 10:25a Joe_bostic $ */ 17 /*********************************************************************************************** 18 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : REINF.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : May 24, 1994 * 28 * * 29 * Last Update : July 26, 1996 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * Create_Air_Reinforcement -- Creates air strike reinforcement * 34 * Create_Special_Reinforcement -- Ad hoc reinforcement handler. * 35 * Do_Reinforcements -- Create and place a reinforcement team. * 36 * _Consists_Only_Of_Infantry -- Determine if this group consists only of infantry. * 37 * _Create_Group -- Create a group given team specification. * 38 * _Pop_Group_Out_Of_Object -- Process popping the group out of the object. * 39 * _Who_Can_Pop_Out_Of -- Find a suitable host for these reinforcements. * 40 * _Need_To_Take -- Examines unit to determine if it should be confiscated. * 41 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 42 43 #include "function.h" 44 45 46 /*********************************************************************************************** 47 * _Pop_Group_Out_Of_Object -- Process popping the group out of the object. * 48 * * 49 * This routine will cause the group to pop out of the object specified. * 50 * * 51 * INPUT: group -- Pointer to the first object in the group to be popped out. * 52 * * 53 * object -- Pointer to the object that the group is to pop out of. * 54 * * 55 * OUTPUT: bool; Was the group popped out of the specified object? * 56 * * 57 * WARNINGS: none * 58 * * 59 * HISTORY: * 60 * 06/25/1996 JLB : Created. * 61 *=============================================================================================*/ 62 static bool _Pop_Group_Out_Of_Object(FootClass * group, TechnoClass * object) 63 { 64 assert(group != NULL && object != NULL); 65 int quantity = 0; 66 67 /* 68 ** Take every infantry member of this group and detach it from the group list 69 ** and then make it pop out of the candidate source. 70 */ 71 while (group != NULL) { 72 TechnoClass * todo = group; 73 group = (FootClass *)(ObjectClass *)group->Next; 74 todo->Next = NULL; 75 76 switch (object->What_Am_I()) { 77 78 /* 79 ** The infantry just walks out of a building. 80 */ 81 case RTTI_BUILDING: 82 if (object->Exit_Object(todo) != 2) { 83 delete todo; 84 } else { 85 ++quantity; 86 } 87 break; 88 89 /* 90 ** Infantry get attached to transport vehicles and then unload. 91 */ 92 case RTTI_UNIT: 93 case RTTI_VESSEL: 94 case RTTI_AIRCRAFT: 95 object->Attach((FootClass *)todo); 96 object->Assign_Mission(MISSION_UNLOAD); 97 ++quantity; 98 break; 99 100 default: 101 delete todo; 102 break; 103 } 104 } 105 106 return (quantity != 0); 107 } 108 109 110 /*********************************************************************************************** 111 * _Need_To_Take -- Examines unit to determine if it should be confiscated. * 112 * * 113 * The unit is examined and if the owning house needs to confiscate it, then this routine * 114 * will return TRUE. In other cases, the unit should be left to its own devices. * 115 * * 116 * INPUT: unit -- Pointer to the object to examine. * 117 * * 118 * OUTPUT: bool; Should the object be confiscated by the player so that it becomes one of * 119 * his normal game objects? * 120 * * 121 * WARNINGS: none * 122 * * 123 * HISTORY: * 124 * 07/26/1996 JLB : Created. * 125 *=============================================================================================*/ 126 bool _Need_To_Take(AircraftClass const * air) 127 { 128 if (*air == AIRCRAFT_YAK || *air == AIRCRAFT_MIG) { 129 int deficit = air->House->Get_Quantity(STRUCT_AIRSTRIP); 130 // int deficit = air->House->Get_Quantity(STRUCT_AIRSTRIP) - (air->House->Get_Quantity(AIRCRAFT_YAK)+air->House->Get_Quantity(AIRCRAFT_MIG)); 131 132 /* 133 ** Loop through all aircraft and subtract all the ones that are NOT loaners. 134 */ 135 for (int index = 0; index < Aircraft.Count(); index++) { 136 AircraftClass const * airptr = Aircraft.Ptr(index); 137 if ((*airptr == AIRCRAFT_YAK || *airptr == AIRCRAFT_MIG) && airptr->IsOwnedByPlayer && !airptr->IsALoaner && airptr != air) { 138 deficit -= 1; 139 if (deficit == 0) break; 140 } 141 } 142 143 if (deficit > 0) return(true); 144 } 145 return(false); 146 } 147 148 149 /*********************************************************************************************** 150 * _Create_Group -- Create a group given team specification. * 151 * * 152 * This routine will create all members of the group as specified by the team type. * 153 * * 154 * INPUT: teamtype -- Pointer to the team type that specifies what objects should be * 155 * created in this group. * 156 * * 157 * OUTPUT: Returns with a pointer to the first member of the group created. * 158 * * 159 * WARNINGS: none * 160 * * 161 * HISTORY: * 162 * 06/25/1996 JLB : Created. * 163 *=============================================================================================*/ 164 static FootClass * _Create_Group(TeamTypeClass const * teamtype) 165 { 166 assert(teamtype != NULL); 167 168 TeamClass * team = new TeamClass(teamtype); 169 if (team != NULL) { 170 team->Force_Active(); 171 } 172 173 bool hasunload = false; 174 for (int tm = 0; tm < teamtype->MissionCount; tm++) { 175 if (teamtype->MissionList[tm].Mission == TMISSION_UNLOAD) { 176 hasunload = true; 177 break; 178 } 179 } 180 181 /* 182 ** Now that the official source for the reinforcement has been determined, the 183 ** objects themselves must be created. 184 */ 185 FootClass * transport = NULL; 186 FootClass * object = NULL; 187 for (int index = 0; index < teamtype->ClassCount; index++) { 188 TechnoTypeClass const * tclass = teamtype->Members[index].Class; 189 190 for (int sub = 0; sub < teamtype->Members[index].Quantity; sub++) { 191 ScenarioInit++; 192 FootClass * temp = (FootClass *)tclass->Create_One_Of(HouseClass::As_Pointer(teamtype->House)); 193 ScenarioInit--; 194 195 if (temp != NULL) { 196 197 /* 198 ** Add the member to the team. 199 */ 200 if (team != NULL) { 201 ScenarioInit++; 202 bool ok = team->Add(temp); 203 //Mono_Printf("Added to team = %d.\n", ok);Keyboard->Get(); 204 205 ScenarioInit--; 206 temp->IsInitiated = true; 207 } 208 209 if (temp->What_Am_I() == RTTI_AIRCRAFT && !_Need_To_Take((AircraftClass const *)temp)) { 210 temp->IsALoaner = true; 211 } 212 213 /* 214 ** Build the list of transporters and passengers. 215 */ 216 if (tclass->Max_Passengers() > 0) { 217 218 /* 219 ** Link to the list of transports. 220 */ 221 temp->Next = transport; 222 transport = temp; 223 224 } else { 225 226 /* 227 ** Link to the list of normal objects. 228 */ 229 temp->Next = object; 230 object = temp; 231 } 232 } 233 } 234 } 235 236 /* 237 ** If the group consists of transports and normal objects, then assign the normal 238 ** objects to be passengers on the transport. 239 */ 240 if (transport != NULL && object != NULL) { 241 transport->Attach(object); 242 243 /* 244 ** HACK ALERT! If the this team has an unload mission, then flag the transport 245 ** as a loaner so that it will exit from the map when the unload process is 246 ** complete, but only if the transport is an aircraft type. 247 */ 248 if (hasunload && (transport->What_Am_I() == RTTI_AIRCRAFT || transport->What_Am_I() == RTTI_VESSEL)) { 249 transport->IsALoaner = true; 250 } 251 } 252 253 /* 254 ** For JUST transport helicopters, consider the loaner a gift if there are 255 ** no passengers. 256 */ 257 if (transport != NULL && object == NULL && transport->What_Am_I() == RTTI_AIRCRAFT && *((AircraftClass *)transport) == AIRCRAFT_TRANSPORT) { 258 transport->IsALoaner = false; 259 } 260 261 if (transport == 0 && object == 0) { 262 if (team != NULL) delete team; 263 return(NULL); 264 } 265 266 /* 267 ** If this group consists only of non-transport object, then just return with a pointer 268 ** to the first member of the group. 269 */ 270 if (transport == NULL) { 271 return(object); 272 } 273 274 return(transport); 275 } 276 277 278 /*********************************************************************************************** 279 * _Consists_Only_Of_Infantry -- Determine if this group consists only of infantry. * 280 * * 281 * Use this to determine if the specified group only contains infantry. Such a reinforcement* 282 * group is a candidate for popping out of a building or transport vehicle rather than * 283 * driving/walking/sailing/flying onto the map under its own power. * 284 * * 285 * INPUT: first -- Pointer to the first object in the group to examine. * 286 * * 287 * OUTPUT: bool; Is the entire group composed of infantry type units? * 288 * * 289 * WARNINGS: none * 290 * * 291 * HISTORY: * 292 * 06/25/1996 JLB : Created. * 293 *=============================================================================================*/ 294 static bool _Consists_Only_Of_Infantry(FootClass const * first) 295 { 296 while (first != NULL) { 297 if (first->What_Am_I() != RTTI_INFANTRY) { 298 return(false); 299 } 300 first = (FootClass const *)((ObjectClass *)first->Next); 301 } 302 return(true); 303 } 304 305 306 /*********************************************************************************************** 307 * _Who_Can_Pop_Out_Of -- Find a suitable host for these reinforcements. * 308 * * 309 * This routine is used to scan nearby locations to determine if there is a suitable host * 310 * for these reinforcements to "pop out of" (apologies to Aliens). Typical hosts include * 311 * buildings and transport vehicles (of any kind). * 312 * * 313 * INPUT: origin -- The cell that should be scanned from. Only this location and immediate * 314 * adjacent locations will be scanned. * 315 * * 316 * OUTPUT: Returns with a pointer to a suitable host. If none could be found then NULL is * 317 * returned. * 318 * * 319 * WARNINGS: none * 320 * * 321 * HISTORY: * 322 * 06/25/1996 JLB : Created. * 323 *=============================================================================================*/ 324 static TechnoClass * _Who_Can_Pop_Out_Of(CELL origin) 325 { 326 CellClass * cellptr = &Map[origin]; 327 TechnoClass * candidate = NULL; 328 329 for (int f = -1; f < 8; f++) { 330 CellClass * ptr = cellptr; 331 if (f != -1) { 332 ptr = ptr->Adjacent_Cell(FacingType(f)); 333 if (!ptr) continue; 334 } 335 336 BuildingClass * building = ptr->Cell_Building(); 337 if (building && building->Strength > 0) { 338 candidate = building; 339 } 340 341 UnitClass * unit = ptr->Cell_Unit(); 342 if (unit && unit->Strength && unit->Class->Max_Passengers() > 0) { 343 return(unit); 344 } 345 } 346 return(candidate); 347 } 348 349 350 /*********************************************************************************************** 351 * Do_Reinforcements -- Create and place a reinforcement team. * 352 * * 353 * This routine is called when a reinforcement team must be created and placed on the map. * 354 * It will create all members of the team and place them at the location determined from * 355 * the team composition. The reinforcement team should follow team orders until overridden * 356 * by AI or player intervention. * 357 * * 358 * INPUT: teamtype -- Pointer to the team type to create as a reinforcement. * 359 * * 360 * OUTPUT: Was the reinforcement successfully created and placed? * 361 * * 362 * WARNINGS: none * 363 * * 364 * HISTORY: * 365 * 05/08/1995 JLB : Created. * 366 * 05/18/1995 JLB : Returns success or failure condition. * 367 * 06/19/1995 JLB : Announces reinforcements. * 368 * 02/15/1996 JLB : Recognizes team reinforcement location. * 369 *=============================================================================================*/ 370 bool Do_Reinforcements(TeamTypeClass const * teamtype) 371 { 372 assert(teamtype != 0); 373 374 /* 375 ** perform some preliminary checks for validity. 376 */ 377 if (!teamtype || !teamtype->ClassCount) return(false); 378 379 /* 380 ** HACK ALERT! 381 ** Give this team an attack waypoint mission that will attack the waypoint location of this 382 ** team if there are no team missions previously assigned. 383 */ 384 if (teamtype->MissionCount == 0) { 385 TeamTypeClass * tt = (TeamTypeClass *)teamtype; 386 tt->MissionCount = 1; 387 tt->MissionList[0].Mission = TMISSION_ATT_WAYPT; 388 tt->MissionList[0].Data.Value = teamtype->Origin; 389 } 390 391 FootClass * object = _Create_Group(teamtype); 392 393 394 //Mono_Printf("%d-%s (object=%p, team=%d).\n", __LINE__, __FILE__, object, object->Team.Is_Valid());Keyboard->Get(); 395 396 397 /* 398 ** Bail on this reinforcement if no reinforcements could be created. 399 ** This is probably because the object maximum was reached. 400 */ 401 if (!object) { 402 return(false); 403 } 404 405 /* 406 ** Special case code to handle infantry types that run from a building. This presumes 407 ** that infantry are never a transport (which is safe to do). 408 */ 409 if (object != NULL && teamtype->Origin != -1 && _Consists_Only_Of_Infantry(object)) { 410 411 /* 412 ** Search for an object that these infantry can pop out of. 413 */ 414 TechnoClass * candidate = _Who_Can_Pop_Out_Of(Scen.Waypoint[teamtype->Origin]); 415 416 if (candidate != NULL) { 417 return(_Pop_Group_Out_Of_Object(object, candidate)); 418 } 419 } 420 421 /* 422 ** The reinforcements must be delivered the old fashioned way -- by moving onto the 423 ** map using their own power. First order of business is to determine where they 424 ** should arrive from. 425 */ 426 SourceType source = HouseClass::As_Pointer(teamtype->House)->Control.Edge; 427 if (source == SOURCE_NONE) { 428 source = SOURCE_NORTH; 429 } 430 431 /* 432 ** Pick the location where the reinforcements appear and then place 433 ** them there. 434 */ 435 bool placed = false; 436 437 FacingType eface = (FacingType)(source << 1); // Facing to enter map. 438 439 CELL cell = Map.Calculated_Cell(source, teamtype->Origin, -1, object->Techno_Type_Class()->Speed); 440 #ifdef FIXIT_ANTS 441 /* 442 ** For the ants, they will pop out of the ant hill directly. 443 */ 444 if (teamtype->Origin != -1 && object->What_Am_I() == RTTI_UNIT && 445 (*((UnitClass*)object) == UNIT_ANT1 || 446 *((UnitClass*)object) == UNIT_ANT2 || 447 *((UnitClass*)object) == UNIT_ANT3)) { 448 CELL newcell = Scen.Waypoint[teamtype->Origin]; 449 if (newcell != -1) { 450 if (Map[newcell].TType == TEMPLATE_HILL01) { 451 cell = newcell; 452 } 453 } 454 } 455 #endif 456 457 CELL newcell = cell; 458 459 FootClass * o = (FootClass *)(ObjectClass *)object->Next; 460 object->Next = 0; 461 bool okvoice = false; 462 while (newcell > 0 && object != NULL) { 463 DirType desiredfacing = Facing_Dir(eface); 464 if (object->What_Am_I() == RTTI_AIRCRAFT) { 465 desiredfacing = Random_Pick(DIR_N, DIR_MAX); 466 } 467 468 ScenarioInit++; 469 if (object->Unlimbo(Cell_Coord(newcell), desiredfacing)) { 470 okvoice = true; 471 472 /* 473 ** If this object is part of a team, then the mission for this 474 ** object will be guard. The team handler will assign the proper 475 ** mission that it should follow. 476 */ 477 if (object->What_Am_I() != RTTI_AIRCRAFT) { 478 object->Assign_Mission(MISSION_GUARD); 479 object->Commence(); 480 } 481 482 } else { 483 484 /* 485 ** Could not unlimbo at location specified so find an adjacent location that it can 486 ** be unlimboed at. If this fails, then abort the whole placement process. 487 */ 488 FacingType adj; 489 for (adj = FACING_N; adj < FACING_COUNT; adj++) { 490 CELL trycell = Adjacent_Cell(newcell, adj); 491 if (!Map.In_Radar(trycell) && object->Can_Enter_Cell(trycell, adj) == MOVE_OK) { 492 newcell = trycell; 493 break; 494 } 495 } 496 if (adj < FACING_COUNT) continue; 497 newcell = 0; 498 } 499 ScenarioInit--; 500 501 object = o; 502 if (object != NULL) { 503 o = (FootClass *)(ObjectClass *)object->Next; 504 object->Next = 0; 505 } 506 } 507 508 /* 509 ** If there are still objects that could not be placed, then delete them. 510 */ 511 if (o != NULL) { 512 while (o != NULL) { 513 FootClass * old = o; 514 o = (FootClass *)(ObjectClass *)o->Next; 515 old->Next = 0; 516 517 delete old; 518 } 519 } 520 521 /* 522 ** Announce when the reinforcements have arrived. 523 */ 524 if (okvoice && teamtype->House == PlayerPtr->Class->House) { 525 Speak(VOX_REINFORCEMENTS, NULL, newcell ? Cell_Coord(newcell) : 0); 526 } 527 528 return(true); 529 } 530 531 532 /*********************************************************************************************** 533 * Create_Special_Reinforcement -- Ad hoc reinforcement handler. * 534 * * 535 * Use this routine to bring on a reinforcement that hasn't been anticipated by the trigger * 536 * system. An example of this would be replacement harvesters or airfield ordered units. * 537 * The appropriate transport is created (if necessary) and a mission is assigned such that * 538 * the object will legally bring itself onto the playing field. * 539 * * 540 * INPUT: house -- The owner of this reinforcement. * 541 * * 542 * type -- The object to bring on. * 543 * * 544 * another -- This is reserved for the transport class in those cases where the * 545 * transport MUST be forced to a specific type. * 546 * * 547 * mission -- The mission to assign this reinforcement team. * 548 * * 549 * argument -- Optional team mission argument (usually a waypoint). * 550 * * 551 * OUTPUT: Was the special reinforcement created without error? * 552 * * 553 * WARNINGS: This routine will fail if a team type cannot be created. * 554 * * 555 * HISTORY: * 556 * 07/04/1995 JLB : Created. * 557 *=============================================================================================*/ 558 bool Create_Special_Reinforcement(HouseClass * house, TechnoTypeClass const * type, TechnoTypeClass const * another, TeamMissionType mission, int argument) 559 { 560 assert(house != 0); 561 assert(type != 0); 562 563 if (house && type) { 564 TeamTypeClass * team = new TeamTypeClass(); 565 566 if (team) { 567 568 /* 569 ** If there is no overridden mission assign to this special reinforcement, then 570 ** we must assign something. If not, the reinforcement will just sit at the edge 571 ** of the map. 572 */ 573 if (!another && mission == TMISSION_NONE) { 574 mission = TMISSION_MOVECELL; 575 argument = Map.Calculated_Cell(house->Control.Edge); 576 } 577 578 /* 579 ** Fill in the team characteristics. 580 */ 581 strcpy((char *)&team->IniName[0], "TEMP"); 582 team->IsReinforcable = false; 583 team->IsTransient = true; 584 team->ClassCount = 1; 585 team->Members[0].Class = type; 586 team->Members[0].Quantity = 1; 587 team->MissionCount = 1; 588 if (mission == TMISSION_NONE) { 589 team->MissionList[0].Mission = TMISSION_UNLOAD; 590 team->MissionList[0].Data.Value = WAYPT_REINF; 591 } else { 592 team->MissionList[0].Mission = mission; 593 team->MissionList[0].Data.Value = argument; 594 } 595 team->House = house->Class->House; 596 if (another) { 597 team->ClassCount++; 598 team->Members[1].Class = another; 599 team->Members[1].Quantity = 1; 600 } 601 602 bool ok = Do_Reinforcements(team); 603 if (!ok) delete team; 604 return(ok); 605 } 606 } 607 return(false); 608 } 609 610 611 /*********************************************************************************************** 612 * Create_Air_Reinforcement -- Creates air strike reinforcement * 613 * * 614 * This routine is used to launch an airstrike. It will create the necessary aircraft and * 615 * assign them to attack the target specified. This routine bypasses the normal * 616 * reinforcement logic since it doesn't need the sophistication of unloading and following * 617 * team mission lists. * 618 * * 619 * INPUT: house -- The perpetrator of this air strike. * 620 * * 621 * air -- The type of aircraft to make up this airstrike. * 622 * * 623 * number -- The number of aircraft in this airstrike. * 624 * * 625 * mission -- The mission to assign the aircraft. * 626 * * 627 * tarcom -- The target to assign these aircraft. * 628 * * 629 * navcom -- The navigation target to assign (if necessary). * 630 * * 631 * OUTPUT: Returns the number of aircraft created for this airstrike. * 632 * * 633 * WARNINGS: none * 634 * * 635 * HISTORY: * 636 * 07/04/1995 JLB : Commented. * 637 *=============================================================================================*/ 638 int Create_Air_Reinforcement(HouseClass * house, AircraftType air, int number, MissionType mission, TARGET tarcom, TARGET navcom, InfantryType passenger) 639 { 640 assert(house != 0); 641 assert((unsigned)air < AIRCRAFT_COUNT); 642 assert(number != 0); 643 assert((unsigned)mission < MISSION_COUNT); 644 /* 645 ** Get a pointer to the class of the object that we are going to create. 646 */ 647 TechnoTypeClass const * type = (TechnoTypeClass *)&AircraftTypeClass::As_Reference(air); 648 649 /* 650 ** Abort the airstrike if Tanya is the passenger and she's dead. 651 */ 652 if (passenger == INFANTRY_TANYA && IsTanyaDead) { 653 number = 0; 654 } 655 656 /* 657 ** Loop through the number of objects we are supposed to create and 658 ** create and place them on the map. 659 */ 660 int sub; 661 for (sub = 0; sub < number; sub++) { 662 663 /* 664 ** Create one of the required objects. If this fails we could have 665 ** a real problem. 666 */ 667 ScenarioInit++; 668 TechnoClass * obj = (TechnoClass *)type->Create_One_Of(house); 669 ScenarioInit--; 670 if (!obj) return(sub); 671 672 /* 673 ** Flying objects always have the IsALoaner bit set. 674 */ 675 obj->IsALoaner = true; 676 677 /* 678 ** Find a cell for the object to come in on. This is stolen from the 679 ** the code that handles a SOURCE_AIR in the normal logic. 680 */ 681 SourceType source = house->Control.Edge; 682 switch (source) { 683 case SOURCE_NORTH: 684 case SOURCE_EAST: 685 case SOURCE_SOUTH: 686 case SOURCE_WEST: 687 break; 688 689 default: 690 source = SOURCE_NORTH; 691 break; 692 } 693 CELL newcell = Map.Calculated_Cell(source, -1, -1, SPEED_WINGED); 694 695 /* 696 ** Try and place the object onto the map. 697 */ 698 ScenarioInit++; 699 int placed = obj->Unlimbo(Cell_Coord(newcell), DIR_N); 700 ScenarioInit--; 701 if (placed) { 702 703 /* 704 ** If we succeeded in placing the obj onto the map then 705 ** now we need to give it a mission and destination. 706 */ 707 obj->Assign_Mission(mission); 708 709 /* 710 ** If a navcom was specified then set it. 711 */ 712 if (navcom != TARGET_NONE) { 713 obj->Assign_Destination(navcom); 714 } 715 716 /* 717 ** If a tarcom was specified then set it. 718 */ 719 if (tarcom != TARGET_NONE) { 720 obj->Assign_Target(tarcom); 721 } 722 723 /* 724 ** Assign generic passenger value here. This value is used to determine 725 ** if this aircraft should drop parachute reinforcements. 726 */ 727 if (obj->What_Am_I() == RTTI_AIRCRAFT) { 728 AircraftClass * aircraft = (AircraftClass *)obj; 729 if (passenger != INFANTRY_NONE) { 730 aircraft->Passenger = passenger; 731 } 732 // if (Passenger == INFANTRY_TANYA) { 733 // aircraft->Ammo = 1; 734 //aircraft->AttacksRemaining = 1; 735 // } 736 } 737 738 /* 739 ** Start the object into action. 740 */ 741 obj->Commence(); 742 } else { 743 delete obj; 744 sub--; 745 return(sub); 746 } 747 } 748 return(sub); 749 }