TEAMTYPE.CPP (39616B)
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: F:\projects\c&c\vcs\code\teamtype.cpv 2.17 16 Oct 1995 16:48:52 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 : TEAMTYPE.CPP * 24 * * 25 * Programmer : Bill Randolph * 26 * * 27 * Start Date : December 7, 1994 * 28 * * 29 * Last Update : July 21, 1995 [JLB] * 30 * * 31 *-------------------------------------------------------------------------* 32 * Functions: * 33 * TeamTypeClass::TeamTypeClass -- class constructor * 34 * TeamTypeClass::~TeamTypeClass -- class destructor * 35 * TeamTypeClass::Init -- pre-scenario initialization * 36 * TeamTypeClass::Read_INI -- reads INI data * 37 * TeamTypeClass::Write_INI -- writes INI data * 38 * TeamTypeClass::Read_Old_INI -- reads old INI format * 39 * TeamTypeClass::As_Pointer -- gets ptr for team type with given name * 40 * TeamTypeClass::Remove -- removes this team from the system * 41 * TeamTypeClass::Mission_From_Name -- returns mission for given name * 42 * TeamTypeClass::Name_From_Mission -- returns name for given mission * 43 * TeamTypeClass::operator new -- 'new' operator * 44 * TeamTypeClass::operator delete -- 'delete' operator * 45 * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. * 46 * TeamTypeClass::Validate -- validates teamtype pointer * 47 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 48 49 #include "function.h" 50 51 52 /* 53 ********************************** Globals ********************************** 54 */ 55 char const * TeamTypeClass::TMissions[TMISSION_COUNT] = { 56 "Attack Base", 57 "Attack Units", 58 "Attack Civil.", 59 "Rampage", 60 "Defend Base", 61 // "Harvest", 62 "Move", 63 "Move to Cell", 64 "Retreat", 65 "Guard", 66 "Loop", 67 "Attack Tarcom", 68 "Unload", 69 }; 70 71 /* 72 ** This contains the value of the Virtual Function Table Pointer 73 */ 74 void * TeamTypeClass::VTable; 75 76 77 /*********************************************************************************************** 78 * TeamTypeClass::Validate -- validates teamtype pointer * 79 * * 80 * INPUT: * 81 * none. * 82 * * 83 * OUTPUT: * 84 * 1 = ok, 0 = error * 85 * * 86 * WARNINGS: * 87 * none. * 88 * * 89 * HISTORY: * 90 * 08/09/1995 BRR : Created. * 91 *=============================================================================================*/ 92 #ifdef CHEAT_KEYS 93 int TeamTypeClass::Validate(void) const 94 { 95 int num; 96 97 num = TeamTypes.ID(this); 98 if (num < 0 || num >= TEAMTYPE_MAX) { 99 Validate_Error("TEAMTYPE"); 100 return (0); 101 } 102 else 103 return (1); 104 } 105 #else 106 #define Validate() 107 #endif 108 109 110 /*************************************************************************** 111 * TeamTypeClass::TeamTypeClass -- class constructor * 112 * * 113 * INPUT: * 114 * * 115 * OUTPUT: * 116 * * 117 * WARNINGS: * 118 * * 119 * HISTORY: * 120 * 12/07/1994 BR : Created. * 121 *=========================================================================*/ 122 TeamTypeClass::TeamTypeClass(void) 123 { 124 IsPrebuilt = true; 125 IsReinforcable = true; 126 IsRoundAbout = false; 127 IsLearning = false; 128 IsSuicide = false; 129 IsAutocreate = false; 130 IsTransient = false; 131 IsMercenary = false; 132 RecruitPriority = 7; 133 MaxAllowed = 0; 134 Fear = 0; 135 InitNum = 0; 136 House = HOUSE_NONE; 137 MissionCount = 0; 138 IniName[0] = '\0'; 139 ClassCount = 0; 140 for (int i = 0; i < MAX_TEAM_CLASSCOUNT; i++) { 141 Class[i] = NULL; 142 DesiredNum[i] = 0; 143 } 144 } 145 146 147 /*************************************************************************** 148 * TeamTypeClass::Init -- pre-scenario initialization * 149 * * 150 * INPUT: * 151 * * 152 * OUTPUT: * 153 * * 154 * WARNINGS: * 155 * * 156 * HISTORY: * 157 * 12/07/1994 BR : Created. * 158 *=========================================================================*/ 159 void TeamTypeClass::Init(void) 160 { 161 TeamTypeClass *ptr; 162 163 TeamTypes.Free_All(); 164 165 ptr = new TeamTypeClass(); 166 VTable = ((void **)(((char *)ptr) + sizeof(AbstractTypeClass) - 4))[0]; 167 delete ptr; 168 } 169 170 171 /*************************************************************************** 172 * TeamTypeClass::Read_INI -- reads INI data * 173 * * 174 * INI entry format: * 175 * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, * 176 * RecruitPriority,MaxAllowed,InitNum,Fear, * 177 * ClassCount,Class:Num,Class:Num,..., * 178 * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... * 179 * * 180 * INPUT: * 181 * buffer buffer to hold the INI data * 182 * * 183 * OUTPUT: * 184 * none. * 185 * * 186 * WARNINGS: * 187 * none. * 188 * * 189 * HISTORY: * 190 * 12/07/1994 BR : Created. * 191 * 02/01/1995 BR : No del team if no classes (editor needs empty teams!) * 192 *=========================================================================*/ 193 void TeamTypeClass::Read_INI(char *buffer) 194 { 195 TeamTypeClass * team; // Working team pointer. 196 char *tbuffer; // Accumulation buffer of team names. 197 int len; // Length of data in buffer. 198 char buf[500]; // INI entry buffer 199 200 /*------------------------------------------------------------------------ 201 Set 'tbuffer' to point just past the INI buffer 202 ------------------------------------------------------------------------*/ 203 len = strlen(buffer) + 2; 204 tbuffer = buffer + len; 205 206 /*------------------------------------------------------------------------ 207 Read all TeamType entry names into 'tbuffer' 208 ------------------------------------------------------------------------*/ 209 WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); 210 211 /* 212 ----------------------- Loop for all team entries ------------------------ 213 */ 214 while (*tbuffer != '\0') { 215 /* 216 ....................... Create a new team type ........................ 217 */ 218 team = new TeamTypeClass(); 219 220 /* 221 ......................... Get the team entry .......................... 222 */ 223 WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); 224 225 /* 226 .......................... Fill the team in ........................... 227 */ 228 team->Fill_In(tbuffer, buf); 229 230 /* 231 ...................... Go to the next INI entry ....................... 232 */ 233 tbuffer += strlen(tbuffer)+1; 234 } 235 236 /* 237 ** If no teams were read in, try reading the old INI format. 238 */ 239 if (TeamTypes.Count()==0) { 240 Read_Old_INI(buffer); 241 } 242 } 243 244 245 /*********************************************************************************************** 246 * TeamTypeClass::Fill_In -- fills in trigger from the given INI entry * 247 * * 248 * This routine fills in the given teamtype with the given name, and values from * 249 * the given INI entry. * 250 * * 251 * (This routine is used by the scenario editor, to import teams from the MASTER.INI file.) * 252 * * 253 * INI entry format: * 254 * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, * 255 * RecruitPriority,MaxAllowed,InitNum,Fear, * 256 * ClassCount,Class:Num,Class:Num,..., * 257 * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... * 258 * * 259 * INPUT: * 260 * name mnemonic for the desired trigger * 261 * entry INI entry to parse * 262 * * 263 * OUTPUT: * 264 * none. * 265 * * 266 * WARNINGS: * 267 * none. * 268 * * 269 * HISTORY: * 270 * 11/28/1994 BR : Created. * 271 *=============================================================================================*/ 272 void TeamTypeClass::Fill_In(char * name, char *entry) 273 { 274 Validate(); 275 int num_classes; 276 char *p1; // parsing pointer 277 char *p2; // parsing pointer 278 int i; // loop counter 279 TechnoTypeClass const *otype; // ptr to type of object 280 InfantryType i_id; // infantry ID 281 UnitType u_id; // unit ID 282 AircraftType a_id; // aircraft ID 283 TeamMissionStruct mission; 284 285 /* 286 ------------------------------ Set its name ------------------------------ 287 */ 288 Set_Name(name); 289 290 /* 291 ---------------------------- 1st token: House ---------------------------- 292 */ 293 House = HouseTypeClass::From_Name(strtok(entry,",")); 294 295 /* 296 -------------------------- 2nd token: RoundAbout ------------------------- 297 */ 298 IsRoundAbout = atoi(strtok(NULL,",")); 299 300 /* 301 --------------------------- 3rd token: Learning -------------------------- 302 */ 303 IsLearning = atoi(strtok(NULL,",")); 304 305 /* 306 --------------------------- 4th token: Suicide --------------------------- 307 */ 308 IsSuicide = atoi(strtok(NULL,",")); 309 310 /* 311 ----------------------------- 5th token: Spy ----------------------------- 312 */ 313 IsAutocreate = atoi(strtok(NULL,",")); 314 315 /* 316 -------------------------- 6th token: Mercenary -------------------------- 317 */ 318 IsMercenary = atoi(strtok(NULL,",")); 319 320 /* 321 ----------------------- 7th token: RecruitPriority ----------------------- 322 */ 323 RecruitPriority = atoi(strtok(NULL,",")); 324 325 /* 326 -------------------------- 8th token: MaxAllowed ------------------------- 327 */ 328 MaxAllowed = atoi(strtok(NULL,",")); 329 330 /* 331 --------------------------- 9th token: InitNum --------------------------- 332 */ 333 InitNum = atoi(strtok(NULL,",")); 334 335 /* 336 ------------------------- 10th token: Fear level ------------------------- 337 */ 338 Fear = atoi(strtok(NULL,",")); 339 340 /* 341 ------------------------ 11th token: Class count ------------------------- 342 */ 343 num_classes = atoi(strtok(NULL,",")); 344 345 /* 346 -------------- Loop through entries, setting class ptr & num ------------- 347 */ 348 ClassCount = 0; 349 for (i = 0; i < num_classes; i++) { 350 p1 = strtok(NULL,",:"); 351 p2 = strtok(NULL,",:"); 352 otype = NULL; 353 354 /* 355 ------------------- See if this is an infantry name ------------------- 356 */ 357 i_id = InfantryTypeClass::From_Name(p1); 358 if (i_id != INFANTRY_NONE) { 359 otype = &InfantryTypeClass::As_Reference(i_id); 360 } 361 362 /* 363 ---------------------- See if this is a unit name --------------------- 364 */ 365 u_id = UnitTypeClass::From_Name(p1); 366 if (u_id != UNIT_NONE) { 367 otype = &UnitTypeClass::As_Reference(u_id); 368 } 369 370 /* 371 ------------------- See if this is an aircraft name ------------------- 372 */ 373 a_id = AircraftTypeClass::From_Name(p1); 374 if (a_id != AIRCRAFT_NONE) { 375 otype = &AircraftTypeClass::As_Reference(a_id); 376 } 377 378 /* 379 --------------- If the name was resolved, add this class -------------- 380 */ 381 if (otype) { 382 if (ClassCount < MAX_TEAM_CLASSCOUNT) { 383 Class[ClassCount] = otype; 384 DesiredNum[ClassCount] = atoi(p2); 385 ClassCount++; 386 } 387 } 388 } 389 390 /* 391 ----------------------- next token: Mission count ------------------------ 392 */ 393 MissionCount = atoi(strtok(NULL,",")); 394 395 for (i = 0; i < MissionCount; i++) { 396 p1 = strtok(NULL,",:"); 397 p2 = strtok(NULL,",:"); 398 mission.Mission = Mission_From_Name(p1); 399 mission.Argument = atoi(p2); 400 MissionList[i] = mission; 401 } 402 403 char * ptr = strtok(NULL, ","); 404 if (ptr) { 405 IsReinforcable = atoi(ptr); 406 } 407 ptr = strtok(NULL, ","); 408 if (ptr) { 409 IsPrebuilt = atoi(ptr); 410 } 411 } 412 413 414 /*************************************************************************** 415 * TeamTypeClass::Write_INI -- writes INI data * 416 * * 417 * INI entry format: * 418 * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, * 419 * RecruitPriority,MaxAllowed,InitNum,Fear, * 420 * ClassCount,Class:Num,Class:Num,..., * 421 * MissionCount,Mission,Arg,Mission,Arg,Mission,Arg,... * 422 * * 423 * INPUT: * 424 * buffer buffer to store INI data in * 425 * * 426 * OUTPUT: * 427 * none. * 428 * * 429 * WARNINGS: * 430 * none. * 431 * * 432 * HISTORY: * 433 * 12/07/1994 BR : Created. * 434 *=========================================================================*/ 435 void TeamTypeClass::Write_INI(char *buffer, bool refresh) 436 { 437 int index; 438 int i; 439 char buf[500]; 440 TeamTypeClass * team; 441 char const *hname; 442 443 /*------------------------------------------------------------------------ 444 First, clear out all existing teamtypes in the old-style format. 445 ------------------------------------------------------------------------*/ 446 WWWritePrivateProfileString("Teams", NULL, NULL, buffer); 447 448 /*------------------------------------------------------------------------ 449 Clear out all existing teamtype data from the INI file. 450 ------------------------------------------------------------------------*/ 451 if (refresh) { 452 WWWritePrivateProfileString(INI_Name(), NULL, NULL, buffer); 453 } 454 455 /*------------------------------------------------------------------------ 456 Now write all the team data out 457 ------------------------------------------------------------------------*/ 458 buf[0] = 0; 459 for (index = 0; index < TeamTypes.Count(); index++) { 460 /* 461 .................. Get ptr to next active teamtype .................... 462 */ 463 team = TeamTypes.Ptr(index); 464 465 /* 466 .......................... Find house's name .......................... 467 */ 468 if (team->House==HOUSE_NONE) { 469 hname = "None"; 470 } else { 471 hname = HouseClass::As_Pointer(team->House)->Class->IniName; 472 } 473 474 /* 475 ......................... Generate INI entry .......................... 476 */ 477 sprintf(buf,"%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", 478 hname, 479 team->IsRoundAbout, 480 team->IsLearning, 481 team->IsSuicide, 482 team->IsAutocreate, 483 team->IsMercenary, 484 team->RecruitPriority, 485 team->MaxAllowed, 486 team->InitNum, 487 team->Fear, 488 team->ClassCount); 489 490 /*..................................................................... 491 For every class in the team, record the class's name & desired count 492 .....................................................................*/ 493 for (i = 0; i < team->ClassCount; i++) { 494 sprintf (buf + strlen(buf), ",%s:%d", 495 team->Class[i]->IniName, 496 team->DesiredNum[i]); 497 } 498 499 /*..................................................................... 500 Record the # of missions, and each mission name & argument value. 501 .....................................................................*/ 502 sprintf(buf + strlen(buf),",%d",team->MissionCount); 503 for (i = 0; i < team->MissionCount; i++) { 504 sprintf (buf + strlen(buf), ",%s:%d", 505 Name_From_Mission(team->MissionList[i].Mission), 506 team->MissionList[i].Argument); 507 } 508 509 if (team->IsReinforcable) { 510 strcat(buf, ",1"); 511 } else { 512 strcat(buf, ",0"); 513 } 514 if (team->IsPrebuilt) { 515 strcat(buf, ",1"); 516 } else { 517 strcat(buf, ",0"); 518 } 519 520 WWWritePrivateProfileString(INI_Name(), team->IniName, buf, buffer); 521 } 522 } 523 524 525 /*************************************************************************** 526 * TeamTypeClass::Read_Old_INI -- reads old INI format * 527 * * 528 * INI entry format: * 529 * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, * 530 * RecruitPriority,MaxAllowed,InitNum,Class:Num,Class:Num,...,Fear * 531 * * 532 * INPUT: * 533 * buffer buffer to hold the INI data * 534 * * 535 * OUTPUT: * 536 * none. * 537 * * 538 * WARNINGS: * 539 * none. * 540 * * 541 * HISTORY: * 542 * 12/07/1994 BR : Created. * 543 * 02/01/1995 BR : No del team if no classes (editor needs empty teams!) * 544 *=========================================================================*/ 545 void TeamTypeClass::Read_Old_INI(char *buffer) 546 { 547 TeamTypeClass * team; // Working team pointer. 548 char *tbuffer; // Accumulation buffer of team names. 549 int len; // Length of data in buffer. 550 char buf[256]; // INI entry buffer 551 char *p1; // parsing pointer 552 char *p2; // parsing pointer 553 int index; 554 TechnoTypeClass const *otype; // ptr to type of object 555 InfantryType i_id; // infantry ID 556 UnitType u_id; // unit ID 557 AircraftType a_id; // infantry ID 558 559 /*------------------------------------------------------------------------ 560 Set 'tbuffer' to point just past the INI buffer 561 ------------------------------------------------------------------------*/ 562 len = strlen(buffer) + 2; 563 tbuffer = buffer + len; 564 565 /*------------------------------------------------------------------------ 566 Read all TeamType entry names into 'tbuffer' 567 ------------------------------------------------------------------------*/ 568 WWGetPrivateProfileString("Teams", NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); 569 570 /* 571 ----------------------- Loop for all team entries ------------------------ 572 */ 573 while (*tbuffer != '\0') { 574 /* 575 ........................ Create a new trigger ......................... 576 */ 577 team = new TeamTypeClass(); 578 579 /* 580 ............................ Set its name ............................. 581 */ 582 team->Set_Name(tbuffer); 583 584 /* 585 ......................... Get the team entry .......................... 586 */ 587 WWGetPrivateProfileString("Teams", tbuffer, NULL, buf, sizeof(buf)-1, buffer); 588 589 /* 590 .......................... 1st token: House ........................... 591 */ 592 team->House = HouseTypeClass::From_Name(strtok(buf,",")); 593 594 /* 595 ........................ 2nd token: RoundAbout ........................ 596 */ 597 team->IsRoundAbout = atoi(strtok(NULL,",")); 598 599 /* 600 ......................... 3rd token: Learning ......................... 601 */ 602 team->IsLearning = atoi(strtok(NULL,",")); 603 604 /* 605 ......................... 4th token: Suicide .......................... 606 */ 607 team->IsSuicide = atoi(strtok(NULL,",")); 608 609 /* 610 ........................... 5th token: Spy ............................ 611 */ 612 team->IsAutocreate = atoi(strtok(NULL,",")); 613 614 /* 615 ........................ 6th token: Mercenary ......................... 616 */ 617 team->IsMercenary = atoi(strtok(NULL,",")); 618 619 /* 620 ..................... 7th token: RecruitPriority ...................... 621 */ 622 team->RecruitPriority = atoi(strtok(NULL,",")); 623 624 /* 625 ........................ 8th token: MaxAllowed ........................ 626 */ 627 team->MaxAllowed = atoi(strtok(NULL,",")); 628 629 /* 630 ......................... 9th token: InitNum .......................... 631 */ 632 team->InitNum = atoi(strtok(NULL,",")); 633 634 /* 635 ....................... 10th token: Mission name ...................... 636 */ 637 strtok(NULL,","); // just throw it away 638 639 /* 640 ............ Loop through entries, setting class ptr & num ............ 641 */ 642 index = 0; 643 p1 = strtok(NULL,",:"); 644 p2 = strtok(NULL,",:"); 645 while (p1 && p2) { 646 otype = NULL; 647 648 /* 649 ................. See if this is an infantry name .................. 650 */ 651 i_id = InfantryTypeClass::From_Name(p1); 652 if (i_id!=INFANTRY_NONE) { 653 otype = &InfantryTypeClass::As_Reference(i_id); 654 } 655 656 /* 657 .................... See if this is a unit name .................... 658 */ 659 u_id = UnitTypeClass::From_Name(p1); 660 if (u_id != UNIT_NONE) { 661 otype = &UnitTypeClass::As_Reference(u_id); 662 } 663 664 /* 665 ................. See if this is an aircraft name .................. 666 */ 667 a_id = AircraftTypeClass::From_Name(p1); 668 if (a_id != AIRCRAFT_NONE) { 669 otype = &AircraftTypeClass::As_Reference(a_id); 670 } 671 672 /* 673 ............. If the name was resolved, add this class ............. 674 */ 675 if (otype) { 676 team->Class[index] = otype; 677 team->DesiredNum[index] = atoi(p2); 678 index++; 679 team->ClassCount = index; 680 } 681 682 /* 683 ................. Go to the next entry on the line ................. 684 */ 685 p1 = strtok(NULL,",:"); 686 p2 = strtok(NULL,",:"); 687 } 688 689 team->Fear = 0; 690 691 /* 692 ...................... Go to the next INI entry ....................... 693 */ 694 tbuffer += strlen(tbuffer)+1; 695 } 696 } 697 698 699 /*************************************************************************** 700 * TeamTypeClass::As_Pointer -- gets ptr for team type with given name * 701 * * 702 * INPUT: * 703 * name name of teamtype * 704 * * 705 * OUTPUT: * 706 * ptr to TeamType with that name * 707 * * 708 * WARNINGS: * 709 * none. * 710 * * 711 * HISTORY: * 712 * 12/07/1994 BR : Created. * 713 *=========================================================================*/ 714 TeamTypeClass * TeamTypeClass::As_Pointer(char *name) 715 { 716 int i; 717 718 if (name == NULL) { 719 return(NULL); 720 } 721 722 for (i = 0; i < TeamTypes.Count(); i++) { 723 if (!stricmp(name, TeamTypes.Ptr(i)->IniName)) { 724 return(TeamTypes.Ptr(i)); 725 } 726 } 727 728 return(NULL); 729 } 730 731 732 /*************************************************************************** 733 * TeamTypeClass::Remove -- removes this team from the system * 734 * * 735 * INPUT: * 736 * none. * 737 * * 738 * OUTPUT: * 739 * none. * 740 * * 741 * WARNINGS: * 742 * none. * 743 * * 744 * HISTORY: * 745 * 12/09/1994 BR : Created. * 746 *=========================================================================*/ 747 void TeamTypeClass::Remove(void) 748 { 749 Validate(); 750 int i; 751 TriggerClass * trigger; 752 753 /* 754 ** Remove all trigger references to this team. 755 */ 756 for (i = 0; i < Triggers.Count(); i++) { 757 trigger = Triggers.Ptr(i); 758 if (trigger->Team == this) { 759 trigger->Team = NULL; 760 } 761 } 762 763 /* 764 ** Delete myself. 765 */ 766 delete this; 767 } 768 769 770 /*************************************************************************** 771 * TeamTypeClass::Mission_From_Name -- returns team mission for given name * 772 * * 773 * INPUT: * 774 * name name to compare * 775 * * 776 * OUTPUT: * 777 * mission for that name * 778 * * 779 * WARNINGS: * 780 * none. * 781 * * 782 * HISTORY: * 783 * 12/13/1994 BR : Created. * 784 *=========================================================================*/ 785 TeamMissionType TeamTypeClass::Mission_From_Name(char const *name) 786 { 787 int order; 788 789 if (name) { 790 for (order = TMISSION_FIRST; order < TMISSION_COUNT; order++) { 791 if (stricmp(TMissions[order], name) == 0) { 792 return((TeamMissionType) order); 793 } 794 } 795 } 796 797 return(TMISSION_NONE); 798 } 799 800 801 /*************************************************************************** 802 * TeamTypeClass::Name_From_Mission -- returns name for given mission * 803 * * 804 * INPUT: * 805 * order mission to get name for * 806 * * 807 * OUTPUT: * 808 * name of mission * 809 * * 810 * WARNINGS: * 811 * none. * 812 * * 813 * HISTORY: * 814 * 12/13/1994 BR : Created. * 815 *=========================================================================*/ 816 char const * TeamTypeClass::Name_From_Mission(TeamMissionType order) 817 { 818 if (order <= TMISSION_NONE || order >= TMISSION_COUNT) { 819 return("None"); 820 } else { 821 return(TMissions[order]); 822 } 823 } 824 825 826 /*************************************************************************** 827 * TeamTypeClass::operator new -- 'new' operator * 828 * * 829 * INPUT: * 830 * none. * 831 * * 832 * OUTPUT: * 833 * pointer to new TeamType * 834 * * 835 * WARNINGS: * 836 * none. * 837 * * 838 * HISTORY: * 839 * 11/28/1994 BR : Created. * 840 *=========================================================================*/ 841 void * TeamTypeClass::operator new(size_t ) 842 { 843 void * ptr = TeamTypes.Allocate(); 844 if (ptr) { 845 ((TeamTypeClass *)ptr)->IsActive = true; 846 } 847 return(ptr); 848 } 849 850 851 /*************************************************************************** 852 * TeamTypeClass::operator delete -- 'delete' operator * 853 * * 854 * INPUT: * 855 * ptr pointer to delete * 856 * * 857 * OUTPUT: * 858 * none. * 859 * * 860 * WARNINGS: * 861 * none. * 862 * * 863 * HISTORY: * 864 * 11/28/1994 BR : Created. * 865 *=========================================================================*/ 866 void TeamTypeClass::operator delete(void *ptr) 867 { 868 if (ptr) { 869 ((TeamTypeClass *)ptr)->IsActive = false; 870 } 871 TeamTypes.Free((TeamTypeClass *)ptr); 872 } 873 874 875 876 TeamClass * TeamTypeClass::Create_One_Of(void) const 877 { 878 if (ScenarioInit || TeamClass::Number[TeamTypes.ID(this)] < MaxAllowed) { 879 return(new TeamClass(this, HouseClass::As_Pointer(House))); 880 } 881 return(NULL); 882 } 883 884 885 TARGET TeamTypeClass::As_Target(void) const 886 { 887 Validate(); 888 return(Build_Target(KIND_TEAMTYPE, TeamTypes.ID(this))); 889 } 890 891 892 void TeamTypeClass::Destroy_All_Of(void) const 893 { 894 for (int index = 0; index < Teams.Count(); index++) { 895 TeamClass * team = Teams.Ptr(index); 896 897 if (team->Class == this) { 898 delete team; 899 index--; 900 } 901 } 902 } 903 904 905 /*********************************************************************************************** 906 * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. * 907 * * 908 * This routine will scan through the team types available and create teams of the * 909 * type that can best utilize the existing unit mix. * 910 * * 911 * INPUT: house -- Pointer to the house that this team is to be created for. * 912 * * 913 * utype -- A bit mask of the unit types available for this house. * 914 * * 915 * itypes -- A bit mask of the infantry types available for this house. * 916 * * 917 * alerted -- Is this house alerted? If true, then the Autocreate teams will be * 918 * considered in the selection process. * 919 * * 920 * OUTPUT: Returns with a pointer to the team type that should be created. If no team should * 921 * be created, then it returns NULL. * 922 * * 923 * WARNINGS: none * 924 * * 925 * HISTORY: * 926 * 07/13/1995 JLB : Created. * 927 * 07/21/1995 JLB : Will autocreate team even if no members in field. * 928 *=============================================================================================*/ 929 TeamTypeClass const * TeamTypeClass::Suggested_New_Team(HouseClass * house, long utypes, long itypes, bool alerted) 930 { 931 TeamTypeClass const * best = NULL; 932 int bestvalue = 0; 933 934 for (int index = 0; index < TeamTypes.Count(); index++) { 935 TeamTypeClass const * ttype = TeamTypes.Ptr(index); 936 937 if (ttype && 938 ttype->House == house->Class->House && 939 TeamClass::Number[index] < ((alerted || !ttype->IsAutocreate) ? ttype->MaxAllowed : 0)) { 940 941 /* 942 ** Determine what kind of units this team requires. 943 */ 944 long uneeded = 0; 945 long ineeded = 0; 946 for (int ctype = 0; ctype < ttype->ClassCount; ctype++) { 947 switch (ttype->Class[ctype]->What_Am_I()) { 948 case RTTI_INFANTRYTYPE: 949 ineeded |= (1 << ((InfantryTypeClass *)ttype->Class[ctype])->Type); 950 break; 951 952 case RTTI_UNITTYPE: 953 uneeded |= (1 << ((UnitTypeClass *)ttype->Class[ctype])->Type); 954 break; 955 } 956 } 957 958 /* 959 ** If this team can use the types required, then consider it a possible 960 ** team type to create. 961 */ 962 int value = 0; 963 if ((ineeded & itypes) || (uneeded & utypes)) { 964 value = ttype->RecruitPriority; 965 } else { 966 value = ttype->RecruitPriority/2; 967 } 968 969 if (!best || bestvalue < value) { 970 bestvalue = value; 971 best = ttype; 972 } 973 } 974 } 975 976 return(best); 977 }