CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

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 }