| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879 |
- /*
- ** Command & Conquer Red Alert(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /* $Header: /CounterStrike/TEAMTYPE.CPP 1 3/03/97 10:25a Joe_bostic $ */
- /***********************************************************************************************
- *** 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 ***
- ***********************************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : TEAMTYPE.CPP *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : 06/28/96 *
- * *
- * Last Update : July 30, 1996 [JLB] *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * TeamMissionClass::Description -- Compose a text description of team mi *
- * TeamMissionClass::Draw_It -- Draws a team mission list box entry. *
- * TeamMission_Needs -- Determines what extra data is needed by team miss *
- * TeamTypeClass::As_Pointer -- gets ptr for team type with given name *
- * TeamTypeClass::Build_INI_Entry -- Builds the INI entry for this team type. *
- * TeamTypeClass::Create_One_Of -- Creates a team of this type. *
- * TeamTypeClass::Description -- Builds a description of the team. *
- * TeamTypeClass::Destroy_All_Of -- Destroy all teams of this type. *
- * TeamTypeClass::Detach -- Detach the specified target from this team type. *
- * TeamTypeClass::Draw_It -- Display the team type in a list box. *
- * TeamTypeClass::Edit -- Edit the team type. *
- * TeamTypeClass::Fill_In -- fills in trigger from the given INI entry *
- * TeamTypeClass::From_Name -- Converts a name into a team type pointer. *
- * TeamTypeClass::Init -- pre-scenario initialization *
- * TeamTypeClass::Member_Description -- Builds a member description string *
- * TeamTypeClass::Mission_From_Name -- returns mission for given name *
- * TeamTypeClass::Name_From_Mission -- returns name for given mission *
- * TeamTypeClass::Read_INI -- reads INI data *
- * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. *
- * TeamTypeClass::TeamTypeClass -- class constructor *
- * TeamTypeClass::Write_INI -- Write out the team types to the INI database. *
- * TeamTypeClass::operator delete -- 'delete' operator *
- * TeamTypeClass::operator new -- 'new' operator *
- * TeamTypeClass::~TeamTypeClass -- class destructor *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- TeamMissionClass TeamMissions[TMISSION_COUNT] = {
- {TMISSION_ATTACK},
- {TMISSION_ATT_WAYPT},
- {TMISSION_FORMATION},
- {TMISSION_MOVE},
- {TMISSION_MOVECELL},
- {TMISSION_GUARD},
- {TMISSION_LOOP},
- {TMISSION_ATTACKTARCOM},
- {TMISSION_UNLOAD},
- {TMISSION_DEPLOY},
- {TMISSION_HOUND_DOG},
- {TMISSION_DO},
- {TMISSION_SET_GLOBAL},
- {TMISSION_LOAD},
- {TMISSION_SPY},
- {TMISSION_PATROL},
- };
- int atoh(char * str);
- #if defined(CHEAT_KEYS) || defined(SCENARIO_EDITOR)
- /***********************************************************************************************
- * TeamTypeClass::Draw_It -- Display the team type in a list box. *
- * *
- * This is a helper routine that is used when this team type is stored into a list box *
- * and must be displayed. It will display the team type as a single line of text. *
- * *
- * INPUT: see below... *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/30/1996 JLB : Created. *
- *=============================================================================================*/
- void TeamTypeClass::Draw_It(int , int x, int y, int width, int height, bool selected, TextPrintType flags) const
- {
- RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
- static int _tabs[] = {35, 60, 80, 100};
- if ((flags & 0x0F) == TPF_6PT_GRAD || (flags & 0x0F) == TPF_EFNT) {
- if (selected) {
- flags = flags | TPF_BRIGHT_COLOR;
- LogicPage->Fill_Rect(x, y, x + width - 1, y + height - 1, scheme->Shadow);
- } else {
- if (!(flags & TPF_USE_GRAD_PAL)) {
- flags = flags | TPF_MEDIUM_COLOR;
- }
- }
- Conquer_Clip_Text_Print(Description(), x, y, scheme, TBLACK, flags, width, _tabs);
- } else {
- Conquer_Clip_Text_Print(Description(), x, y, (selected ? &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY]), TBLACK, flags, width, _tabs);
- }
- }
- #endif
- /*
- ********************************** Globals **********************************
- */
- char const * TeamTypeClass::TMissions[TMISSION_COUNT] = {
- "Attack...",
- "Attack Waypoint...",
- "Change Formation to...",
- "Move to waypoint...",
- "Move to Cell...",
- "Guard area (1/10th min)...",
- "Jump to line #...",
- "Attack Tarcom",
- "Unload",
- "Deploy",
- "Follow friendlies",
- "Do this...",
- "Set global...",
- "Invulnerable",
- "Load onto Transport",
- "Spy on bldg @ waypt...",
- "Patrol to waypoint..."
- };
- /***************************************************************************
- * TeamTypeClass::TeamTypeClass -- class constructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/07/1994 BR : Created. *
- * 11/22/1995 JLB : Uses initializer constructor method. *
- *=========================================================================*/
- TeamTypeClass::TeamTypeClass(void) :
- AbstractTypeClass(RTTI_TEAMTYPE, TeamTypes.ID(this), TXT_NONE, ""),
- IsRoundAbout(false),
- IsSuicide(false),
- IsAutocreate(false),
- IsPrebuilt(true),
- IsReinforcable(true),
- IsTransient(false),
- RecruitPriority(7),
- InitNum(0),
- MaxAllowed(0),
- Fear(0),
- House(HOUSE_NONE),
- Trigger(0),
- Origin(-1),
- Number(0),
- MissionCount(0),
- ClassCount(0)
- {
- for (int i = 0; i < MAX_TEAM_CLASSCOUNT; i++) {
- Members[i].Class = NULL;
- Members[i].Quantity = 0;
- }
- }
- /***************************************************************************
- * TeamTypeClass::Init -- pre-scenario initialization *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/07/1994 BR : Created. *
- *=========================================================================*/
- void TeamTypeClass::Init(void)
- {
- TeamTypes.Free_All();
- }
- /***************************************************************************
- * TeamTypeClass::As_Pointer -- gets ptr for team type with given name *
- * *
- * INPUT: *
- * name name of teamtype *
- * *
- * OUTPUT: *
- * ptr to TeamType with that name *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/07/1994 BR : Created. *
- *=========================================================================*/
- TeamTypeClass * TeamTypeClass::As_Pointer(char const * name)
- {
- if (name) {
- for (int index = 0; index < TeamTypes.Count(); index++) {
- if (!stricmp(name, TeamTypes.Ptr(index)->IniName)) {
- return(TeamTypes.Ptr(index));
- }
- }
- }
- return(NULL);
- }
- /***************************************************************************
- * TeamTypeClass::Mission_From_Name -- returns team mission for given name *
- * *
- * INPUT: *
- * name name to compare *
- * *
- * OUTPUT: *
- * mission for that name *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/13/1994 BR : Created. *
- *=========================================================================*/
- TeamMissionType TeamTypeClass::Mission_From_Name(char const * name)
- {
- if (name) {
- for (TeamMissionType order = TMISSION_FIRST; order < TMISSION_COUNT; order++) {
- if (stricmp(TMissions[order], name) == 0) {
- return(order);
- }
- }
- }
- return(TMISSION_NONE);
- }
- /***************************************************************************
- * TeamTypeClass::Name_From_Mission -- returns name for given mission *
- * *
- * INPUT: *
- * order mission to get name for *
- * *
- * OUTPUT: *
- * name of mission *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/13/1994 BR : Created. *
- *=========================================================================*/
- char const * TeamTypeClass::Name_From_Mission(TeamMissionType order)
- {
- assert((unsigned)order < TMISSION_COUNT);
- return(TMissions[order]);
- }
- /***************************************************************************
- * TeamTypeClass::operator new -- 'new' operator *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * pointer to new TeamType *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/28/1994 BR : Created. *
- *=========================================================================*/
- void * TeamTypeClass::operator new(size_t )
- {
- void * ptr = TeamTypes.Allocate();
- if (ptr) {
- ((TeamTypeClass *)ptr)->IsActive = true;
- }
- return(ptr);
- }
- /***************************************************************************
- * TeamTypeClass::operator delete -- 'delete' operator *
- * *
- * INPUT: *
- * ptr pointer to delete *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/28/1994 BR : Created. *
- *=========================================================================*/
- void TeamTypeClass::operator delete(void * ptr)
- {
- if (ptr) {
- ((TeamTypeClass *)ptr)->IsActive = false;
- }
- TeamTypes.Free((TeamTypeClass *)ptr);
- }
- /***********************************************************************************************
- * TeamTypeClass::Create_One_Of -- Creates a team of this type. *
- * *
- * Use this routine to create a team object from this team type. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: Returns with a pointer to the newly created team object. If one could not be *
- * created, then NULL is returned. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 09/21/1995 JLB : Created. *
- *=============================================================================================*/
- TeamClass * TeamTypeClass::Create_One_Of(void) const
- {
- if (ScenarioInit || Number < MaxAllowed) {
- // if (ScenarioInit || TeamClass::Number[ID] < MaxAllowed) {
- return(new TeamClass(this, HouseClass::As_Pointer(House)));
- }
- return(NULL);
- }
- /***********************************************************************************************
- * TeamTypeClass::Destroy_All_Of -- Destroy all teams of this type. *
- * *
- * This routine will destroy all teams of this type. Typical use of this is from a trigger *
- * event. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 09/21/1995 JLB : Created. *
- *=============================================================================================*/
- void TeamTypeClass::Destroy_All_Of(void) const
- {
- for (int index = 0; index < Teams.Count(); index++) {
- TeamClass * team = Teams.Ptr(index);
- if (team->Class == this) {
- delete team;
- index--;
- }
- }
- }
- /***********************************************************************************************
- * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. *
- * *
- * This routine will scan through the team types available and create teams of the *
- * type that can best utilize the existing unit mix. *
- * *
- * INPUT: house -- Pointer to the house that this team is to be created for. *
- * *
- * atypes -- A bit mask of the aircraft types available for this house. *
- * *
- * utypes -- A bit mask of the unit types available for this house. *
- * *
- * itypes -- A bit mask of the infantry types available for this house. *
- * *
- * vtypes -- A bit mask of the vessel types available for this house. *
- * *
- * alerted -- Is this house alerted? If true, then the Autocreate teams will be *
- * considered in the selection process. *
- * *
- * OUTPUT: Returns with a pointer to the team type that should be created. If no team should *
- * be created, then it returns NULL. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/13/1995 JLB : Created. *
- * 07/21/1995 JLB : Will autocreate team even if no members in field. *
- *=============================================================================================*/
- TeamTypeClass const * TeamTypeClass::Suggested_New_Team(HouseClass * house, long , long , long , long , bool alerted)
- //TeamTypeClass const * TeamTypeClass::Suggested_New_Team(HouseClass * house, long atypes, long utypes, long itypes, long vtypes, bool alerted)
- {
- // TeamTypeClass const * best = NULL;
- // int bestvalue = 0;
- TeamTypeClass const * choices[20];
- int choicecount = 0;
- for (int index = 0; index < TeamTypes.Count(); index++) {
- TeamTypeClass const * ttype = TeamTypes.Ptr(index);
- assert(ttype != NULL);
- int maxnum = ttype->MaxAllowed;
- if ((alerted && !ttype->IsAutocreate) || (!alerted && ttype->IsAutocreate)) {
- maxnum = 0;
- }
- if (choicecount >= ARRAY_SIZE(choices)) break;
- if (ttype != NULL && ttype->House == house->Class->House && ttype->Number < maxnum) {
- choices[choicecount++] = ttype;
- #ifdef OBSOLETE
- /*
- ** Determine what kind of units this team requires.
- */
- long uneeded = 0;
- long ineeded = 0;
- long vneeded = 0;
- long aneeded = 0;
- for (int ctype = 0; ctype < ttype->ClassCount; ctype++) {
- switch (ttype->Members[ctype].Class->What_Am_I()) {
- case RTTI_INFANTRYTYPE:
- ineeded |= (1 << ((InfantryTypeClass *)ttype->Members[ctype].Class)->Type);
- break;
- case RTTI_UNITTYPE:
- uneeded |= (1 << ((UnitTypeClass *)ttype->Members[ctype].Class)->Type);
- break;
- case RTTI_VESSELTYPE:
- vneeded |= (1 << ((VesselTypeClass *)ttype->Members[ctype].Class)->Type);
- break;
- case RTTI_AIRCRAFTTYPE:
- aneeded |= (1 << ((AircraftTypeClass *)ttype->Members[ctype].Class)->Type);
- break;
- }
- }
- /*
- ** If this team can use the types required, then consider it a possible
- ** team type to create.
- */
- int value = 0;
- if ((aneeded & atypes) != 0 || (ineeded & itypes) != 0 || (uneeded & utypes) != 0 || (vneeded & vtypes) != 0) {
- value = ttype->RecruitPriority;
- } else {
- value = ttype->RecruitPriority/2;
- }
- if (best == NULL || bestvalue < value) {
- bestvalue = value;
- best = ttype;
- }
- #endif
- }
- }
- if (choicecount > 0) {
- return(choices[Random_Pick(0, choicecount-1)]);
- }
- return(NULL);
- // return(best);
- }
- /***********************************************************************************************
- * TeamTypeClass::From_Name -- Converts a name into a team type pointer. *
- * *
- * This routine is used to convert an ASCII name of a team type into the corresponding *
- * team type pointer. *
- * *
- * INPUT: name -- Pointer to the ASCII name of the team type. *
- * *
- * OUTPUT: Returns with a pointer to the team type that this ASCII name represents. If there *
- * is no match, the NULL is returned. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/26/1996 JLB : Created. *
- *=============================================================================================*/
- TeamTypeClass * TeamTypeClass::From_Name(char const * name)
- {
- if (name) {
- for (int index = 0; index < TeamTypes.Count(); index++) {
- if (stricmp(name, TeamTypes.Ptr(index)->IniName) == 0) {
- return(TeamTypes.Ptr(index));
- }
- }
- }
- return(0);
- }
- /***********************************************************************************************
- * TeamMission_Needs -- Determines what extra data is needed by team mission. *
- * *
- * This routine will return the required extra data that the specified team mission will *
- * need. *
- * *
- * INPUT: tmtype -- The team mission type to check. *
- * *
- * OUTPUT: Returns with the data type needed for this team mission. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/26/1996 JLB : Created. *
- *=============================================================================================*/
- NeedType TeamMission_Needs(TeamMissionType tmtype)
- {
- switch (tmtype) {
- /*
- ** Requires a formation type.
- */
- case TMISSION_FORMATION:
- return(NEED_FORMATION);
- /*
- ** Team mission requires a target quarry value.
- */
- case TMISSION_ATTACK:
- return(NEED_QUARRY);
- /*
- ** Team mission requires a data value.
- */
- case TMISSION_MOVECELL:
- return(NEED_HEX_NUMBER);
- case TMISSION_SET_GLOBAL:
- case TMISSION_GUARD:
- case TMISSION_LOOP:
- return(NEED_NUMBER);
- /*
- ** Team mission requires a waypoint.
- */
- case TMISSION_PATROL:
- case TMISSION_MOVE:
- case TMISSION_ATT_WAYPT:
- case TMISSION_SPY:
- return(NEED_WAYPOINT);
- /*
- ** Team mission requires a general mission type.
- */
- case TMISSION_DO:
- return(NEED_MISSION);
- default:
- break;
- }
- return(NEED_NONE);
- }
- #ifdef SCENARIO_EDITOR
- /***********************************************************************************************
- * TeamMissionClass::Draw_It -- Draws a team mission list box entry. *
- * *
- * This routine will display a team mission list box entry. It converts the index number *
- * into the appropriate text string and then displays the text at the coordinates *
- * specified. *
- * *
- * INPUT: index -- The index number to use when rendering the team mission. *
- * *
- * x,y -- The X,Y coordinate to use when drawing the team mission entry. *
- * *
- * width, height -- The dimensions of the area that the description can be *
- * rendered into. *
- * *
- * selected -- Is this entry currently selected? If so, then it should be rendered *
- * differently. *
- * *
- * flags -- Text print control flags used for when the text is printed. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/05/1996 JLB : Created. *
- *=============================================================================================*/
- void TeamMissionClass::Draw_It(int index, int x, int y, int width, int height, bool selected, TextPrintType flags)
- {
- RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
- static int _tabs[] = {13,40};
- if ((flags & 0x0F) == TPF_6PT_GRAD || (flags & 0x0F) == TPF_EFNT) {
- if (selected) {
- flags = flags | TPF_BRIGHT_COLOR;
- LogicPage->Fill_Rect(x, y, x + width - 1, y + height - 1,
- scheme->Shadow);
- } else {
- if (!(flags & TPF_USE_GRAD_PAL)) {
- flags = flags | TPF_MEDIUM_COLOR;
- }
- }
- Conquer_Clip_Text_Print(Description(index), x, y, scheme, TBLACK, flags, width, _tabs);
- } else {
- Conquer_Clip_Text_Print(Description(index), x, y,
- (selected ? &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY]), TBLACK, flags, width, _tabs);
- }
- }
- /***********************************************************************************************
- * TeamTypeClass::Edit -- Edit the team type. *
- * *
- * This routine handles the editing dialog box for the team type. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: Was the team type edited? A FALSE indicates that the dialog was canceled. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/05/1996 JLB : Created. *
- *=============================================================================================*/
- bool TeamTypeClass::Edit(void)
- {
- /*
- ** Dialog & button dimensions
- */
- enum {
- D_DIALOG_W = 400,
- D_DIALOG_H = 250,
- D_DIALOG_X = 0,
- D_DIALOG_Y = 0,
- D_NAME_X=D_DIALOG_X+35,
- D_NAME_Y=D_DIALOG_Y+27,
- ED_WIDTH=40,
- D_CHECK_X=D_DIALOG_X+35, // Start of check box attribute list.
- D_CHECK_Y=D_NAME_Y+25,
- CB_SPACING_Y=9, // Vertical spacing between check box lines.
- CB_SPACING_X=8, // Horizontal spacing for check box description text.
- D_SPACING_X=9, // Horizontal spacing between data entry fields.
- D_CANCEL_W = 50,
- D_CANCEL_H = 9,
- D_CANCEL_X = D_DIALOG_X + D_DIALOG_W - (D_CANCEL_W+35),
- D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - (D_CANCEL_H+20),
- D_OK_W = 50,
- D_OK_H = 9,
- D_OK_X = D_DIALOG_X + D_DIALOG_W - (D_OK_W+18)*2,
- D_OK_Y = D_CANCEL_Y
- };
- /*
- ** Button enumerations:
- */
- enum {
- BUTTON_NAME=100,
- BUTTON_RECRUIT,
- BUTTON_MAXNUM,
- BUTTON_INITNUM,
- BUTTON_HOUSE,
- BUTTON_ROUNDABOUT,
- BUTTON_LEARNING,
- BUTTON_SUICIDE,
- BUTTON_AUTO,
- BUTTON_PREBUILT,
- BUTTON_REINFORCE,
- BUTTON_MISSION1,
- BUTTON_MISSION2,
- BUTTON_ADD,
- BUTTON_INSERT,
- BUTTON_DELETE,
- BUTTON_REPLACE,
- BUTTON_ARG,
- BUTTON_FORMATION,
- BUTTON_MEMBERS,
- BUTTON_MISSION,
- BUTTON_TRIGGER,
- BUTTON_ORIGIN,
- BUTTON_OK,
- BUTTON_CANCEL,
- BUTTON_QUARRY,
- };
- /*
- ** Dialog variables:
- */
- ControlClass * commands = 0;
- RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
- /*
- ** Team name edit field.
- */
- char name_buf[10];
- EditClass name_edt(BUTTON_NAME, name_buf, sizeof(name_buf),
- TPF_EFNT | TPF_NOSHADOW,
- D_NAME_X, D_NAME_Y, ED_WIDTH, 9, EditClass::ALPHANUMERIC);
- strcpy(name_buf, IniName);
- commands = &name_edt;
- /*
- ** House ownership of this team.
- */
- char housetext[25] = "";
- DropListClass housebtn(BUTTON_HOUSE, housetext, sizeof(housetext),
- TPF_EFNT | TPF_NOSHADOW,
- name_edt.X+name_edt.Width+D_SPACING_X, name_edt.Y, 55, 8*5,
- MFCD::Retrieve("EBTN-UP.SHP"),
- MFCD::Retrieve("EBTN-DN.SHP"));
- for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) {
- housebtn.Add_Item(HouseTypeClass::As_Reference(house).IniName);
- }
- if (House == HOUSE_NONE) House = HOUSE_GOOD;
- housebtn.Set_Selected_Index(House);
- housebtn.Add(*commands);
- /*
- ** Recruit priority for this team.
- */
- char recr_buf[4];
- EditClass recr_edt(BUTTON_RECRUIT, recr_buf, sizeof(recr_buf),
- TPF_EFNT | TPF_NOSHADOW,
- housebtn.X+housebtn.Width+5+D_SPACING_X, housebtn.Y, ED_WIDTH, 9, EditClass::NUMERIC);
- sprintf(recr_buf, "%d", RecruitPriority);
- recr_edt.Add(*commands);
- /*
- ** Maximum allowed for this team type.
- */
- char maxnum_buf[4];
- EditClass maxnum_edt(BUTTON_MAXNUM, maxnum_buf, sizeof(maxnum_buf),
- TPF_EFNT | TPF_NOSHADOW,
- recr_edt.X+recr_edt.Width+D_SPACING_X, recr_edt.Y, ED_WIDTH, 9, EditClass::NUMERIC);
- sprintf(maxnum_buf, "%d", MaxAllowed);
- maxnum_edt.Add(*commands);
- /*
- ** Initial number for this team type.
- */
- char initnum_buf[4];
- EditClass initnum_edt(BUTTON_INITNUM, initnum_buf, sizeof(initnum_buf),
- TPF_EFNT | TPF_NOSHADOW,
- maxnum_edt.X+maxnum_edt.Width+D_SPACING_X, maxnum_edt.Y, ED_WIDTH, 9, EditClass::NUMERIC);
- sprintf(initnum_buf, "%d", InitNum);
- initnum_edt.Add(*commands);
- /*
- ** Waypoint preference to create/reinforce this team.
- */
- char origin[4];
- EditClass originbtn(BUTTON_ORIGIN, origin, sizeof(origin),
- TPF_EFNT | TPF_NOSHADOW,
- initnum_edt.X+initnum_edt.Width+D_SPACING_X, initnum_edt.Y, 20, 9, EditClass::ALPHA);
- *originbtn.Get_Text() = '\0';
- if (Origin != -1) {
- if (Origin < 26) {
- sprintf(originbtn.Get_Text(), "%c", Origin + 'A');
- } else {
- sprintf(originbtn.Get_Text(), "%c%c", (Origin/26) + 'A'-1, Origin % 26 + 'A');
- }
- }
- originbtn.Add(*commands);
- /*
- ** Members of this team control button.
- */
- TextButtonClass membersbtn(BUTTON_MEMBERS, "Members", TPF_EBUTTON, name_edt.X, name_edt.Y+12, 50);
- membersbtn.Add(*commands);
- /*
- ** Trigger to assign to each member of this team (when object joins team).
- */
- char trigtext[25] = "";
- DropListClass triggerbtn(BUTTON_TRIGGER, trigtext, sizeof(trigtext),
- TPF_EFNT | TPF_NOSHADOW,
- D_DIALOG_X+D_DIALOG_W-95, membersbtn.Y, 60, 8*5,
- MFCD::Retrieve("EBTN-UP.SHP"),
- MFCD::Retrieve("EBTN-DN.SHP"));
- triggerbtn.Add_Item("<NONE>");
- for (int index = 0; index < TriggerTypes.Count(); index++) {
- triggerbtn.Add_Item(TriggerTypes.Ptr(index)->IniName);
- }
- if (Trigger.Is_Valid()) {
- triggerbtn.Set_Selected_Index(Trigger->Name());
- } else {
- triggerbtn.Set_Selected_Index(0);
- }
- triggerbtn.Add(*commands);
- /*
- ** Roundabout travel logic attribute for this team.
- */
- CheckBoxClass roundbtn(BUTTON_ROUNDABOUT, D_CHECK_X, D_CHECK_Y);
- if (IsRoundAbout) {
- roundbtn.Turn_On();
- } else {
- roundbtn.Turn_Off();
- }
- roundbtn.Add(*commands);
- /*
- ** Suicide travel to target attribute.
- */
- CheckBoxClass suicidebtn(BUTTON_SUICIDE, D_CHECK_X, roundbtn.Y+CB_SPACING_Y);
- if (IsSuicide) {
- suicidebtn.Turn_On();
- } else {
- suicidebtn.Turn_Off();
- }
- suicidebtn.Add(*commands);
- /*
- ** Autocreate attribute for this team.
- */
- CheckBoxClass autocreatebtn(BUTTON_AUTO, D_CHECK_X, suicidebtn.Y+CB_SPACING_Y);
- if (IsAutocreate) {
- autocreatebtn.Turn_On();
- } else {
- autocreatebtn.Turn_Off();
- }
- autocreatebtn.Add(*commands);
- /*
- ** Prebuild team members attribute for this team.
- */
- CheckBoxClass prebuildbtn(BUTTON_PREBUILT, D_CHECK_X, autocreatebtn.Y+CB_SPACING_Y);
- if (IsPrebuilt) {
- prebuildbtn.Turn_On();
- } else {
- prebuildbtn.Turn_Off();
- }
- prebuildbtn.Add(*commands);
- /*
- ** Reinforce this team in progress attribute.
- */
- CheckBoxClass reinforcebtn(BUTTON_REINFORCE, D_CHECK_X, prebuildbtn.Y+CB_SPACING_Y);
- if (IsReinforcable) {
- reinforcebtn.Turn_On();
- } else {
- reinforcebtn.Turn_Off();
- }
- reinforcebtn.Add(*commands);
- /*
- ** Create drop box of possible team missions. This is used when building/editing the
- ** team mission list.
- */
- char droptext[45];
- DropListClass missionlist1(BUTTON_MISSION1, droptext, sizeof(droptext),
- TPF_EFNT | TPF_NOSHADOW,
- reinforcebtn.X, reinforcebtn.Y+15, 170, 8*8,
- MFCD::Retrieve("EBTN-UP.SHP"),
- MFCD::Retrieve("EBTN-DN.SHP"));
- for (TeamMissionType tm = TMISSION_FIRST; tm < TMISSION_COUNT; tm++) {
- missionlist1.Add_Item(TeamTypeClass::Name_From_Mission(tm));
- }
- missionlist1.Set_Selected_Index(0);
- missionlist1.Add_Tail(*commands);
- /*
- ** Optional mission argument entry field.
- */
- char arg_buf[6] = {0};
- EditClass arg_edt(BUTTON_ARG, arg_buf, sizeof(arg_buf),
- TPF_EFNT | TPF_NOSHADOW,
- missionlist1.X + missionlist1.Width + 15, missionlist1.Y, 60, -1, EditClass::ALPHANUMERIC);
- // arg_edt.Add(*commands);
- char qtext[55];
- DropListClass qlist(BUTTON_QUARRY, qtext, sizeof(qtext),
- TPF_EFNT | TPF_NOSHADOW,
- missionlist1.X + missionlist1.Width + 15, missionlist1.Y, 100, 5*8,
- MFCD::Retrieve("EBTN-UP.SHP"),
- MFCD::Retrieve("EBTN-DN.SHP"));
- for (QuarryType q = QUARRY_FIRST; q < QUARRY_COUNT; q++) {
- qlist.Add_Item(QuarryName[q]);
- }
- qlist.Set_Selected_Index(0);
- qlist.Add_Tail(*commands);
- char ftext[55];
- DropListClass flist(BUTTON_FORMATION, ftext, sizeof(ftext),
- TPF_EFNT | TPF_NOSHADOW,
- missionlist1.X + missionlist1.Width + 15, missionlist1.Y, 100, 5*8,
- MFCD::Retrieve("EBTN-UP.SHP"),
- MFCD::Retrieve("EBTN-DN.SHP"));
- for (FormationType f = FORMATION_FIRST; f < FORMATION_COUNT; f++) {
- flist.Add_Item(FormationName[f]);
- }
- flist.Set_Selected_Index(0);
- flist.Add_Tail(*commands);
- char mtext[55];
- DropListClass mlist(BUTTON_MISSION, mtext, sizeof(mtext),
- TPF_EFNT | TPF_NOSHADOW,
- missionlist1.X + missionlist1.Width + 15, missionlist1.Y, 100, 5*8,
- MFCD::Retrieve("EBTN-UP.SHP"),
- MFCD::Retrieve("EBTN-DN.SHP"));
- for (MissionType m = MISSION_FIRST; m < MISSION_COUNT; m++) {
- mlist.Add_Item(MissionClass::Mission_Name(m));
- }
- mlist.Set_Selected_Index(0);
- mlist.Add_Tail(*commands);
- TListClass<TeamMissionClass *> missionlist2(BUTTON_MISSION2, missionlist1.X+60, missionlist1.Y+22, 240, 8*7,
- TPF_EFNT | TPF_NOSHADOW,
- MFCD::Retrieve("EBTN-UP.SHP"),
- MFCD::Retrieve("EBTN-DN.SHP"));
- for (index = 0; index < MissionCount; index++) {
- missionlist2.Add_Item(new TeamMissionClass(MissionList[index]));
- // missionlist2.Add_Item(&TeamMissions[MissionList[index].Mission]);
- }
- static int tabs[] = {13, 40}; // list box tab stops
- missionlist2.Set_Tabs(tabs);
- missionlist2.Add_Tail(*commands);
- /*
- ** Mission editing command buttons.
- */
- TextButtonClass addbtn(BUTTON_ADD, "Append", TPF_EBUTTON, D_NAME_X, missionlist1.Y+missionlist1.Height+1, 50);
- addbtn.Add(*commands);
- TextButtonClass insertbtn(BUTTON_INSERT, "Insert", TPF_EBUTTON, addbtn.X, addbtn.Y+10, 50);
- insertbtn.Add(*commands);
- TextButtonClass delbtn(BUTTON_DELETE, "Delete", TPF_EBUTTON, insertbtn.X, insertbtn.Y+10, 50);
- delbtn.Add(*commands);
- TextButtonClass repbtn(BUTTON_REPLACE, "Replace", TPF_EBUTTON, delbtn.X, delbtn.Y+10, 50);
- repbtn.Add(*commands);
- TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
- TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_EBUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
- /*
- ** Initialize
- */
- Set_Logic_Page(SeenBuff);
- /*
- ** Create the list
- */
- okbtn.Add(*commands);
- cancelbtn.Add_Tail(*commands);
- /*
- ** Main Processing Loop
- */
- int lastindex = -1;
- int lastcount = -1;
- int lastbutton = -1;
- bool cancel = false;
- bool display = true;
- bool process = true;
- while (process) {
- /*
- ** Invoke game callback
- */
- Call_Back();
- /*
- ** Refresh display if needed
- */
- if (display) {
- /*
- ** Add the optional data entry field as necessary.
- */
- arg_edt.Remove();
- qlist.Remove();
- flist.Remove();
- mlist.Remove();
- switch (TeamMission_Needs(TeamMissionType(missionlist1.Current_Index()))) {
- default:
- break;
- case NEED_MISSION:
- mlist.Add(*commands);
- break;
- case NEED_FORMATION:
- flist.Add(*commands);
- break;
- case NEED_WAYPOINT:
- case NEED_NUMBER:
- case NEED_HEX_NUMBER:
- arg_edt.Add(*commands);
- break;
- case NEED_QUARRY:
- qlist.Add(*commands);
- break;
- }
- /*
- ** Display the dialog box
- */
- Hide_Mouse();
- Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
- Draw_Caption(TXT_TEAM_EDIT, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
- /*
- ** Draw the captions
- */
- Fancy_Text_Print("Name:", name_edt.X, name_edt.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("House:", housebtn.X, housebtn.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Pri:", recr_edt.X, recr_edt.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Max:", maxnum_edt.X, maxnum_edt.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Num:", initnum_edt.X, initnum_edt.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Loc:", originbtn.X, originbtn.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("# Team Mission", missionlist2.X, missionlist2.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Trigger:", triggerbtn.X-4, triggerbtn.Y+1, scheme, TBLACK, TPF_RIGHT | TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print(Member_Description(), membersbtn.X + membersbtn.Width + 3, membersbtn.Y+1, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Use safest, possibly longer, route to target?", roundbtn.X+CB_SPACING_X, roundbtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Charge toward target ignoring distractions?", suicidebtn.X+CB_SPACING_X, suicidebtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Only 'Autocreate A.I.' uses this team type?", autocreatebtn.X+CB_SPACING_X, autocreatebtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Prebuild team members before team is created?", prebuildbtn.X+CB_SPACING_X, prebuildbtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- Fancy_Text_Print("Automatically reinforce team whenever possible?", reinforcebtn.X+CB_SPACING_X, reinforcebtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
- /*
- ** Redraw the buttons
- */
- commands->Draw_All();
- Show_Mouse();
- display = false;
- }
- /*
- ** Get user input
- */
- KeyNumType input = commands->Input();
- /*
- ** Process input
- */
- switch (input) {
- /*
- ** Select a Mission on the right-hand mission list; update the Argument
- ** field to reflect the current value. This only serves as an aide to editing
- ** the team mission list.
- */
- case BUTTON_MISSION2 | KN_BUTTON:
- if (missionlist2.Count() && lastcount == missionlist2.Count() && lastbutton == BUTTON_MISSION2 && lastindex == missionlist2.Current_Index()) {
- missionlist1.Set_Selected_Index(missionlist2.Current_Item()->Mission);
- switch (TeamMission_Needs(missionlist2.Current_Item()->Mission)) {
- case NEED_MISSION:
- mlist.Set_Selected_Index(missionlist2.Current_Item()->Data.Mission);
- break;
- case NEED_FORMATION:
- flist.Set_Selected_Index(missionlist2.Current_Item()->Data.Formation);
- break;
- case NEED_NUMBER:
- sprintf(arg_edt.Get_Text(), "%d", missionlist2.Current_Item()->Data.Value);
- break;
- case NEED_HEX_NUMBER:
- sprintf(arg_edt.Get_Text(), "%x", missionlist2.Current_Item()->Data.Value);
- break;
- case NEED_QUARRY:
- strcpy(qlist.Get_Text(), QuarryName[missionlist2.Current_Item()->Data.Quarry]);
- break;
- case NEED_WAYPOINT:
- if (missionlist2.Current_Item()->Data.Value < 26) {
- sprintf(arg_edt.Get_Text(), "%c", missionlist2.Current_Item()->Data.Value + 'A');
- } else {
- sprintf(arg_edt.Get_Text(), "%c%c", (missionlist2.Current_Item()->Data.Value)/26 + 'A'-1, (missionlist2.Current_Item()->Data.Value % 26) + 'A');
- }
- break;
- }
- }
- lastindex = missionlist2.Current_Index();
- lastcount = missionlist2.Count();
- display = true;
- break;
- /*
- ** Add current mission data to current position of team mission list. Any
- ** subsequent missions get moved downward.
- */
- case BUTTON_INSERT | KN_BUTTON:
- if (missionlist2.Count() < MAX_TEAM_MISSIONS) {
- TeamMissionClass * tm = new TeamMissionClass;
- tm->Mission = TeamMissionType(missionlist1.Current_Index());
- tm->Data.Value = 0;
- switch (TeamMission_Needs(tm->Mission)) {
- case NEED_MISSION:
- tm->Data.Mission = MissionType(mlist.Current_Index());
- break;
- case NEED_FORMATION:
- tm->Data.Formation = FormationType(flist.Current_Index());
- break;
- case NEED_QUARRY:
- tm->Data.Quarry = QuarryType(qlist.Current_Index());
- break;
- case NEED_NUMBER:
- tm->Data.Value = atoi(arg_edt.Get_Text());
- break;
- case NEED_HEX_NUMBER:
- tm->Data.Value = atoh(arg_edt.Get_Text());
- break;
- case NEED_WAYPOINT:
- tm->Data.Value = toupper(*arg_edt.Get_Text()) - 'A';
- if ( *((arg_edt.Get_Text())+1)) {
- tm->Data.Value = (tm->Data.Value+1)*26;
- tm->Data.Value += toupper(*((arg_edt.Get_Text())+1)) - 'A';;
- }
- if ((unsigned)tm->Data.Value >= WAYPT_HOME) {
- tm->Data.Value = 0;
- }
- break;
- default:
- tm->Data.Value = 0;
- break;
- }
- missionlist2.Insert_Item(tm);
- }
- display = true;
- break;
- /*
- ** Add mission data to the end of the mission list.
- */
- case BUTTON_ADD | KN_BUTTON:
- if (missionlist2.Count() < MAX_TEAM_MISSIONS) {
- TeamMissionClass * tm = new TeamMissionClass;
- tm->Mission = TeamMissionType(missionlist1.Current_Index());
- tm->Data.Value = 0;
- switch (TeamMission_Needs(tm->Mission)) {
- case NEED_MISSION:
- tm->Data.Mission = MissionType(mlist.Current_Index());
- break;
- case NEED_FORMATION:
- tm->Data.Formation = FormationType(flist.Current_Index());
- break;
- case NEED_QUARRY:
- tm->Data.Quarry = QuarryType(qlist.Current_Index());
- break;
- case NEED_NUMBER:
- tm->Data.Value = atoi(arg_edt.Get_Text());
- break;
- case NEED_HEX_NUMBER:
- tm->Data.Value = atoh(arg_edt.Get_Text());
- break;
- case NEED_WAYPOINT:
- tm->Data.Value = toupper(*arg_edt.Get_Text()) - 'A';;
- if ( *((arg_edt.Get_Text())+1)) {
- tm->Data.Value = (tm->Data.Value+1)*26;
- tm->Data.Value += toupper(*((arg_edt.Get_Text())+1)) - 'A';;
- }
- if ((unsigned)tm->Data.Value >= WAYPT_HOME) {
- tm->Data.Value = 0;
- }
- break;
- default:
- tm->Data.Value = 0;
- break;
- }
- missionlist2.Add_Item(tm);
- display = true;
- }
- break;
- /*
- ** Replace the currently selected mission with the work mission data.
- */
- case BUTTON_REPLACE | KN_BUTTON:
- if (missionlist2.Count()) {
- TeamMissionClass * tm = missionlist2.Current_Item();
- tm->Mission = TeamMissionType(missionlist1.Current_Index());
- tm->Data.Value = 0;
- switch (TeamMission_Needs(tm->Mission)) {
- case NEED_MISSION:
- tm->Data.Mission = MissionType(mlist.Current_Index());
- break;
- case NEED_FORMATION:
- tm->Data.Formation = FormationType(flist.Current_Index());
- break;
- case NEED_QUARRY:
- tm->Data.Quarry = QuarryType(qlist.Current_Index());
- break;
- case NEED_NUMBER:
- tm->Data.Value = atoi(arg_edt.Get_Text());
- break;
- case NEED_HEX_NUMBER:
- tm->Data.Value = atoh(arg_edt.Get_Text());
- break;
- case NEED_WAYPOINT:
- tm->Data.Value = toupper(*arg_edt.Get_Text()) - 'A';
- if ( *((arg_edt.Get_Text())+1)) {
- tm->Data.Value = (tm->Data.Value+1)*26;
- tm->Data.Value += toupper(*((arg_edt.Get_Text())+1)) - 'A';
- }
- if ((unsigned)tm->Data.Value >= WAYPT_HOME) {
- tm->Data.Value = 0;
- }
- break;
- default:
- tm->Data.Value = 0;
- break;
- }
- missionlist2[missionlist2.Current_Index()] = tm;
- }
- display = true;
- break;
- /*
- ** Delete the currently selected mission.
- */
- case BUTTON_DELETE | KN_BUTTON:
- if (missionlist2.Count()) {
- TeamMissionClass * tm = missionlist2.Current_Item();
- missionlist2.Remove_Index(missionlist2.Current_Index());
- delete tm;
- }
- display = true;
- break;
- /*
- ** Invoke the members dialog
- */
- case BUTTON_MEMBERS | KN_BUTTON:
- /*
- ** Take editor focus away
- */
- membersbtn.Turn_Off();
- /*
- ** Invoke the dialog
- */
- Map.Team_Members(HousesType(housebtn.Current_Index()));
- /*
- ** Redraw
- */
- display = true;
- break;
- /*
- ** When the OK button is selected, lift the values from the dialog box
- ** and place them into the team type object.
- */
- case BUTTON_OK | KN_BUTTON:
- strtrim(name_edt.Get_Text());
- if (strlen(name_edt.Get_Text()) != 0) {
- strcpy(IniName, name_edt.Get_Text());
- } else {
- strcpy(IniName, "----");
- }
- IsRoundAbout = roundbtn.IsOn;
- IsSuicide = suicidebtn.IsOn;
- IsAutocreate = autocreatebtn.IsOn;
- IsPrebuilt = prebuildbtn.IsOn;
- IsReinforcable = reinforcebtn.IsOn;
- RecruitPriority = atoi(recr_edt.Get_Text());
- InitNum = atoi(initnum_edt.Get_Text());
- MaxAllowed = atoi(maxnum_edt.Get_Text());
- House = HousesType(housebtn.Current_Index());
- Trigger = NULL;
- if (triggerbtn.Current_Index() > 0) {
- Trigger = TriggerTypes.Ptr(triggerbtn.Current_Index()-1);
- }
- MissionCount = missionlist2.Count();
- for (index = 0; index < MissionCount; index++) {
- MissionList[index].Data.Value = 0; // Clears extra bits.
- MissionList[index] = *missionlist2[index];
- }
- #ifdef TOFIX
- // the mission class objects pointed to in the list should be deleted?
- #endif
- if (strlen(originbtn.Get_Text())) {
- if (strlen(originbtn.Get_Text()) == 1) {
- Origin = toupper(*originbtn.Get_Text()) - 'A';
- } else {
- Origin = (toupper(*originbtn.Get_Text())+1 - 'A' ) * 26;
- Origin += toupper(*(originbtn.Get_Text()+1)) - 'A';
- }
- } else {
- Origin = -1;
- }
- cancel = false;
- process = false;
- break;
- /*
- ** Cancel: return
- */
- case BUTTON_CANCEL | KN_BUTTON:
- cancel = true;
- process = false;
- break;
- /*
- ** Unrecognized events are ignored. If any button related event is
- ** detected, then collapse any drop down list boxes. This keeps the
- ** dialog box clean.
- */
- default:
- if (input & KN_BUTTON) {
- housebtn.Collapse();
- missionlist1.Collapse();
- triggerbtn.Collapse();
- display = true;
- }
- break;
- }
- /*
- ** Record the last dialog control touched so that a double click
- ** can be detected.
- */
- if (input & KN_BUTTON) {
- lastbutton = (input & ~KN_BUTTON);
- }
- }
- return(!cancel);
- }
- int atoh(char * str)
- {
- int retval = 0;
- while (*str) {
- retval *= 16;
- if (*str >= '0' && *str <= '9') {
- retval += *str-'0';
- } else {
- if (*str >= 'a' && *str <= 'f') {
- retval += 10 + (*str - 'a');
- } else {
- if (*str >= 'A' && *str <= 'F') {
- retval += 10 + (*str - 'A');
- }
- }
- }
- str++;
- }
- return(retval);
- }
- #endif
- #if defined(CHEAT_KEYS) || defined(SCENARIO_EDITOR)
- /***********************************************************************************************
- * TeamTypeClass::Member_Description -- Builds a member description string. *
- * *
- * This routine will build a team member description string. The string will be composed *
- * of the team member type and quantity. As many team member types will be listed that *
- * can fit within a reasonable size. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: Returns with a pointer to the text string that contains a description of the team *
- * type members. *
- * *
- * WARNINGS: The return string may be truncated if necessary to fit within reasonable size *
- * limits. *
- * *
- * HISTORY: *
- * 01/05/1996 JLB : Created. *
- *=============================================================================================*/
- char const * TeamTypeClass::Member_Description(void) const
- {
- static char buffer[128];
- buffer[0] = '\0';
- /*
- ** Fill in class & count for all classes
- */
- for (int index = 0; index < ClassCount; index++) {
- char txt[10];
- strcat(buffer, Members[index].Class->IniName);
- strcat(buffer, ":");
- sprintf(txt, "%d", Members[index].Quantity);
- strcat(buffer, txt);
- if (index < ClassCount-1) {
- strcat(buffer, ",");
- }
- }
- if (strlen(buffer) > 25) {
- strcpy(&buffer[25-3], "...");
- }
- return(buffer);
- }
- /***********************************************************************************************
- * TeamTypeClass::Description -- Builds a description of the team. *
- * *
- * This routine will build a brief description of the team type. This description is used *
- * in the team type list. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: Returns with the composed text string that represents the team type. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/05/1996 JLB : Created. *
- *=============================================================================================*/
- char const * TeamTypeClass::Description(void) const
- {
- static char _buffer[128];
- char extra = ' ';
- char loc[3];
- loc[0] = loc[1] = loc[2] = 0;
- if (IsAutocreate) extra = '*';
- if (Origin > -1) {
- // if (Origin != -1) {
- if (Origin < 26) {
- loc[0] = 'A' + Origin;
- } else {
- loc[0] = Origin / 26 + 'A'-1;
- loc[1] = Origin % 26 + 'A';
- }
- }
- sprintf(_buffer, "%s\t%s\t%c%s\t%d\t%s", IniName, HouseTypeClass::As_Reference(House).Suffix, extra, loc, MissionCount, Member_Description());
- return(_buffer);
- }
- /***********************************************************************************************
- * TeamMissionClass::Description -- Compose a text description of team mission. *
- * *
- * This routine will create a text representation of a team mission. This description will *
- * be used in the list of team missions for display purposes. *
- * *
- * INPUT: index -- The index to assign to this team. The index is used since some team *
- * missions refer to the another team mission by index number. *
- * *
- * OUTPUT: Returns with a pointer to the team mission text. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/05/1996 JLB : Created. *
- *=============================================================================================*/
- char const * TeamMissionClass::Description(int index) const
- {
- static char buffer[64];
- sprintf(buffer, "%d\t%s", index, TeamTypeClass::Name_From_Mission(Mission));
- switch (TeamMission_Needs(Mission)) {
- case NEED_MISSION:
- strcat(buffer, MissionClass::Mission_Name(Data.Mission));
- break;
- case NEED_FORMATION:
- strcat(buffer, FormationName[Data.Quarry]);
- break;
- case NEED_NUMBER:
- sprintf(&buffer[strlen(buffer)], "%d", Data.Value);
- break;
- case NEED_HEX_NUMBER:
- sprintf(&buffer[strlen(buffer)], "%x", Data.Value);
- break;
- case NEED_QUARRY:
- strcat(buffer, QuarryName[Data.Quarry]);
- break;
- case NEED_WAYPOINT:
- if (Data.Value < 26) {
- sprintf(&buffer[strlen(buffer)], "%c", Data.Value + 'A');
- } else {
- sprintf(&buffer[strlen(buffer)], "%c%c", (Data.Value/26) + 'A'-1, (Data.Value % 26) + 'A');
- }
- break;
- }
- return(buffer);
- }
- #endif
- /***********************************************************************************************
- * TeamTypeClass::Detach -- Detach the specified target from this team type. *
- * *
- * This routine is called when some object is about to be removed from the game system and *
- * all references to it must be severed. This will check to see if the specified object *
- * is a trigger that this team refers to. If so, then the reference will be cleared. *
- * *
- * INPUT: target -- The target object to remove references to. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/30/1996 JLB : Created. *
- *=============================================================================================*/
- void TeamTypeClass::Detach(TARGET target, bool)
- {
- if (Is_Target_TriggerType(target) && Trigger.Is_Valid() && Trigger == As_TriggerType(target)) {
- Trigger = NULL;
- }
- }
- /***************************************************************************
- * TeamTypeClass::Read_INI -- reads INI data *
- * *
- * INI entry format: *
- * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, *
- * RecruitPriority,MaxAllowed,InitNum,Fear, *
- * ClassCount,Class:Num,Class:Num,..., *
- * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... *
- * *
- * INPUT: *
- * buffer buffer to hold the INI data *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/07/1994 BR : Created. *
- * 02/01/1995 BR : No del team if no classes (editor needs empty teams!) *
- *=========================================================================*/
- void TeamTypeClass::Read_INI(CCINIClass & ini)
- {
- TeamTypeClass * team; // Working team pointer.
- char buf[500]; // INI entry buffer
- int len = ini.Entry_Count(INI_Name());
- /*
- ** Loop for all team entries, create and fill in.
- */
- for (int index = 0; index < len; index++) {
- team = new TeamTypeClass();
- if (team != NULL) {
- char const * entry = ini.Get_Entry(INI_Name(), index);
- ini.Get_String(INI_Name(), entry, NULL, buf, sizeof(buf));
- team->Fill_In((char *)entry, buf);
- }
- }
- }
- /***********************************************************************************************
- * TeamTypeClass::Fill_In -- fills in trigger from the given INI entry *
- * *
- * This routine fills in the given teamtype with the given name, and values from *
- * the given INI entry. *
- * *
- * (This routine is used by the scenario editor, to import teams from the MASTER.INI file.) *
- * *
- * INI entry format: *
- * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, *
- * RecruitPriority,MaxAllowed,InitNum,Fear, *
- * ClassCount,Class:Num,Class:Num,..., *
- * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... *
- * *
- * INPUT: *
- * name mnemonic for the desired trigger *
- * entry INI entry to parse *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 11/28/1994 BR : Created. *
- * 11/29/1995 JLB : Revamped to use new team class. *
- *=============================================================================================*/
- void TeamTypeClass::Fill_In(char * name, char * entry)
- {
- assert(TeamTypes.ID(this) == ID);
- /*
- ** Set its name
- */
- Set_Name(name);
- House = HousesType(atoi(strtok(entry, ",")));
- int code;
- switch (NewINIFormat) {
- default:
- code = atoi(strtok(NULL, ","));
- IsRoundAbout = ((code & 0x0001) != 0);
- IsSuicide = ((code & 0x0002) != 0);
- IsAutocreate = ((code & 0x0004) != 0);
- IsPrebuilt = ((code & 0x0008) != 0);
- IsReinforcable = ((code & 0x0010) != 0);
- break;
- case 0:
- case 1:
- IsRoundAbout = atoi(strtok(NULL, ","));
- IsSuicide = atoi(strtok(NULL, ","));
- IsAutocreate = atoi(strtok(NULL, ","));
- IsPrebuilt = atoi(strtok(NULL, ","));
- IsReinforcable = atoi(strtok(NULL, ","));
- break;
- }
- RecruitPriority = atoi(strtok(NULL, ","));
- InitNum = atoi(strtok(NULL, ","));
- MaxAllowed = atoi(strtok(NULL, ","));
- Origin = atoi(strtok(NULL, ","));
- switch (NewINIFormat) {
- default:
- Trigger.Set_Raw(atoi(strtok(NULL, ",")));
- break;
- case 0:
- case 1:
- // Throw this token away -- it isn't used.
- strtok(NULL, ",");
- break;
- }
- /*
- ** Fetch the team member types and quantity values.
- */
- ClassCount = atoi(strtok(NULL, ","));
- for (int index = 0; index < ClassCount; index++) {
- char * p1 = strtok(NULL, ",:");
- char * p2 = strtok(NULL, ",:");
- TechnoTypeClass const * otype = NULL;
- /*
- ** See if this is an infantry name
- */
- InfantryType i_id = InfantryTypeClass::From_Name(p1);
- if (i_id != INFANTRY_NONE) {
- otype = &InfantryTypeClass::As_Reference(i_id);
- } else {
- /*
- ** See if this is a unit name
- */
- UnitType u_id = UnitTypeClass::From_Name(p1);
- if (u_id != UNIT_NONE) {
- otype = &UnitTypeClass::As_Reference(u_id);
- } else {
- /*
- ** See if this is an aircraft name
- */
- AircraftType a_id = AircraftTypeClass::From_Name(p1);
- if (a_id != AIRCRAFT_NONE) {
- otype = &AircraftTypeClass::As_Reference(a_id);
- } else {
- /*
- ** See if this is a vessel name.
- */
- VesselType v_id = VesselTypeClass::From_Name(p1);
- if (v_id != VESSEL_NONE) {
- otype = &VesselTypeClass::As_Reference(v_id);
- }
- }
- }
- }
- /*
- ** If the name was resolved, add this class
- */
- if (otype) {
- Members[index].Class = otype;
- Members[index].Quantity = atoi(p2);
- } else {
- ClassCount--;
- if (index == 0) break;
- index--;
- }
- }
- /*
- ** Fetch the missions assigned to this team type.
- */
- MissionCount = atoi(strtok(NULL, ","));
- for (index = 0; index < MissionCount; index++) {
- MissionList[index].Mission = TeamMissionType(atoi(strtok(NULL, ",:")));
- MissionList[index].Data.Value = atoi(strtok(NULL, ",:"));
- }
- if (NewINIFormat < 2) {
- /*
- ** Fetch the trigger ID.
- */
- Trigger.Set_Raw(atoi(strtok(NULL, ",")));
- }
- }
- /***********************************************************************************************
- * TeamTypeClass::Write_INI -- Write out the team types to the INI database. *
- * *
- * This routine will take all team types and write them out to the INI database specified. *
- * *
- * INPUT: ini -- Reference to the INI database that will hold al the teams. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: All preexisting team data in the database will be erased by this routine. *
- * *
- * HISTORY: *
- * 07/30/1996 JLB : Created. *
- *=============================================================================================*/
- void TeamTypeClass::Write_INI(CCINIClass & ini)
- {
- ini.Clear("TeamTypes");
- ini.Clear(INI_Name());
- /*
- ** Now write all the team data out
- */
- for (int index = 0; index < TeamTypes.Count(); index++) {
- // for (int index = TeamTypes.Count()-1; index >= 0; index--) {
- TeamTypeClass * team = TeamTypes.Ptr(index);
- char buf[256];
- buf[0] = 0;
- team->Build_INI_Entry(buf);
- ini.Put_String(INI_Name(), team->IniName, buf);
- }
- }
- /***********************************************************************************************
- * TeamTypeClass::Build_INI_Entry -- Builds the INI entry for this team type. *
- * *
- * This routine is used to build the text string that will go into the INI database for *
- * a team of this type. This text string will be parsed back into a team object when the *
- * scenario INI is read in. *
- * *
- * INPUT: buf -- Pointer to a buffer that will hold the team text entry. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: Be sure that the buffer can hold the string build. A size of 80 or so is *
- * usually sufficient. *
- * *
- * HISTORY: *
- * 07/30/1996 JLB : Created. *
- *=============================================================================================*/
- void TeamTypeClass::Build_INI_Entry(char * buf)
- {
- int code = 0;
- code |= IsRoundAbout ? 0x0001 : 0;
- code |= IsSuicide ? 0x0002 : 0;
- code |= IsAutocreate ? 0x0004 : 0;
- code |= IsPrebuilt ? 0x0008 : 0;
- code |= IsReinforcable ? 0x0010 : 0;
- /*
- ** Output the general data for this team type.
- */
- sprintf(buf, "%d,%d,%d,%d,%d,%d,%d",
- House,
- code,
- RecruitPriority,
- InitNum,
- MaxAllowed,
- Origin,
- TriggerTypes.Logical_ID(Trigger)
- );
- buf += strlen(buf);
- /*
- ** For every class in the team, record the class's name & desired count
- */
- sprintf (buf, ",%d", ClassCount);
- buf += strlen(buf);
- for (int i = 0; i < ClassCount; i++) {
- sprintf (buf, ",%s:%d", Members[i].Class->IniName, Members[i].Quantity);
- buf += strlen(buf);
- }
- /*
- ** Record the # of missions, and each mission name & argument value.
- */
- sprintf(buf, ",%d", MissionCount);
- buf += strlen(buf);
- for (i = 0; i < MissionCount; i++) {
- sprintf (buf, ",%d:%d", MissionList[i].Mission, MissionList[i].Data.Value);
- buf += strlen(buf);
- }
- }
|